summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-02-02 10:10:24 -0500
committerFreya Murphy <freya@freyacat.org>2024-02-02 10:13:32 -0500
commit1d794d87f4307f7b34f5b69d69213343aed9d137 (patch)
tree50d2508ddc4e6be814d31bfb37a37065e5e71525
parentdebugger (diff)
downloadcorn-1d794d87f4307f7b34f5b69d69213343aed9d137.tar.gz
corn-1d794d87f4307f7b34f5b69d69213343aed9d137.tar.bz2
corn-1d794d87f4307f7b34f5b69d69213343aed9d137.zip
looping kalloc can allocate all of memory (sometimes) :3
-rw-r--r--Makefile55
-rw-r--r--arch/amd64/linker.ld1
-rw-r--r--src/arch/amd64/paging.c8
-rw-r--r--src/kmain.c4
-rw-r--r--src/lib.c1
-rw-r--r--src/memory/memory.c11
-rw-r--r--src/memory/physalloc.c40
-rw-r--r--src/memory/virtalloc.c106
8 files changed, 134 insertions, 92 deletions
diff --git a/Makefile b/Makefile
index 2e58dd1..19b2342 100644
--- a/Makefile
+++ b/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 \
diff --git a/arch/amd64/linker.ld b/arch/amd64/linker.ld
index 7a34a9e..797dc35 100644
--- a/arch/amd64/linker.ld
+++ b/arch/amd64/linker.ld
@@ -31,6 +31,7 @@ SECTIONS {
.bss BLOCK(4K) : ALIGN(4K)
{
+ *(COMMON)
*(.bss)
}
diff --git a/src/arch/amd64/paging.c b/src/arch/amd64/paging.c
index 607267e..604e0a0 100644
--- a/src/arch/amd64/paging.c
+++ b/src/arch/amd64/paging.c
@@ -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:
diff --git a/src/kmain.c b/src/kmain.c
index 07244bf..7501669 100644
--- a/src/kmain.c
+++ b/src/kmain.c
@@ -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
}
diff --git a/src/lib.c b/src/lib.c
index ee4afcb..d2708c8 100644
--- a/src/lib.c
+++ b/src/lib.c
@@ -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;
diff --git a/src/memory/memory.c b/src/memory/memory.c
index ae26bfe..d1a163f 100644
--- a/src/memory/memory.c
+++ b/src/memory/memory.c
@@ -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");
}
diff --git a/src/memory/physalloc.c b/src/memory/physalloc.c
index 67c99c7..b0dbdcd 100644
--- a/src/memory/physalloc.c
+++ b/src/memory/physalloc.c
@@ -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;
- bitmap = mmap(bitmap, bitmap_size);
- memset(bitmap, 0, bitmap_size);
+ page_area_addr = (char *) page_align((uintptr_t) page_area_addr);
- memory_start = page_align(kaddr(kernel_end) + bitmap_size + page_area_size);
+ memory_start = page_align((uintptr_t)page_area_addr + page_area_size);
+ bitmap = mmap(bitmap, bitmap_size);
+ memset(bitmap, 0, bitmap_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;
diff --git a/src/memory/virtalloc.c b/src/memory/virtalloc.c
index baa7892..bfeb670 100644
--- a/src/memory/virtalloc.c
+++ b/src/memory/virtalloc.c
@@ -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,26 +112,60 @@ void virtaddr_init(void) {
start_node = &bootstrap_nodes[0];
}
-void *virtaddr_alloc(int n_pages) {
+static void merge_back(struct addr_node *node) {
+ while(node->prev) {
+ if (node->is_alloc != node->prev->is_alloc)
+ break;
+ struct addr_node *temp = node->prev;
+ node->start = temp->start;
+ node->prev = temp->prev;
+ if (temp->prev)
+ temp->prev->next = node;
+ free_node(temp);
+ }
+ if (node->prev == NULL) {
+ start_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 = 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;
- long length = node->end - node->start;
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;
@@ -110,34 +173,17 @@ void *virtaddr_alloc(int n_pages) {
new->is_alloc = true;
new->is_used = true;
new->next = node;
- return (void *) new->start;
+ return (void*)new->start;
+ //void *mem = (void *) new->start;
+ //merge_back(new);
+ //merge_forward(new);
+ //return mem;
}
}
return NULL;
}
-static void merge_back(struct addr_node *node) {
- while (node->prev && !node->is_alloc) {
- struct addr_node *temp = node->prev;
- node->start = node->prev->start;
- node->prev = node->prev->prev;
- free_node(temp);
- }
- if (node->prev == NULL) {
- start_node = node;
- }
-}
-
-static void merge_forward(struct addr_node *node) {
- while (node->next && !node->is_alloc) {
- struct addr_node *temp = node->next;
- node->end = node->next->end;
- node->next = node->next->next;
- free_node(temp);
- }
-}
-
long virtaddr_free(void *virtaddr) {
uintptr_t virt = (uintptr_t) virtaddr;