From 34247153636c4f38116907eb1421868113cae50d Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 19:52:25 -0400 Subject: comment out non contigous phys page allocator, its causing problems and this is due tomorrow, dear god aaaaaaaaa --- kernel/memory/paging.c | 114 ++++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 49 deletions(-) (limited to 'kernel/memory') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 763bdce..9dfa236 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -1025,64 +1025,80 @@ void *mem_alloc_pages(mem_ctx_t ctx, size_t count, unsigned int flags) void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, unsigned int flags) { - size_t pages_needed = count; - - struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; - struct phys_page_slice phys_pages; + void *phys = NULL; if (virtaddr_take(&ctx->virtctx, virt, count)) return NULL; - while (pages_needed > 0) { - phys_pages = alloc_phys_page_withextra(pages_needed); - if (phys_pages.pagestart == NULL) { - goto mem_alloc_pages_at_fail; - } - - { - // allocate the first page and store in it the physical address of the - // previous chunk of pages - // TODO: skip this if there are already enough pages from first alloc - void *pageone = kmapaddr(phys_pages.pagestart, NULL, 1, - F_PRESENT | F_WRITEABLE); - if (pageone == NULL) { - panic("kernel out of virtual memory"); - } - *((struct phys_page_slice *)pageone) = prev_phys_block; - prev_phys_block = phys_pages; - kunmapaddr(pageone); - } - - // index into virtual page array at index [count - pages_needed] - void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); - - assert(pages_needed >= phys_pages.num_pages, "overflow"); - pages_needed -= phys_pages.num_pages; + phys = alloc_phys_pages_exact(count); + if (phys == NULL) + return NULL; - if (map_pages((volatile struct pml4 *)ctx->pml4, vaddr, - phys_pages.pagestart, flags, phys_pages.num_pages)) { - goto mem_alloc_pages_at_fail; - } + if (map_pages((volatile struct pml4 *)ctx->pml4, virt, phys, flags, count)) { + free_phys_pages(phys, count); + return NULL; } return virt; -mem_alloc_pages_at_fail: - while (prev_phys_block.pagestart) { - void *virtpage = kmapaddr(prev_phys_block.pagestart, NULL, 1, - F_PRESENT | F_WRITEABLE); - if (!virtpage) { - // memory corruption, most likely a bug - // could also ERROR here and exit with leak - panic("unable to free memory from failed mem_alloc_pages_at call"); - } - struct phys_page_slice prev = *(struct phys_page_slice *)virtpage; - prev_phys_block = prev; - free_phys_pages_slice(prev); - kunmapaddr(virtpage); - } - - return NULL; +// size_t pages_needed = count; +// +// struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; +// struct phys_page_slice phys_pages; +// +// if (virtaddr_take(&ctx->virtctx, virt, count)) +// return NULL; +// +// while (pages_needed > 0) { +// phys_pages = alloc_phys_page_withextra(pages_needed); +// if (phys_pages.pagestart == NULL) { +// goto mem_alloc_pages_at_fail; +// } +// +// { +// // allocate the first page and store in it the physical address of the +// // previous chunk of pages +// // TODO: skip this if there are already enough pages from first alloc +// void *pageone = kmapaddr(phys_pages.pagestart, NULL, 1, +// F_PRESENT | F_WRITEABLE); +// if (pageone == NULL) { +// panic("kernel out of virtual memory"); +// } +// *((struct phys_page_slice *)pageone) = prev_phys_block; +// prev_phys_block = phys_pages; +// kunmapaddr(pageone); +// } +// +// // index into virtual page array at index [count - pages_needed] +// void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); +// +// assert(pages_needed >= phys_pages.num_pages, "overflow"); +// pages_needed -= phys_pages.num_pages; +// +// if (map_pages((volatile struct pml4 *)ctx->pml4, vaddr, +// phys_pages.pagestart, flags, phys_pages.num_pages)) { +// goto mem_alloc_pages_at_fail; +// } +// } +// +// return virt; +// +//mem_alloc_pages_at_fail: +// while (prev_phys_block.pagestart) { +// void *virtpage = kmapaddr(prev_phys_block.pagestart, NULL, 1, +// F_PRESENT | F_WRITEABLE); +// if (!virtpage) { +// // memory corruption, most likely a bug +// // could also ERROR here and exit with leak +// panic("unable to free memory from failed mem_alloc_pages_at call"); +// } +// struct phys_page_slice prev = *(struct phys_page_slice *)virtpage; +// prev_phys_block = prev; +// free_phys_pages_slice(prev); +// kunmapaddr(virtpage); +// } +// +// return NULL; } void mem_free_pages(mem_ctx_t ctx, const void *virt) -- cgit v1.2.3-freya From 27afee24b6f89b11399033ed46278900cc0a43fa Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 19:53:02 -0400 Subject: more data! --- kernel/memory/virtalloc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel/memory') diff --git a/kernel/memory/virtalloc.h b/kernel/memory/virtalloc.h index 5033242..44bf8d7 100644 --- a/kernel/memory/virtalloc.h +++ b/kernel/memory/virtalloc.h @@ -13,7 +13,7 @@ #include #include -#define BOOTSTRAP_VIRT_ALLOC_NODES 64 +#define BOOTSTRAP_VIRT_ALLOC_NODES 256 struct virt_addr_node { /// first virtural address -- cgit v1.2.3-freya From bfb4f18ddc8b915c9ce5b1e5c085c30b836458db Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 19:53:15 -0400 Subject: fix yet another terrible bug, someone please kill me --- kernel/memory/virtalloc.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'kernel/memory') diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c index 0cbba33..4ee75bb 100644 --- a/kernel/memory/virtalloc.c +++ b/kernel/memory/virtalloc.c @@ -1,10 +1,12 @@ -#include "lib/kio.h" #include #include #include #include "virtalloc.h" +extern char kernel_start[]; +extern char kernel_end[]; + static struct virt_addr_node *get_node_idx(struct virt_ctx *ctx, int idx) { if (idx < BOOTSTRAP_VIRT_ALLOC_NODES) { @@ -64,6 +66,7 @@ static struct virt_addr_node *get_node(struct virt_ctx *ctx) for (; idx < count; idx++) { struct virt_addr_node *node = get_node_idx(ctx, idx); if (!node->is_used) { + node->is_used = true; ctx->used_node_count++; return node; } @@ -81,7 +84,7 @@ static void free_node(struct virt_ctx *ctx, struct virt_addr_node *node) void virtaddr_init(struct virt_ctx *ctx) { struct virt_addr_node init = { - .start = 0x50000000, + .start = 0x0, .end = 0x1000000000000, // 48bit memory address max .next = NULL, .prev = NULL, @@ -96,6 +99,10 @@ void virtaddr_init(struct virt_ctx *ctx) ctx->alloc_node_count = 0; ctx->used_node_count = 0; ctx->is_allocating = false; + + virtaddr_take(ctx, (void *)kernel_start, + ((uint64_t)kernel_end - (uint64_t)kernel_start) / PAGE_SIZE + + 1); } int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new) @@ -211,9 +218,9 @@ int virtaddr_take(struct virt_ctx *ctx, const void *virt, int n_pages) left->prev = node->prev; left->start = node->start; left->end = (uintptr_t)virt; - left->is_used = true; left->is_alloc = false; - node->prev->next = left; + if (node->prev) + node->prev->next = left; node->prev = left; } @@ -224,16 +231,15 @@ int virtaddr_take(struct virt_ctx *ctx, const void *virt, int n_pages) right->next = node->next; right->start = (uintptr_t)virt + n_length; right->end = node->end; - right->is_used = true; right->is_alloc = false; - node->next->prev = right; + if (node->next) + node->next->prev = right; node->next = right; } node->start = (uintptr_t)virt; node->end = node->start + n_length; node->is_alloc = true; - node->is_used = true; return 0; } @@ -257,6 +263,8 @@ long virtaddr_free(struct virt_ctx *ctx, const void *virtaddr) if (node->start == virt) { int length = node->end - node->start; int pages = length / PAGE_SIZE; + // FIXME: ??? + node->is_alloc = false; merge_back(ctx, node); merge_forward(ctx, node); return pages; -- cgit v1.2.3-freya From f7a899db24b91005e57bf4d3b5494e59965c7f04 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Thu, 1 May 2025 21:34:22 -0400 Subject: changes idk --- kernel/fs/tar.c | 1 + kernel/lib/kalloc.c | 4 +++- kernel/mboot/module.c | 2 +- kernel/memory/paging.c | 3 ++- kernel/memory/physalloc.c | 21 ++++++++++++++++----- kernel/memory/virtalloc.c | 6 +++--- 6 files changed, 26 insertions(+), 11 deletions(-) (limited to 'kernel/memory') diff --git a/kernel/fs/tar.c b/kernel/fs/tar.c index 86af81f..061dd0c 100644 --- a/kernel/fs/tar.c +++ b/kernel/fs/tar.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include diff --git a/kernel/lib/kalloc.c b/kernel/lib/kalloc.c index 02e9457..8dca46b 100644 --- a/kernel/lib/kalloc.c +++ b/kernel/lib/kalloc.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include @@ -34,7 +35,8 @@ static struct page_header *get_header(void *ptr) static void *alloc_new(size_t size) { - size_t pages = ((size + header_len + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; + size_t pages = + ((size + header_len + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; void *addr = kalloc_pages(pages); void *mem = (char *)addr + header_len; diff --git a/kernel/mboot/module.c b/kernel/mboot/module.c index cb05b45..bf15eca 100644 --- a/kernel/mboot/module.c +++ b/kernel/mboot/module.c @@ -33,7 +33,7 @@ void *mboot_get_initrd(size_t *len) return NULL; mod = (struct multiboot_tag_module *)tag; - phys = (void *) (uintptr_t) mod->mod_start; + phys = (void *)(uintptr_t)mod->mod_start; initrd_len = mod->mod_end - mod->mod_start; // map addr diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 9dfa236..39f7638 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include @@ -353,7 +354,7 @@ static volatile struct pt *pt_alloc(volatile struct pd *pPD, void *vADDR, } pPT = alloc_phys_page(); - if (pPD == NULL) + if (pPT == NULL) return NULL; vPT = PT_MAP(pPT); diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index 8971bcf..4255339 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include #include @@ -62,7 +63,7 @@ static long page_idx(void *page) static inline bool bitmap_get(size_t i) { - return (bitmap[i / 64] >> i % 64) & 1; + return (bitmap[i / 64] >> (i % 64)) & 1; } static inline void bitmap_set(size_t i, bool v) @@ -71,9 +72,9 @@ static inline void bitmap_set(size_t i, bool v) free_memory -= PAGE_SIZE; else free_memory += PAGE_SIZE; - int idx = i / 64; - bitmap[idx] &= ~(1 << i % 64); - bitmap[idx] |= (v << i % 64); + size_t idx = i / 64; + bitmap[idx] &= ~(1 << (i % 64)); + bitmap[idx] |= (v << (i % 64)); } void *alloc_phys_page(void) @@ -105,9 +106,17 @@ void *alloc_phys_pages_exact(size_t pages) free_region_start = i; n_contiguous++; if (n_contiguous == pages) { + void *pADDR; + pADDR = page_at(free_region_start); + + if (pADDR == NULL) { + n_contiguous = 0; + continue; + } + for (size_t j = 0; j < pages; j++) bitmap_set(free_region_start + j, true); - return page_at(free_region_start); + return pADDR; } } else n_contiguous = 0; @@ -118,6 +127,7 @@ void *alloc_phys_pages_exact(size_t pages) struct phys_page_slice alloc_phys_page_withextra(size_t max_pages) { + panic("please dont use this its broken i think?!\n"); if (max_pages == 0) return PHYS_PAGE_SLICE_NULL; @@ -160,6 +170,7 @@ void free_phys_page(void *ptr) void free_phys_pages_slice(struct phys_page_slice slice) { + panic("please dont use this its broken i think?!\n"); free_phys_pages(slice.pagestart, slice.num_pages); } diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c index 4ee75bb..da64f3b 100644 --- a/kernel/memory/virtalloc.c +++ b/kernel/memory/virtalloc.c @@ -100,9 +100,9 @@ void virtaddr_init(struct virt_ctx *ctx) ctx->used_node_count = 0; ctx->is_allocating = false; - virtaddr_take(ctx, (void *)kernel_start, - ((uint64_t)kernel_end - (uint64_t)kernel_start) / PAGE_SIZE + - 1); + virtaddr_take(ctx, (void *)0, + ((uint64_t)kernel_end + PAGE_SIZE - 1) / PAGE_SIZE * + PAGE_SIZE); } int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new) -- cgit v1.2.3-freya From e10b750a33bb9b8fb9b5f636c5d937cb54104bd9 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Fri, 2 May 2025 12:37:55 -0400 Subject: broken? --- kernel/memory/paging.c | 119 +++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 59 deletions(-) (limited to 'kernel/memory') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 39f7638..e21fd34 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -1035,71 +1035,72 @@ void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, if (phys == NULL) return NULL; - if (map_pages((volatile struct pml4 *)ctx->pml4, virt, phys, flags, count)) { + if (map_pages((volatile struct pml4 *)ctx->pml4, virt, phys, flags, + count)) { free_phys_pages(phys, count); return NULL; } return virt; -// size_t pages_needed = count; -// -// struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; -// struct phys_page_slice phys_pages; -// -// if (virtaddr_take(&ctx->virtctx, virt, count)) -// return NULL; -// -// while (pages_needed > 0) { -// phys_pages = alloc_phys_page_withextra(pages_needed); -// if (phys_pages.pagestart == NULL) { -// goto mem_alloc_pages_at_fail; -// } -// -// { -// // allocate the first page and store in it the physical address of the -// // previous chunk of pages -// // TODO: skip this if there are already enough pages from first alloc -// void *pageone = kmapaddr(phys_pages.pagestart, NULL, 1, -// F_PRESENT | F_WRITEABLE); -// if (pageone == NULL) { -// panic("kernel out of virtual memory"); -// } -// *((struct phys_page_slice *)pageone) = prev_phys_block; -// prev_phys_block = phys_pages; -// kunmapaddr(pageone); -// } -// -// // index into virtual page array at index [count - pages_needed] -// void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); -// -// assert(pages_needed >= phys_pages.num_pages, "overflow"); -// pages_needed -= phys_pages.num_pages; -// -// if (map_pages((volatile struct pml4 *)ctx->pml4, vaddr, -// phys_pages.pagestart, flags, phys_pages.num_pages)) { -// goto mem_alloc_pages_at_fail; -// } -// } -// -// return virt; -// -//mem_alloc_pages_at_fail: -// while (prev_phys_block.pagestart) { -// void *virtpage = kmapaddr(prev_phys_block.pagestart, NULL, 1, -// F_PRESENT | F_WRITEABLE); -// if (!virtpage) { -// // memory corruption, most likely a bug -// // could also ERROR here and exit with leak -// panic("unable to free memory from failed mem_alloc_pages_at call"); -// } -// struct phys_page_slice prev = *(struct phys_page_slice *)virtpage; -// prev_phys_block = prev; -// free_phys_pages_slice(prev); -// kunmapaddr(virtpage); -// } -// -// return NULL; + // size_t pages_needed = count; + // + // struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; + // struct phys_page_slice phys_pages; + // + // if (virtaddr_take(&ctx->virtctx, virt, count)) + // return NULL; + // + // while (pages_needed > 0) { + // phys_pages = alloc_phys_page_withextra(pages_needed); + // if (phys_pages.pagestart == NULL) { + // goto mem_alloc_pages_at_fail; + // } + // + // { + // // allocate the first page and store in it the physical address of the + // // previous chunk of pages + // // TODO: skip this if there are already enough pages from first alloc + // void *pageone = kmapaddr(phys_pages.pagestart, NULL, 1, + // F_PRESENT | F_WRITEABLE); + // if (pageone == NULL) { + // panic("kernel out of virtual memory"); + // } + // *((struct phys_page_slice *)pageone) = prev_phys_block; + // prev_phys_block = phys_pages; + // kunmapaddr(pageone); + // } + // + // // index into virtual page array at index [count - pages_needed] + // void *vaddr = ((uint8_t *)virt) + ((count - pages_needed) * PAGE_SIZE); + // + // assert(pages_needed >= phys_pages.num_pages, "overflow"); + // pages_needed -= phys_pages.num_pages; + // + // if (map_pages((volatile struct pml4 *)ctx->pml4, vaddr, + // phys_pages.pagestart, flags, phys_pages.num_pages)) { + // goto mem_alloc_pages_at_fail; + // } + // } + // + // return virt; + // + //mem_alloc_pages_at_fail: + // while (prev_phys_block.pagestart) { + // void *virtpage = kmapaddr(prev_phys_block.pagestart, NULL, 1, + // F_PRESENT | F_WRITEABLE); + // if (!virtpage) { + // // memory corruption, most likely a bug + // // could also ERROR here and exit with leak + // panic("unable to free memory from failed mem_alloc_pages_at call"); + // } + // struct phys_page_slice prev = *(struct phys_page_slice *)virtpage; + // prev_phys_block = prev; + // free_phys_pages_slice(prev); + // kunmapaddr(virtpage); + // } + // + // return NULL; } void mem_free_pages(mem_ctx_t ctx, const void *virt) -- cgit v1.2.3-freya From ed44d51f7dcaee989d6f36bab8042f438692e7ce Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Fri, 2 May 2025 12:38:02 -0400 Subject: off by one --- kernel/memory/physalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'kernel/memory') diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index 4255339..47522b8 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -27,7 +27,7 @@ static const char *segment_type_str[] = { static int n_pages(const struct memory_segment *m) { - return m->len / PAGE_SIZE; + return (m->len + PAGE_SIZE - 1) / PAGE_SIZE; } static void *page_at(int i) -- cgit v1.2.3-freya From 40bfcbb2cf8a39e58ec19b21956caaf4685c9b8b Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:34:48 -0400 Subject: terrible hack to not overwrite mboot data --- kernel/include/comus/mboot.h | 10 ++++++++++ kernel/mboot/mboot.c | 19 +++++++++++++++++++ kernel/mboot/module.c | 16 +++++++++++++--- kernel/memory/physalloc.c | 24 ++++++++++++++++-------- 4 files changed, 58 insertions(+), 11 deletions(-) (limited to 'kernel/memory') diff --git a/kernel/include/comus/mboot.h b/kernel/include/comus/mboot.h index aba3e4e..bed29f1 100644 --- a/kernel/include/comus/mboot.h +++ b/kernel/include/comus/mboot.h @@ -47,4 +47,14 @@ EFI_HANDLE mboot_get_efi_hdl(void); */ void *mboot_get_initrd(size_t *len); +/** + * Returns the physical pointer to the loaded init ram disk with size given by len + */ +void *mboot_get_initrd_phys(size_t *len); + +/** + * Gets the end of the mboot pointer + */ +void *mboot_end(void); + #endif /* mboot.h */ diff --git a/kernel/mboot/mboot.c b/kernel/mboot/mboot.c index e4547e7..8163f04 100644 --- a/kernel/mboot/mboot.c +++ b/kernel/mboot/mboot.c @@ -5,6 +5,8 @@ static volatile void *mboot = NULL; +extern char kernel_end[]; + void mboot_init(long magic, volatile void *ptr) { if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) @@ -12,6 +14,23 @@ void mboot_init(long magic, volatile void *ptr) mboot = ptr; } +void *mboot_end(void) +{ + if (mboot == NULL) + return NULL; + + struct multiboot *info = (struct multiboot *)mboot; + uintptr_t mboot_end, initrd_end; + size_t initrd_len; + + mboot_end = (uintptr_t)info + info->total_size; + initrd_end = (uintptr_t)mboot_get_initrd_phys(&initrd_len); + if (initrd_end) + initrd_end += initrd_len; + + return (void *)MAX(mboot_end, initrd_end); +} + void *locate_mboot_table(uint32_t type) { if (mboot == NULL) diff --git a/kernel/mboot/module.c b/kernel/mboot/module.c index bf15eca..03c5147 100644 --- a/kernel/mboot/module.c +++ b/kernel/mboot/module.c @@ -1,4 +1,4 @@ -#include "comus/memory.h" +#include #include #include "mboot.h" @@ -16,7 +16,7 @@ struct multiboot_tag_module { static void *mapped_addr = NULL; size_t initrd_len; -void *mboot_get_initrd(size_t *len) +void *mboot_get_initrd_phys(size_t *len) { struct multiboot_tag_module *mod; void *tag, *phys; @@ -36,11 +36,21 @@ void *mboot_get_initrd(size_t *len) phys = (void *)(uintptr_t)mod->mod_start; initrd_len = mod->mod_end - mod->mod_start; + *len = initrd_len; + return phys; +} + +void *mboot_get_initrd(size_t *len) +{ + // get phys + void *phys = mboot_get_initrd_phys(len); + if (phys == NULL) + return NULL; + // map addr mapped_addr = kmapaddr(phys, NULL, initrd_len, F_PRESENT | F_WRITEABLE); if (mapped_addr == NULL) return NULL; - *len = initrd_len; return mapped_addr; } diff --git a/kernel/memory/physalloc.c b/kernel/memory/physalloc.c index 47522b8..7551c75 100644 --- a/kernel/memory/physalloc.c +++ b/kernel/memory/physalloc.c @@ -1,12 +1,14 @@ -#include "lib/kio.h" #include #include #include +#include +#include #include "physalloc.h" extern char kernel_start[]; extern char kernel_end[]; +static void *kernel_real_end = NULL; // between memory_start and kernel_start will be the bitmap static uintptr_t memory_start = 0; @@ -30,16 +32,17 @@ static int n_pages(const struct memory_segment *m) return (m->len + PAGE_SIZE - 1) / PAGE_SIZE; } -static void *page_at(int i) +static void *page_at(size_t i) { - int cur_page = 0; + size_t cur_page = 0; + const struct memory_segment *m = page_start; for (uint64_t idx = 0; idx < segment_count; idx++) { - const struct memory_segment *m = page_start; - int pages = n_pages(m); + size_t pages = n_pages(m); if (i - cur_page < pages) { return (void *)(m->addr + (PAGE_SIZE * (i - cur_page))); } cur_page += pages; + m++; } return NULL; } @@ -48,8 +51,8 @@ static long page_idx(void *page) { uintptr_t addr = (uintptr_t)page; int cur_page = 0; + const struct memory_segment *m = page_start; for (uint64_t idx = 0; idx < segment_count; idx++) { - const struct memory_segment *m = page_start; if (addr < m->addr) { return -1; } @@ -57,6 +60,7 @@ static long page_idx(void *page) return cur_page + ((addr - m->addr) / PAGE_SIZE); } cur_page += n_pages(m); + m++; } return -1; } @@ -211,7 +215,7 @@ static struct memory_segment clamp_segment(const struct memory_segment *segment) if (memory_start) start = memory_start; else - start = (uintptr_t)kernel_end; + start = (uintptr_t)kernel_real_end; if (segment->addr < start) { addr = start; @@ -243,6 +247,10 @@ void physalloc_init(struct memory_map *map) segment_count = 0; + kernel_real_end = mboot_end(); + if ((char *)kernel_real_end < kernel_end) + kernel_real_end = kernel_end; + for (uint32_t i = 0; i < map->entry_count; i++) { struct memory_segment *segment = &map->entries[i]; @@ -256,7 +264,7 @@ void physalloc_init(struct memory_map *map) long bitmap_pages = (page_count / 64 / PAGE_SIZE) + 1; long bitmap_size = bitmap_pages * PAGE_SIZE; - bitmap = (uint64_t *)page_align((uintptr_t)kernel_end); + bitmap = (uint64_t *)page_align((uintptr_t)kernel_real_end); long page_area_size = segment_count * sizeof(struct memory_segment); char *page_area_addr = (char *)bitmap + bitmap_size; -- cgit v1.2.3-freya From b54fdd17a99a7feffc36a3ad067d4293ba3e9577 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:36:04 -0400 Subject: add some memory logging --- kernel/memory/paging.c | 46 ++++++++++++++++++++++++++----------- kernel/user.c | 62 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 76 insertions(+), 32 deletions(-) (limited to 'kernel/memory') diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index e21fd34..fc3b256 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -1,4 +1,3 @@ -#include "lib/kio.h" #include #include @@ -6,7 +5,6 @@ #include "physalloc.h" #include "paging.h" #include "memory.h" -#include // PAGE MAP LEVEL 4 ENTRY struct pml4e { @@ -259,8 +257,10 @@ static volatile struct pml4 *pml4_alloc(void) volatile struct pml4 *pPML4, *vPML4; pPML4 = alloc_phys_page(); - if (pPML4 == NULL) + if (pPML4 == NULL) { + ERROR("Could not allocate PML4"); return NULL; + } vPML4 = PML4_MAP(pPML4); memsetv(vPML4, 0, sizeof(struct pml4)); @@ -288,8 +288,10 @@ static volatile struct pdpt *pdpt_alloc(volatile struct pml4 *pPML4, } pPDPT = alloc_phys_page(); - if (pPML4 == NULL) + if (pPDPT == NULL) { + ERROR("Could not allocate PDPT"); return NULL; + } vPDPT = PDPT_MAP(pPDPT); memsetv(vPDPT, 0, sizeof(struct pdpt)); @@ -321,8 +323,10 @@ static volatile struct pd *pd_alloc(volatile struct pdpt *pPDPT, void *vADDR, } pPD = alloc_phys_page(); - if (pPDPT == NULL) + if (pPD == NULL) { + ERROR("Could not allocate PD"); return NULL; + } vPD = PD_MAP(pPD); memsetv(vPD, 0, sizeof(struct pd)); @@ -354,8 +358,10 @@ static volatile struct pt *pt_alloc(volatile struct pd *pPD, void *vADDR, } pPT = alloc_phys_page(); - if (pPT == NULL) + if (pPT == NULL) { + ERROR("Could not allocate PT"); return NULL; + } vPT = PT_MAP(pPT); memsetv(vPT, 0, sizeof(struct pt)); @@ -911,11 +917,15 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, // get page aligned (or allocate) vitural address if (virt == NULL) virt = virtaddr_alloc(&ctx->virtctx, pages); - if (virt == NULL) + if (virt == NULL) { + ERROR("Could not alloc vitural address for %zu pages", pages); return NULL; + } - if (virtaddr_take(&ctx->virtctx, virt, pages)) + if (virtaddr_take(&ctx->virtctx, virt, pages)) { + ERROR("Could not take vitural address: %p", virt); return NULL; + } assert((uint64_t)virt % PAGE_SIZE == 0, "mem_mapaddr: vitural address not page aligned"); @@ -923,6 +933,7 @@ void *mem_mapaddr(mem_ctx_t ctx, void *phys, void *virt, size_t len, if (map_pages((volatile struct pml4 *)ctx->pml4, virt, aligned_phys, F_PRESENT | flags, pages)) { virtaddr_free(&ctx->virtctx, virt); + ERROR("Could not map pages"); return NULL; } @@ -1028,21 +1039,30 @@ void *mem_alloc_pages_at(mem_ctx_t ctx, size_t count, void *virt, { void *phys = NULL; - if (virtaddr_take(&ctx->virtctx, virt, count)) + if (virtaddr_take(&ctx->virtctx, virt, count)) { + ERROR("Could not take vitural address: %p", virt); return NULL; + } phys = alloc_phys_pages_exact(count); - if (phys == NULL) - return NULL; + if (phys == NULL) { + ERROR("Could not allocate %zu physical pages", count); + goto fail; + } if (map_pages((volatile struct pml4 *)ctx->pml4, virt, phys, flags, count)) { - free_phys_pages(phys, count); - return NULL; + ERROR("Could not map pages"); + goto fail; } return virt; +fail: + free_phys_pages(phys, count); + virtaddr_free(&ctx->virtctx, virt); + return NULL; + // size_t pages_needed = count; // // struct phys_page_slice prev_phys_block = PHYS_PAGE_SLICE_NULL; diff --git a/kernel/user.c b/kernel/user.c index 9612710..97d8f0f 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -1,3 +1,4 @@ +#include "lib/kio.h" #include #include #include @@ -14,7 +15,7 @@ #define USER_STACK_LEN (4 * PAGE_SIZE) #define BLOCK_SIZE (PAGE_SIZE * 1000) -static char *load_buffer = NULL; +static uint8_t *load_buffer = NULL; #define USER_CODE 0x18 #define USER_DATA 0x20 @@ -49,16 +50,22 @@ static int user_load_segment(struct pcb *pcb, struct file *file, int idx) // allocate memory in user process if (mem_alloc_pages_at(pcb->memctx, mem_pages, (void *)hdr.p_vaddr, - F_WRITEABLE | F_UNPRIVILEGED) == NULL) + F_WRITEABLE | F_UNPRIVILEGED) == NULL) { + ERROR("Could not allocate memory for elf segment"); return 1; + } mapADDR = kmapuseraddr(pcb->memctx, (void *)hdr.p_vaddr, mem_bytes); - if (mapADDR == NULL) + if (mapADDR == NULL) { + ERROR("Could load memory for elf segment"); return 1; + } // seek to start of segment - if (file->seek(file, hdr.p_offset, SEEK_SET) < 0) + if (file->seek(file, hdr.p_offset, SEEK_SET) < 0) { + ERROR("Could not load elf segment"); return 1; + } // load data size_t total_read = 0; @@ -66,11 +73,13 @@ static int user_load_segment(struct pcb *pcb, struct file *file, int idx) size_t read = BLOCK_SIZE; if (read > file_bytes - total_read) read = file_bytes - total_read; + TRACE("Reading %zu bytes...", read); if ((read = file->read(file, load_buffer, read)) < 1) { kunmapaddr(mapADDR); + ERROR("Could not load elf segment"); return 1; } - memcpy(mapADDR + total_read, load_buffer, read); + memcpyv(mapADDR + total_read, load_buffer, read); total_read += read; } @@ -89,10 +98,15 @@ static int user_load_segments(struct pcb *pcb, struct file *file) pcb->heap_start = NULL; pcb->heap_len = 0; - if (load_buffer == NULL) - if ((load_buffer = kalloc(BLOCK_SIZE)) == NULL) + if (load_buffer == NULL) { + load_buffer = kalloc(BLOCK_SIZE); + if (load_buffer == NULL) { + ERROR("Could not allocate user load buffer"); return 1; + } + } + TRACE("Loading %u elf segments", pcb->n_elf_segments); for (int i = 0; i < pcb->n_elf_segments; i++) if ((ret = user_load_segment(pcb, file, i))) return ret; @@ -110,12 +124,12 @@ static int validate_elf_hdr(struct pcb *pcb) Elf64_Ehdr *ehdr = &pcb->elf_header; if (strncmp((const char *)ehdr->e_ident, ELFMAG, SELFMAG)) { - WARN("Invalid ELF File."); + ERROR("Invalid ELF File."); return 1; } if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) { - WARN("Unsupported ELF Class."); + ERROR("Unsupported ELF Class."); return 1; } @@ -125,17 +139,17 @@ static int validate_elf_hdr(struct pcb *pcb) } if (ehdr->e_machine != EM_X86_64) { - WARN("Unsupported ELF File target."); + ERROR("Unsupported ELF File target."); return 1; } if (ehdr->e_ident[EI_VERSION] != EV_CURRENT) { - WARN("Unsupported ELF File version."); + ERROR("Unsupported ELF File version."); return 1; } if (ehdr->e_phnum > N_ELF_SEGMENTS) { - WARN("Too many ELF segments."); + ERROR("Too many ELF segments."); return 1; } @@ -151,22 +165,30 @@ static int user_load_elf(struct pcb *pcb, struct file *file) { int ret = 0; - if (file->seek(file, 0, SEEK_SET) < 0) + if (file->seek(file, 0, SEEK_SET) < 0) { + ERROR("Cannot read ELF header."); return 1; - ret = file->read(file, (char *)&pcb->elf_header, sizeof(Elf64_Ehdr)); - if (ret < 0) + } + ret = file->read(file, &pcb->elf_header, sizeof(Elf64_Ehdr)); + if (ret < 0) { + ERROR("Cannot read ELF header."); return 1; + } if (validate_elf_hdr(pcb)) return 1; pcb->n_elf_segments = pcb->elf_header.e_phnum; - if (file->seek(file, pcb->elf_header.e_phoff, SEEK_SET) < 0) + if (file->seek(file, pcb->elf_header.e_phoff, SEEK_SET) < 0) { + ERROR("Cannot read ELF segemts"); return 1; - ret = file->read(file, (char *)&pcb->elf_segments, + } + ret = file->read(file, &pcb->elf_segments, sizeof(Elf64_Phdr) * pcb->elf_header.e_phnum); - if (ret < 0) + if (ret < 0) { + ERROR("Cannot read ELF segemts"); return 1; + } return 0; } @@ -217,8 +239,10 @@ static int user_setup_stack(struct pcb *pcb, const char **args, /* stack */ if (mem_alloc_pages_at(pcb->memctx, USER_STACK_LEN / PAGE_SIZE, (void *)(USER_STACK_TOP - USER_STACK_LEN), - F_WRITEABLE | F_UNPRIVILEGED) == NULL) + F_WRITEABLE | F_UNPRIVILEGED) == NULL) { + ERROR("Could not allocate user stack"); return 1; + } /* regs */ memset(&pcb->regs, 0, sizeof(struct cpu_regs)); -- cgit v1.2.3-freya From 347cf9e458897814a66725c02832f9f15824fb88 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:36:10 -0400 Subject: virt alloc fixes --- kernel/memory/virtalloc.c | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) (limited to 'kernel/memory') diff --git a/kernel/memory/virtalloc.c b/kernel/memory/virtalloc.c index da64f3b..3d60a9f 100644 --- a/kernel/memory/virtalloc.c +++ b/kernel/memory/virtalloc.c @@ -145,32 +145,31 @@ int virtaddr_clone(struct virt_ctx *old, struct virt_ctx *new) static void merge_back(struct virt_ctx *ctx, struct virt_addr_node *node) { - while (node->prev) { - if (node->is_alloc != node->prev->is_alloc) + struct virt_addr_node *prev; + for (prev = node->prev; prev != NULL; prev = prev->prev) { + if (prev->is_alloc) break; - struct virt_addr_node *temp = node->prev; - node->start = temp->start; - node->prev = temp->prev; - if (temp->prev) - temp->prev->next = node; - free_node(ctx, temp); + node->start = prev->start; + node->prev = prev->prev; + if (node->prev) + node->prev->next = node; + free_node(ctx, prev); } - if (node->prev == NULL) { + if (node->prev == NULL) ctx->start_node = node; - } } static void merge_forward(struct virt_ctx *ctx, struct virt_addr_node *node) { - while (node->next) { - if (node->is_alloc != node->next->is_alloc) + struct virt_addr_node *next; + for (next = node->next; next != NULL; next = next->next) { + if (next->is_alloc) break; - struct virt_addr_node *temp = node->next; - node->end = temp->end; - node->next = temp->next; - if (temp->next) - temp->next->prev = node; - free_node(ctx, temp); + node->end = next->end; + node->next = next->next; + if (node->next) + node->next->prev = node; + free_node(ctx, next); } } @@ -263,7 +262,6 @@ long virtaddr_free(struct virt_ctx *ctx, const void *virtaddr) if (node->start == virt) { int length = node->end - node->start; int pages = length / PAGE_SIZE; - // FIXME: ??? node->is_alloc = false; merge_back(ctx, node); merge_forward(ctx, node); -- cgit v1.2.3-freya