mirror of
https://git.stationery.faith/corn/corn.git
synced 2024-09-08 00:31:41 +00:00
looping kalloc can allocate all of memory (sometimes) :3
This commit is contained in:
parent
c8c8d009f6
commit
1d794d87f4
8 changed files with 147 additions and 105 deletions
55
Makefile
55
Makefile
|
@ -1,62 +1,59 @@
|
|||
SRC_DIR=src
|
||||
INCLUDE_DIR=include
|
||||
BUILD_DIR=build
|
||||
|
||||
K_BIN_NAME=kernel.bin
|
||||
ISO_NAME=os_image.iso
|
||||
KERNEL=kernel.bin
|
||||
ISO=os_image.iso
|
||||
|
||||
ARCH=amd64
|
||||
CC=cc
|
||||
LD=ld
|
||||
AS=nasm
|
||||
|
||||
CFLAGS+=-std=c2x -ffreestanding -fno-stack-protector -g -Wall -Wextra -pedantic -lgcc -isystem $(INCLUDE_DIR)
|
||||
CFLAGS+=-DPAGE_SIZE=4096
|
||||
CFLAGS += -std=c2x -ffreestanding -fno-stack-protector -g -Wall -Wextra -pedantic -lgcc -isystem include
|
||||
CFLAGS += -DPAGE_SIZE=4096
|
||||
|
||||
LDFLAGS+=-nmagic
|
||||
LDFLAGS += -nmagic -nostdlib
|
||||
|
||||
C_SRC=$(shell find $(SRC_DIR) -type f -name "*.c")
|
||||
C_OBJ=$(patsubst %.c,$(BUILD_DIR)/%.o,$(C_SRC))
|
||||
H_SRC = $(shell find src include -type f -name "*.h")
|
||||
|
||||
H_SRC=$(shell find $(SRC_DIR) -type f -name "*.h")
|
||||
H_INCLUDE=$(shell find $(INCLUDE_DIR) -type f -name "*.h")
|
||||
C_SRC = $(shell find src -type f -name "*.c")
|
||||
C_OBJ = $(patsubst %.c,build/%.o,$(C_SRC))
|
||||
|
||||
A_SRC=$(shell find $(SRC_DIR) -type f -name "*.S")
|
||||
A_OBJ=$(patsubst %.S,$(BUILD_DIR)/%.S.o,$(A_SRC))
|
||||
A_SRC = $(shell find src -type f -name "*.S" -not -path "src/arch/*")
|
||||
A_SRC += $(shell find src/arch/$(ARCH) -type f -name "*.S")
|
||||
A_OBJ = $(patsubst %.S,build/%.S.o,$(A_SRC))
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
all: $(BUILD_DIR)/$(ISO_NAME)
|
||||
all: build/$(ISO)
|
||||
|
||||
clean:
|
||||
@printf "\033[31m RM \033[0m%s\n" $(BUILD_DIR)
|
||||
@rm -rf $(BUILD_DIR)/*
|
||||
@printf "\033[31m RM \033[0m%s\n" build
|
||||
@rm -rf build/*
|
||||
|
||||
$(A_OBJ): $(BUILD_DIR)/%.S.o : %.S
|
||||
$(A_OBJ): build/%.S.o : %.S
|
||||
@mkdir -p $(@D)
|
||||
@printf "\033[33m AS \033[0m%s\n" $<
|
||||
@nasm $< -f elf64 -o $@
|
||||
|
||||
$(C_OBJ): $(BUILD_DIR)/%.o : %.c
|
||||
$(C_OBJ): build/%.o : %.c
|
||||
@mkdir -p $(@D)
|
||||
@printf "\033[34m CC \033[0m%s\n" $<
|
||||
@$(CC) -c $(CFLAGS) -o $@ $<
|
||||
|
||||
$(BUILD_DIR)/$(K_BIN_NAME): arch/amd64/linker.ld $(A_OBJ) $(C_OBJ) $(H_SRC) $(H_INCLUDE)
|
||||
build/$(KERNEL): arch/$(ARCH)/linker.ld $(A_OBJ) $(C_OBJ) $(H_SRC)
|
||||
@mkdir -p $(@D)
|
||||
@printf "\033[32m LD \033[0m%s\n" $@
|
||||
@$(LD) $(LDFLAGS) --no-warn-rwx-segments -T arch/amd64/linker.ld -o $(BUILD_DIR)/$(K_BIN_NAME) $(A_OBJ) $(C_OBJ)
|
||||
@$(LD) $(LDFLAGS) --no-warn-rwx-segments -T arch/$(ARCH)/linker.ld -o build/$(KERNEL) $(A_OBJ) $(C_OBJ)
|
||||
|
||||
$(BUILD_DIR)/$(ISO_NAME): $(BUILD_DIR)/$(K_BIN_NAME) grub.cfg
|
||||
build/$(ISO): build/$(KERNEL) grub.cfg
|
||||
@mkdir -p $(@D)
|
||||
@mkdir -p $(BUILD_DIR)/iso/boot/grub
|
||||
@cp grub.cfg $(BUILD_DIR)/iso/boot/grub
|
||||
@cp $(BUILD_DIR)/$(K_BIN_NAME) $(BUILD_DIR)/iso/boot
|
||||
@printf "\033[35m ISO \033[0m%s\n" $(BUILD_DIR)/$(ISO_NAME)
|
||||
@grub-mkrescue -o $(BUILD_DIR)/$(ISO_NAME) $(BUILD_DIR)/iso 2> /dev/null
|
||||
@mkdir -p build/iso/boot/grub
|
||||
@cp grub.cfg build/iso/boot/grub
|
||||
@cp build/$(KERNEL) build/iso/boot
|
||||
@printf "\033[35m ISO \033[0m%s\n" build/$(ISO)
|
||||
@grub-mkrescue -o build/$(ISO) build/iso 2> /dev/null
|
||||
|
||||
run: all
|
||||
@qemu-system-x86_64 \
|
||||
-cdrom $(BUILD_DIR)/$(ISO_NAME) \
|
||||
-cdrom build/$(ISO) \
|
||||
-serial stdio \
|
||||
-display gtk,show-menubar=off,zoom-to-fit=on \
|
||||
-m 1G \
|
||||
|
|
|
@ -31,6 +31,7 @@ SECTIONS {
|
|||
|
||||
.bss BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ static void load_pd(void *phys) {
|
|||
return;
|
||||
pt->address = (uint64_t)phys >> 12;
|
||||
pt->flags = F_PRESENT | F_WRITEABLE;
|
||||
invlpg(pdpt_mapped);
|
||||
invlpg(pd_mapped);
|
||||
}
|
||||
|
||||
static void load_pt(void *phys) {
|
||||
|
@ -456,10 +456,14 @@ static int map_pages(
|
|||
|
||||
page->address = (uint64_t)phys >> 12;
|
||||
page->flags = F_PRESENT | flags;
|
||||
invlpg(virt);
|
||||
|
||||
if (flags & F_GLOBAL)
|
||||
invlpg(virt);
|
||||
|
||||
}
|
||||
|
||||
__asm volatile("mov %cr3, %rax; mov %rax, %cr3;");
|
||||
|
||||
return 0;
|
||||
|
||||
failed:
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
void kmain(struct boot_info *info) {
|
||||
memory_init(&info->map);
|
||||
//acpi_init(info->acpi_table);
|
||||
//fb_init(1024, 768);
|
||||
//acpi_init(info->acpi_table);
|
||||
|
||||
kprintf("enterd kmain\n");
|
||||
|
||||
|
@ -17,7 +17,7 @@ void kmain(struct boot_info *info) {
|
|||
*(char *)(0xB8000 + 0x146) = 'i';
|
||||
|
||||
while (1) {
|
||||
//kprintf("ret: 0x%p\n", kalloc(1024));
|
||||
__asm__("hlt;");
|
||||
// loop so we dont halt
|
||||
// this allows interrupts to fire
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ void *memmove(void *dest, const void *src, unsigned long n) {
|
|||
}
|
||||
|
||||
void *memset(void *restrict dest, int c, unsigned long n) {
|
||||
|
||||
unsigned char *d = dest;
|
||||
for (; n; n--) *d++ = c;
|
||||
return dest;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "serial.h"
|
||||
#include <memory.h>
|
||||
#include <stdint.h>
|
||||
#include <lib.h>
|
||||
|
@ -52,6 +51,7 @@ void *kalloc_new(size_t size) {
|
|||
node = 0;
|
||||
}
|
||||
|
||||
memset(addr, 0, pages * PAGE_SIZE);
|
||||
struct page_header *header = addr;
|
||||
header->magic = 0xBEEFCAFE;
|
||||
header->used = size;
|
||||
|
@ -66,6 +66,8 @@ void *kalloc_new(size_t size) {
|
|||
|
||||
if (end_header != NULL) {
|
||||
end_header->next = header;
|
||||
} else {
|
||||
end_header = header;
|
||||
}
|
||||
|
||||
return mem;
|
||||
|
@ -146,7 +148,12 @@ void *krealloc(void *src, size_t dst_len) {
|
|||
return NULL; // allocation failed
|
||||
}
|
||||
|
||||
if (dst_len < src_len)
|
||||
src_len = dst_len;
|
||||
|
||||
memcpy(dst, src, src_len);
|
||||
kfree(src);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
@ -159,7 +166,7 @@ void kfree(void *ptr) {
|
|||
|
||||
header = get_header(ptr);
|
||||
|
||||
if (header == NULL || header->used == 0) {
|
||||
if (header == NULL) {
|
||||
panic("attempted to kfree invalid pointer");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "serial.h"
|
||||
#include <memory.h>
|
||||
#include <stdint.h>
|
||||
#include <lib.h>
|
||||
|
@ -15,8 +14,6 @@ extern char kernel_end;
|
|||
// between memory_start and kernel_start will be the bitmap
|
||||
static uintptr_t memory_start = 0;
|
||||
|
||||
typedef unsigned char page[4096];
|
||||
|
||||
struct memory_area {
|
||||
uint64_t len;
|
||||
uintptr_t addr;
|
||||
|
@ -26,9 +23,8 @@ static uint64_t *bitmap;
|
|||
static uint64_t total_memory;
|
||||
static uint64_t free_memory;
|
||||
static uint64_t page_count;
|
||||
static uint64_t page_free_start;
|
||||
static uint64_t segment_count;
|
||||
static struct memory_area *page_start;
|
||||
struct memory_area *page_start;
|
||||
|
||||
static int n_pages(const struct memory_area *m) {
|
||||
return m->len / PAGE_SIZE;
|
||||
|
@ -37,7 +33,7 @@ static int n_pages(const struct memory_area *m) {
|
|||
static void *page_at(int i) {
|
||||
int cur_page = 0;
|
||||
for (uint64_t idx = 0; idx < segment_count; idx++) {
|
||||
struct memory_area *m = &page_start[idx];
|
||||
const struct memory_area *m = page_start;
|
||||
int pages = n_pages(m);
|
||||
if (i - cur_page < pages) {
|
||||
return (void *) (m->addr + (PAGE_SIZE * (i - cur_page)));
|
||||
|
@ -47,10 +43,11 @@ static void *page_at(int i) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static long page_idx(page p) {
|
||||
uintptr_t addr = (uintptr_t) p;
|
||||
static long page_idx(void *page) {
|
||||
uintptr_t addr = (uintptr_t) page;
|
||||
int cur_page = 0;
|
||||
for (struct memory_area *m = page_start; m != NULL; m++) {
|
||||
for (uint64_t idx = 0; idx < segment_count; idx++) {
|
||||
const struct memory_area *m = page_start;
|
||||
if ((uintptr_t) m + m->len > addr) {
|
||||
return cur_page + ((addr - m->addr) / PAGE_SIZE);
|
||||
}
|
||||
|
@ -82,15 +79,9 @@ void *alloc_phys_pages(int pages) {
|
|||
|
||||
int n_contiguous = 0;
|
||||
int free_region_start = 0;
|
||||
bool first = true;
|
||||
for (uint64_t i = page_free_start; i < page_count; i++) {
|
||||
for (uint64_t i = 0; i < page_count; i++) {
|
||||
bool free = !bitmap_get(i);
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
page_free_start = i;
|
||||
}
|
||||
|
||||
if (free) {
|
||||
if (n_contiguous == 0) free_region_start = i;
|
||||
n_contiguous++;
|
||||
|
@ -113,8 +104,6 @@ void free_phys_pages(void *ptr, int pages) {
|
|||
long idx = page_idx(ptr);
|
||||
if (idx == -1) return;
|
||||
|
||||
if ((unsigned) idx < page_free_start) page_free_start = idx;
|
||||
|
||||
for (int i = 0; i < pages; i++)
|
||||
bitmap_set(idx + pages, false);
|
||||
}
|
||||
|
@ -165,7 +154,6 @@ void memory_init(struct memory_map *map) {
|
|||
total_memory = 0;
|
||||
free_memory = 0;
|
||||
page_count = 0;
|
||||
page_free_start = 0;
|
||||
page_start = NULL;
|
||||
|
||||
segment_count = 0;
|
||||
|
@ -181,21 +169,21 @@ void memory_init(struct memory_map *map) {
|
|||
segment_count++;
|
||||
}
|
||||
|
||||
long bitmap_pages = page_count / 64 / PAGE_SIZE + 1;
|
||||
free_memory = page_count * PAGE_SIZE;
|
||||
|
||||
//HACK: terrible hack bad bad bad bad
|
||||
long bitmap_pages = (page_count / 64 / PAGE_SIZE) + 1;
|
||||
long bitmap_size = bitmap_pages * PAGE_SIZE;
|
||||
bitmap = (uint64_t *) page_align(kaddr(kernel_end));
|
||||
|
||||
long page_area_size = segment_count * sizeof(struct memory_area);
|
||||
char *page_area_addr = (char *)bitmap + bitmap_size;
|
||||
page_area_addr = (char *) page_align((uintptr_t) page_area_addr);
|
||||
|
||||
memory_start = page_align((uintptr_t)page_area_addr + page_area_size);
|
||||
|
||||
bitmap = mmap(bitmap, bitmap_size);
|
||||
memset(bitmap, 0, bitmap_size);
|
||||
|
||||
memory_start = page_align(kaddr(kernel_end) + bitmap_size + page_area_size);
|
||||
|
||||
page_area_addr = mmap(page_area_addr, page_area_size);
|
||||
memset(page_area_addr, 0, page_area_size);
|
||||
|
||||
page_start = (struct memory_area *) page_area_addr;
|
||||
|
||||
struct memory_area *area = page_start;
|
||||
|
|
|
@ -35,6 +35,32 @@ static struct addr_node *get_node_idx(int idx) {
|
|||
}
|
||||
}
|
||||
|
||||
static void update_node_ptrs(
|
||||
struct addr_node *old,
|
||||
struct addr_node *new,
|
||||
int old_len,
|
||||
int new_len
|
||||
) {
|
||||
if (old == NULL)
|
||||
return;
|
||||
int idx = 0;
|
||||
for (int i = 0; i < old_len; i++) {
|
||||
struct addr_node *o = &old[i];
|
||||
if (o && !o->is_used)
|
||||
continue;
|
||||
struct addr_node *n = &new[idx++];
|
||||
*n = *o;
|
||||
if (n->prev != NULL)
|
||||
n->prev->next = n;
|
||||
if (n->next != NULL)
|
||||
n->next->prev = n;
|
||||
}
|
||||
for (int i = idx; i < new_len; i++) {
|
||||
struct addr_node *n = &new[idx++];
|
||||
n->is_used = false;
|
||||
}
|
||||
}
|
||||
|
||||
static struct addr_node *get_node(void) {
|
||||
size_t count = BSS_NODES + alloc_node_count;
|
||||
|
||||
|
@ -43,10 +69,13 @@ static struct addr_node *get_node(void) {
|
|||
int new_alloc = alloc_node_count * 2;
|
||||
if (new_alloc < 8)
|
||||
new_alloc = 8;
|
||||
int allocated = new_alloc - alloc_node_count;
|
||||
int old = new_alloc - allocated;
|
||||
alloc_nodes = krealloc(alloc_nodes, sizeof(struct addr_node) * new_alloc);
|
||||
memset(alloc_nodes + old, 0, sizeof(struct addr_node) + allocated);;
|
||||
struct addr_node *new_nodes;
|
||||
new_nodes = kalloc(sizeof(struct addr_node) * new_alloc);
|
||||
if (new_nodes == NULL)
|
||||
panic("virt addr alloc nodes is null");
|
||||
update_node_ptrs(alloc_nodes, new_nodes, alloc_node_count, new_alloc);
|
||||
kfree(alloc_nodes);
|
||||
alloc_nodes = new_nodes;
|
||||
alloc_node_count = new_alloc;
|
||||
is_allocating = false;
|
||||
count = BSS_NODES + alloc_node_count;
|
||||
|
@ -83,45 +112,15 @@ void virtaddr_init(void) {
|
|||
start_node = &bootstrap_nodes[0];
|
||||
}
|
||||
|
||||
void *virtaddr_alloc(int n_pages) {
|
||||
|
||||
if (n_pages < 1)
|
||||
return NULL;
|
||||
|
||||
long n_length = n_pages * PAGE_SIZE;
|
||||
struct addr_node *node = start_node;
|
||||
|
||||
for (; node != NULL ; node = node->next) {
|
||||
|
||||
if (node->is_alloc)
|
||||
continue;
|
||||
|
||||
long length = node->end - node->start;
|
||||
if (length >= n_length) {
|
||||
struct addr_node *new = get_node();
|
||||
if (node->prev != NULL) {
|
||||
node->prev->next = new;
|
||||
}
|
||||
new->next = node;
|
||||
node->prev = new;
|
||||
new->start = node->start;
|
||||
new->end = new->start + n_length;
|
||||
node->start = new->end;
|
||||
new->is_alloc = true;
|
||||
new->is_used = true;
|
||||
new->next = node;
|
||||
return (void *) new->start;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void merge_back(struct addr_node *node) {
|
||||
while (node->prev && !node->is_alloc) {
|
||||
while(node->prev) {
|
||||
if (node->is_alloc != node->prev->is_alloc)
|
||||
break;
|
||||
struct addr_node *temp = node->prev;
|
||||
node->start = node->prev->start;
|
||||
node->prev = node->prev->prev;
|
||||
node->start = temp->start;
|
||||
node->prev = temp->prev;
|
||||
if (temp->prev)
|
||||
temp->prev->next = node;
|
||||
free_node(temp);
|
||||
}
|
||||
if (node->prev == NULL) {
|
||||
|
@ -130,14 +129,61 @@ static void merge_back(struct addr_node *node) {
|
|||
}
|
||||
|
||||
static void merge_forward(struct addr_node *node) {
|
||||
<<<<<<< HEAD
|
||||
while (node->next && !node->is_alloc) {
|
||||
=======
|
||||
while(node->next) {
|
||||
if (node->is_alloc != node->next->is_alloc)
|
||||
break;
|
||||
>>>>>>> ea2de5a (looping kalloc can allocate all of memory (sometimes) :3)
|
||||
struct addr_node *temp = node->next;
|
||||
node->end = node->next->end;
|
||||
node->next = node->next->next;
|
||||
node->end = temp->end;
|
||||
node->next = temp->next;
|
||||
if (temp->next)
|
||||
temp->next->prev = node;
|
||||
free_node(temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *virtaddr_alloc(int n_pages) {
|
||||
if (n_pages < 1)
|
||||
return NULL;
|
||||
long n_length = n_pages * PAGE_SIZE;
|
||||
struct addr_node *node = start_node;
|
||||
|
||||
for (; node != NULL ; node = node->next) {
|
||||
long length = node->end - node->start;
|
||||
if (node->is_alloc)
|
||||
continue;
|
||||
|
||||
if (length >= n_length) {
|
||||
struct addr_node *new = get_node();
|
||||
if (node->prev != NULL) {
|
||||
node->prev->next = new;
|
||||
} else {
|
||||
start_node = new;
|
||||
}
|
||||
new->next = node;
|
||||
new->prev = node->prev;
|
||||
node->prev = new;
|
||||
new->start = node->start;
|
||||
new->end = new->start + n_length;
|
||||
node->start = new->end;
|
||||
new->is_alloc = true;
|
||||
new->is_used = true;
|
||||
new->next = node;
|
||||
return (void*)new->start;
|
||||
//void *mem = (void *) new->start;
|
||||
//merge_back(new);
|
||||
//merge_forward(new);
|
||||
//return mem;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
long virtaddr_free(void *virtaddr) {
|
||||
|
||||
uintptr_t virt = (uintptr_t) virtaddr;
|
||||
|
|
Loading…
Reference in a new issue