From 774e3796b252383aafb8b3f30d51a19400c74516 Mon Sep 17 00:00:00 2001 From: Brett Weiland Date: Sun, 18 Apr 2021 16:00:17 -0500 Subject: [PATCH] modified: src/bootloader/bios_functions/bios_disk.asm modified: src/bootloader/bootloader.asm new file: src/include/kernel.h modified: src/include/libc.h modified: src/include/paging.h new file: src/include/panic.h modified: src/kernel/kernel.c modified: src/kernel/libc.c modified: src/kernel/page.c new file: src/kernel/panic.c modified: src/link.ld modified: src/makefile modified: tools/page/page.py --- src/.gdb_history | 458 ++++++++++---------- src/backup | 437 +++++++++++++++++++ src/bootloader/bios_functions/bios_disk.asm | 2 +- src/bootloader/bootloader.asm | 2 +- src/include/kernel.h | 5 + src/include/libc.h | 9 +- src/include/paging.h | 39 +- src/include/panic.h | 27 ++ src/indigo_os | Bin 0 -> 19760 bytes src/kernel/kernel.c | 28 +- src/kernel/libc.c | 25 +- src/kernel/page.c | 236 +++++++--- src/kernel/panic.c | 54 +++ src/link.ld | 5 +- src/makefile | 28 +- tools/page/page.py | 20 +- 16 files changed, 1057 insertions(+), 318 deletions(-) create mode 100644 src/backup create mode 100644 src/include/kernel.h create mode 100644 src/include/panic.h create mode 100755 src/indigo_os create mode 100644 src/kernel/panic.c diff --git a/src/.gdb_history b/src/.gdb_history index 19f3771..41118ac 100644 --- a/src/.gdb_history +++ b/src/.gdb_history @@ -1,256 +1,256 @@ -x 0x1 next -break bzero -c -next -condition 3 i == 98268 +print buddy_size +print pmap->next +print pmap +print *pmap +print *pmap +print pmap quit quit -break bzero +quit +break page.c:198 +c +watch pmap +c +print pmap +next +print buddy_size +next +c +print *pmap +quitquit +quit +break page.c +c +quit +break init_pmap +c +next +watch pmap_i +c +print pmap_i +next +quit +break page.c:220 +c +quit +break init_pmap +c +next +watch pmap_i +c +print pmap_i +c +print pmap_i +next +print zones[zone_i] +next +break page.c:137 +c +next +info b +c +print pmap_i +c +print pmap_i +c +print pmap_i +next +print *pmap +print pmap +quit +break page.c:220 +c +print pmap +print *pmap +quit +break debug_pmap c c quit +break page.c:179 +c +next +print buddy_bit +print budorder +c +quit +quit +break page.c:147 +c +next +print threshold_bitsize +print (uint64_t)threshold_bitsize +print pmap_i +print *pmap +print threshold_bitsize +print buddy_bitsize +next +print buddy_bit +print buddy_bit +print buddy_bitlen +print buddy_bitlen[0][7] +print buddy_bitlen[0][7] +next +quit break panic c +next +x ebp +print $ebp +info reg ebp +x 0x1ffff8 +stack 50 quit -break map_page +break debug_pmap c -next -break bzero -d 2 -c -next -return +info reg rbp +info reg rbp +x 0x1fffe8 +print (void*)&debug_pmap next stack +stack 50 +info reg rbp +x 0x1fffe8 +x/20 0x1fffe8 quit quit -break bzero -c -page_table *table = (page_table *)PAGEMAP_LOCATION -print page_table *table = (page_table *)PAGEMAP_LOCATION -print (page_table *)PAGEMAP_LOCATION -print (page_table *)0x4000 -print *(page_table *)0x4000 -print (page_table *)0x4000.pml4 -print (page_table *)0x4000.pml4e -print (page_table *)0x4000->pml4e -print *((page_table *)0x4000).pml4e -print *((page_table *)0x4000).pml4e[0] -print ((page_table *)0x4000).pml4e[0] -print ((page_table *)0x4000).pml4e[2] -print ((page_table *)0x4000).pml4e[3] -print ((page_table *)0x4000).pml4e[4] -print ((page_table *)0x4000).pml4e[1] -print ((page_table *)0x4000).pml4e[1] -print ((page_table *)0x4000).pml4e[1] -print ((page_table *)0x4000).pml4e[1] -print ((page_table *)0x4000).pml4e[0] -print ((page_table *)0x4000).pde[0] -print ((page_table *)0x4000).pde[1] -print ((page_table *)0x4000).pde[0] -print ((page_table *)0x4000).pde[20] -print ((page_table *)0x4000).pde[10] -print ((page_table *)0x4000).pde[0] -print ((page_table *)0x4000).pde[1] -print ((page_table *)0x4000).pde[2] -print ((page_table *)0x4000).pde[0] -print ((page_table *)0x4000).pde[1] -print ((page_table *)0x4000).pde[0] -print ((page_table *)0x4000).pde[1] -print ((page_table *)0x4000).pde[2] -print ((page_table *)0x4000).pde[2] -print ((page_table *)0x4000).pde[21] -print ((page_table *)0x4000).pde[1] +break panic c next -break bzero -c -c -next -watch i -c -info breakpoints -d 4 3 2 -info watchpoitns -info watchpoints -watch i -c -c -info breakpoints -c -d 5 -next -watch i -c -condition 6 i == 9999999 -c -x 0 -x 1 -nexti -break bzero -c -next -watch i -condition 8 i == 16359 -c -x 0x1fffb8 -next -print p1[o]i] -print p1[i] -print p1 +info stack stack +next +info rsp +x 0x1fff28 +x *0x1fff28 +stack 50 quit -break bzero +break panic +c +c +stack +stack 50 +c +stack 50 +info reg rbp +quit +break panic c next -watch i -condition i == 16359 -c -condition 3 i == 16359 -c -x 0 -print p1 -print p1[i] -print &p1[i] -print &(p1[i]) -x p1 -x p1[i] -nexti -next +print stack +stack 50 +stack --help +stack 0x20 +stack 100 0x20 +info reg rbp +info reg rbp + 1 +info reg rbp +x 0x1fff58+8 +x 0x1fff58-8 +x 0x1fff58+1 quit -c -quit -c -quit -quit -quit -quit -next -break mina break main c +next +stepi +next +stepi +x 0x1fffe8 - 8 +x 0x1fffe8 + 8 +x 0x1fffe8 +x 0x1fffc8-8 +x 0x1fffe8-8 +next +step +print rsp +stack +x $rbp-8 +next +x $rbp-8 +x $rbp+8 +stack 50 +stack 100 +stack 90 +stack 90 90 +stack 90 +x $ebp +x $ebp-8x $eb +x $ebp-8 +x $ebp+8 +quit +break panic.c:27 +c +next +print *Frame +print frame +print *frame +print frame->function_base +print/x frame->function_base +x 0x103ef2 +x frame->function_base +x frame->lastframe->function_base +quit +break panic.c:29 +c +print *frame +c +quit +break page.c:30 +c +quit +break panic.c:30 +c +c +pirnt *frame +print *frame +c +print *frame +c +print *frame +c +print *frame +c +print *frame +x 0x1ffff8 +c +quit +c +x 831e +x 0x831e +x 0x103f58 +x/i 0x831e +x/i 0x831e-8 +x/i 0x831e-16 +x/10i 0x831e +x/10i 0x831e-16 +x/10i 0x831e-1 +x/10i 0x831e- +x/10i 0x831e +x/10i 0x831e-8 +x/10i 0x831e+8 +x/10i 0x831e +quit +break 0x831e +c +quit +b *0x831e +c +quit +quit +c +print *frame +print *frame +x *frame +x/1 *frame + *frame +quit +break main.c +c +quit break main c -quit -break bzero -c -next -next -quit -break bzero -c -next -print p1 -next -nexti -info reg rax -next +stack c quit -c -quit -break bzero -c -next -watch i -condition 3 i == 1000000 -c -quit -break bzero -c -next -watch i -condition 3 i == 100000 -c -quit -break bzero -c -next -watch i -condition 3 i == 100000 -c -x 0x0000000000204000 -info reg -info reg rip -quit -break bzero -c -next -watch i -condition 3 i == 20454 -c -quit -break bzer -break bzero -c -next -condition i = 16360 -condition 3 i == 16360 -watch i -condition 3 i == 16360 -c -print (struct page_table)0x5000 -print (page_table)0x5000 -print (page_table *)0x5000 -print (page_table *)0x4000 -print (page_table *)0x4000.pml4e[0] -print (page_table *)0x4000->pml4e[0] -print (page_table *)0x4000->pml4e[ -print (page_table *)0x4000->pml4e -print ((page_table *)0x4000).pml4e -print ((page_table *)0x4000).pml4e[0] -print ((page_table *)0x4000).pde[0] -print ((page_table *)0x4000).pde[1] -print ((page_table *)0x4000).pde[0] -print ((page_table *)0x4000).pde[2] -print ((page_table *)0x4000).pde[1] -print ((page_table *)0x4000).pde[0] -print ((page_table *)0x4000).pde[1] -print ((page_table *)0x4000).pde[0] -print ((page_table *)0x4000).pde[1] -print ((page_table *)0x4000).pde[2] -print ((page_table *)0x4000).pde[3] -quit -break mod_page_pde -break map_page -c -next -print table->pde -print table->pde[1] -next -print table->pde[1] -quit -break map_page -c -next -next -next -quit -break map_page -c -next -mext -next -print table->pde[pde_i] -quit -break map_page -c -next -print table->pde[pde_i] -next -quit -break map_page -c -next -quit -break init_memory -c -next -next -break map_page -c -return -next -pirnt map -quit diff --git a/src/backup b/src/backup new file mode 100644 index 0000000..9191304 --- /dev/null +++ b/src/backup @@ -0,0 +1,437 @@ +#include +#include +#include +#include +#include +#include + +void debug_print_memory() { + struct memory_table *memtable = (struct memory_table *)&_meminfo_loc; + printf(" __________________________________________________________________________\n"); + printf("| type\tstart\t\t\tend\t\t\tsize\t\t |\n"); + printf("|--------------------------------------------------------------------------|\n"); + for(unsigned int i = 0; memtable[i].length > 0; i++) { + printf("| %u %u\t0x%p\t0x%p\t0x%p |\n", memtable[i].type, memtable[i].ACPI, memtable[i].base, (memtable[i].base + memtable[i].length), memtable[i].length); + } + printf("----------------------------------------------------------------------------\n"); +} + +void debug_pmap() { + struct phys_map* pmap; + int pmap_i = 0, order; + uint64_t buddy_size, blong_i, bbit_i, buddy_chunksize, omit_cnt; + printf("Maximum buddy order: %u (up to %#x sized chunks)\n", MAX_BUDDY_ORDER, (0x1000 << MAX_BUDDY_ORDER - 1)); + for(pmap = (struct phys_map*)&_stage2_pagetable; pmap != 0; pmap = pmap->next) { + printf("Table %u:\n" + "\tPhysical Start:\t%#p\n" + "\tTable location:\t%#p\n", pmap_i, pmap->zone_paddr, pmap); + for(order = 0; order <= MAX_BUDDY_ORDER - 1; order++) { + buddy_chunksize = (0x1000 << order); //TODO just put it in the for loop + buddy_size = (((order == MAX_BUDDY_ORDER - 1) + ? (uint64_t *)pmap->next : pmap->buddy[order + 1]) - pmap->buddy[order]); + printf("\tbuddy[%u]:\n" + "\t\tAddress:\t%#x\n" + "\t\tSize:\t\t%u\n" + "\t\tBuddies:\t\t\n", order, pmap->buddy[order], buddy_size); + + omit_cnt = 0; + + for(blong_i = 0; blong_i < buddy_size; blong_i++) { + for(bbit_i = 0; bbit_i < 64; bbit_i++) { + if(*(pmap->buddy[order] + blong_i) & ((uint64_t)1 << bbit_i)) { + if((omit_cnt < 20) || (blong_i == buddy_size - 1)) { + printf("address %#x\tbit %u: %x\t is free\n", + pmap->buddy[order] + blong_i, bbit_i, pmap->zone_paddr + ((blong_i * 64) + bbit_i) * buddy_chunksize); + } + omit_cnt++; + if(omit_cnt == 20) { + printf("\t\t\t[more entries ommited]\n"); + } + } + } + } +print_next_buddy: ; + } + pmap_i++; + } +} + +/* + * part 1: + * init tables (complete) + * + * part 2: setting the actual entires + * if entry contains table, set 0, set threshold + * else: + * if entry: + */ + +// init_memory revision +// rules: + /** +void init_pmap() { + struct memory_table *memtable = (struct memory_table *)&_meminfo_loc; + struct phys_map *pmap = (struct phys_map*)&_stage2_pagetable; + struct phys_map *last_pmap; + unsigned int i, x; + uint64_t budentry_len, pmap_chunksize, total_pmap_len = 0; + void *y; + void *paged_mem = &_stage2_pagetable + 0x200000; + map_page(&_stage2_pagetable, &_stage2_pagetable, PAGE_SIZE_2M); + for(i = 0; memtable[i].length > 0; i++) { + if((memtable[i].type == MEM_AVAILABLE) && (memtable[i].ACPI & 1)) { + total_pmap_len += 88; //it'd be nice to find a cleaner way + + //make sure we don't overwrite what we have so far of the kernel + if((memtable[i].base <= (void*)&_stage2_pagetable) && (memtable[i].base + memtable[i].length >= (void *)&_stage2_pagetable)) { + pmap->chunk_start = &_stage2_pagetable; + pmap->chunk_size = memtable[i].length - (pmap->chunk_start - memtable[i].base); + } + else { + pmap->chunk_start = memtable[i].base; + pmap->chunk_size = memtable[i].length; + } + + for(x = 0; x < 8; x++) { + pmap->bsize[x] = ceil((pmap->chunk_size / (0x1000 * (1 << x))) / (double)64); + total_pmap_len += pmap->bsize[x] * 8; + } + + pmap->next = (void*)&_stage2_pagetable + total_pmap_len; + + while((void*)pmap->next + sizeof(struct phys_map) >= paged_mem) { + //do check here if nessesary + map_page(paged_mem, paged_mem, PAGE_SIZE_2M); + paged_mem += 0x200000; + } + + last_pmap = pmap; + pmap = pmap->next; + } + } + last_pmap->next = 0; //I wonder if there's a better way to do this + pmap = (struct phys_map*)&_stage2_pagetable; + +} +**/ + +void init_pmap() { + struct memory_table *zones = (struct memory_table *)&_meminfo_loc; + struct phys_map *pmap = (struct phys_map*)&_stage2_pagetable; + struct phys_map *last_pmap = (struct phys_map*)&_stage2_pagetable; + + unsigned int zone_i, pmap_i = 0; + int budorder; + + //we keep this info out of the struct because we won't need it after setting up + uint64_t zone_len[MAX_ZONE_CNT], buddy_bitlen[MAX_ZONE_CNT][MAX_BUDDY_ORDER]; + uint64_t *buddy_end; + + uint64_t pmap_size, pmap_bbitsize, pmap_blongsize, buddy_size, pmap_bit; + uint64_t threshold_longsize = 0, threshold_bit, threshold_end, threshold_bitsize; + uint64_t deleteme_last_p_bits; + + + void *paged_mem = (void *)&_stage2_pagetable + 0x200000; + map_page(&_stage2_pagetable, &_stage2_pagetable, PAGE_SIZE_2M); + + for(zone_i = 0; zones[zone_i].length > 0; zone_i++) { + + if((zones[zone_i].type == MEM_AVAILABLE) && (zones[zone_i].ACPI & 1)) { + + //hopefully this should never happen... but x86 is routy. + //I should dig into the docs to check before removing this. + //We also could forget about MAX_ZONE_CNT if we did. + + if(zone_i >= MAX_ZONE_CNT) { + printf("Only %u zones can be used! Modify MAX_ZONE_CNT in paging.h to use all memory.\n", MAX_ZONE_CNT); + break; + } + + + if((zones[zone_i].base <= (void*)&_stage2_pagetable) && + (zones[zone_i].base + zones[zone_i].length >= (void *)&_stage2_pagetable)) { + pmap->zone_paddr = &_stage2_pagetable; + zone_len[pmap_i] = zones[zone_i].length - (pmap->zone_paddr - zones[zone_i].base); + } + else { + pmap->zone_paddr = zones[zone_i].base; + zone_len[pmap_i] = zones[zone_i].length; + } + + pmap->buddy[0] = (void *)pmap + sizeof(*pmap); + + for(budorder = 1; budorder < MAX_BUDDY_ORDER; budorder++) { + buddy_bitlen[pmap_i][budorder - 1] = GET_BUDDY_BITLEN(zone_len[pmap_i], budorder - 1); + pmap->buddy[budorder] = (uint64_t *)pmap->buddy[budorder - 1] + + LSIZE_FROM_BITLEN(buddy_bitlen[pmap_i][budorder - 1]); + } + + buddy_bitlen[pmap_i][MAX_BUDDY_ORDER - 1] = GET_BUDDY_BITLEN(zone_len[pmap_i], MAX_BUDDY_ORDER - 1); + pmap->next = (void *)pmap->buddy[MAX_BUDDY_ORDER - 1] + + (LSIZE_FROM_BITLEN(buddy_bitlen[pmap_i][MAX_BUDDY_ORDER - 1]) * 8); + + pmap = pmap->next; + pmap_i++; + last_pmap = pmap; + + //allocates by an extra sizeof(struct phys_map), + //but were about to discard anyway + while((void *)pmap + sizeof(*pmap) >= paged_mem) { + map_page(paged_mem, paged_mem, PAGE_SIZE_2M); + paged_mem += 0x200000; + } + + } + } + pmap_size = (void*)(pmap) - (void*)&_stage2_pagetable; + if(pmap_size >= zone_len[0]) panic(); //TODO debugging + + pmap = (struct phys_map*)&_stage2_pagetable; + + // Honestly, this section makes me feel like Yandere Dev. It's ugly. + // I've been rewriting this function forever, so I'm deciding to slam it out start to finish. + // I know there's a lot of repeated if statements. I know it hurts. + // But fear not. + // I'll come back and rewrite this part when I've gotten a break from memory management. + for(pmap = (struct phys_map*)&_stage2_pagetable; pmap != 0; pmap++) { + for(budorder = MAX_BUDDY_ORDER - 1; budorder >= 0; budorder--) { + pmap_bbitsize = ceil((float)pmap_size / ((uint64_t)0x1000 << budorder)); + pmap_blongsize = pmap_bbitsize / 64; + + if(budorder == MAX_BUDDY_ORDER - 1) { + buddy_end = (uint64_t *)pmap->next - 1; + threshold_bitsize = ((pmap_blongsize * 64) + pmap_bbitsize) * 2; + threshold_bitsize = UINT64_MAX; + } + else { + buddy_end = pmap->buddy[budorder + 1] - 1; + threshold_longsize = threshold_bitsize / 64; + threshold_end = threshold_longsize + 1; + } + pmap_bit = pmap_bbitsize & 63; + buddy_size = buddy_end - pmap->buddy[budorder]; + + + if(pmap_bbitsize >= BITLEN_FROM_LSIZE(buddy_size)) { + //is this nessesary? + bzero(pmap->buddy[budorder], buddy_size * 8); + } + else { + if(budorder == MAX_BUDDY_ORDER - 1) { + if(pmap_blongsize) bzero(pmap->buddy[budorder], (pmap_blongsize - 1) * 8); + if(pmap_bit) { + *(pmap->buddy[budorder] + pmap_blongsize) = ~(((uint64_t)1 << pmap_bit) - 1); + } + else { + *(pmap->buddy[budorder] + pmap_blongsize) = UINT64_MAX; + } + if(pmap_blongsize + 1 == buddy_size) { + //TODO why did I have this conditional? Do I need it later? Check on desktop before removing + if(buddy_bitlen[0][budorder]) { + *(pmap->buddy[budorder] + pmap_blongsize) &= + ((uint64_t)1 << (buddy_bitlen[0][budorder] & 63)) - 1; + } + } + else { + memset(pmap->buddy[budorder] + pmap_blongsize + 1, UINT8_MAX, + (void *)buddy_end - (void *)pmap->buddy[budorder] - 8); + *buddy_end = ((uint64_t)1 << (buddy_bitlen[0][budorder] & 63)) - 1; + } + } + else { + if(threshold_longsize) bzero(pmap->buddy[budorder], (threshold_longsize - 1) * 8); + + if(threshold_bitsize > pmap_bbitsize) + *(pmap->buddy[budorder] + threshold_longsize) = ((uint64_t)1 << ((threshold_bitsize - 1) & 63)); + + if(buddy_size - threshold_longsize) + bzero(pmap->buddy[budorder] + threshold_longsize + 1, buddy_size - threshold_longsize); + *buddy_end = ((uint64_t)1 << ((buddy_bitlen[0][budorder] & 63) - 1)); + } + threshold_bitsize = ((pmap_blongsize * 64) + pmap_bbitsize) * 2; + } + } + } +// for(pmap = pmap->next; pmap != 0; pmap++) { +// } +} + + +// for(budlong_ptr = pmap->buddy[budorder]; budlong_ptr < (uint64_t *)pmap->next - 1; budlong_ptr++) { + +/** +//uses buddy system allocation +void init_memory() { + struct memory_table *memtable = (struct memory_table *)&_meminfo_loc; + struct phys_map *map = (struct phys_map*)&_stage2_pagetable; + struct phys_map *lasttable; + unsigned int i, buddy_chunksize; + uint64_t buddy_bitsize, prev_buddy_bsize, ppt_size; + uint64_t *buddy_ptr, *budentry_end, *threshold; + uint64_t buddy_size64; + + map_page((void*)&_stage2_pagetable, (void*)&_stage2_pagetable, PAGE_SIZE_2M); + void *next_page = (void *)0x400000; + // at this point, we are declaring our header and kernel itself as free (so don't forget to fix that!) + + //TODO all these for loops are unsanitary. + //We hae a lot of branches in the for loops, + //And we re-do work to allocate the page-table. + //I'll clean this up when I'm certain my buddy system works. + for(i = 0; memtable[i].length > 0; i++) { + if((memtable[i].type == MEM_AVAILABLE) && (memtable[i].ACPI & 1)) { + map->chunk_start = (void*)memtable[i].base; + map->chunk_size = memtable[i].length; + buddy_ptr = (void*)&map->buddies; + + for(buddy_chunksize = 0x1000; buddy_chunksize < 0x100000; buddy_chunksize *= 2) { + buddy_bitsize = memtable[i].length / buddy_chunksize; + buddy_size64 = ceil(buddy_bitsize / (double)64); + + if((void*)&buddy_ptr[buddy_size64] + 24 >= next_page) { + map_page(next_page, next_page, PAGE_SIZE_2M); + next_page += 0x200000; + } + + printf("buddy\t%x\theader bitsize\t%u\theader longsize\t%u\tbuddy start\t%p",\ + buddy_chunksize, buddy_bitsize, buddy_size64, buddy_ptr); + if(((buddy_bitsize * 2) != prev_buddy_bsize) && (buddy_chunksize != 0x1000)) { + buddy_ptr[-1] |= ((uint64_t)1 << ((prev_buddy_bsize & 63) - 1)); + printf("\tlast:\t%lx", buddy_ptr[-1]); + } + printf("\n"); + + if(buddy_chunksize < 0x80000) { + bzero(buddy_ptr, buddy_size64 * 8); + prev_buddy_bsize = buddy_bitsize; + } + + else if(buddy_size64 % buddy_bitsize) { + memset(buddy_ptr, 0xff, (buddy_size64 - 1) * 8); + buddy_ptr[buddy_size64] |= 1 << buddy_bitsize; + } + + else memset(buddy_ptr, 0xff, buddy_size64); + + buddy_ptr += buddy_size64; + } + + //this feels kind of gross + lasttable = map; + map->next = (struct phys_map*)buddy_ptr; + map = (struct phys_map*)buddy_ptr; + } + } + lasttable->next = (void*)0; + map = (struct phys_map*)&_stage2_pagetable; + //now we will allocate the table out of itself so we don't mess things up. + //We can't just call palloc(), we need to allocate out of the first available pages (where the pages are) + //we should clean this whole gross function + /** + ppt_size = (uint64_t)((void *)buddy_ptr - (void *)&_stage2_pagetable); + threshold = (void*)UINT64_MAX; + int buddy_bit; + for(buddy_chunksize = 0x80000; buddy_chunksize >= 0x1000; buddy_chunksize /= 2) { + //this means that our table must fit into the first page table. Fixme later, low priotrity + buddy_size64 = ceil((map->chunk_size / buddy_chunksize) / (double)64); + budentry_end = buddy_ptr; + for(buddy_ptr -= buddy_size64; buddy_ptr <= budentry_end; buddy_ptr++) { + if(buddy_ptr > threshold) { + buddy_ptr = budentry_end; + continue; + } + if( + } + } +} + **/ + +//TODO this function was deleted due to it being wrong. +//I'll create it once I have the physical paging prerequisite set up. +void create_pagetable_stage2(uint64_t free_mem) { +} + + +/** + * BIG TODO: + * Paging turned out to be simpler then I thought. I've temporarily fixed the code, but needs to be rewritten/simplified. + * Let's get rid of those nasty GOTOs if we can. + * Also, once we get physical memory allocator up and running, impliment that in this function. +**/ + +bool map_page(void *virtual_addr, void *physical_addr, uint8_t size) { + //printf("map page called\n"); + uintptr_t va_ptr = (uintptr_t)virtual_addr; + uintptr_t pa_ptr = (uintptr_t)physical_addr; + if((va_ptr % (1 << size)) || (pa_ptr % (1 << size))) { + return 0; + } + page_table *table = (page_table *)PAGEMAP_LOCATION; + int pte_i = (va_ptr >> 12) & 0x1ff; + int pde_i = (va_ptr >> 21) & 0x1ff; + int pdpe_i = (va_ptr >> 30) & 0x1ff; + int pml4e_i = (va_ptr >> 39) & 0x1ff; + + if(table->pml4e[pml4e_i].present) { + if(table->pml4e[pml4e_i].base_ptr != (uintptr_t)&table->pdpe[pdpe_i] >> 12) goto error; + if(table->pdpe[pdpe_i].present) { + if(size == PAGE_SIZE_1G) { + if(table->pdpe[pdpe_i].base_ptr == ((uintptr_t)pa_ptr >> 30 & 0x1ff)) + return true; + goto error; + } + if(table->pdpe[pdpe_i].base_ptr != (uintptr_t)&table->pde[pde_i] >> 12) goto error; + + if(table->pde[pde_i].present) { + if(size == PAGE_SIZE_2M) { + if(table->pde[pde_i].base_ptr == ((uintptr_t)pa_ptr >> 21 & 0x1ff)) + return true; + goto error; + } + if(table->pde[pde_i].base_ptr != (uintptr_t)&table->pte[pte_i] >> 12) goto error; + if(table->pte[pte_i].present) { + if(table->pte[pte_i].base_ptr != ((pa_ptr >> 12) & 0x1ff)) goto error; + return true; + } + else goto mod_page_pte; + } + else goto mod_page_pde; + } + else goto mod_page_pdpe; + } + else { + table->pml4e[pml4e_i].base_ptr = (uintptr_t)&table->pdpe[pdpe_i] >> 12; + table->pdpe[pml4e_i].read_write = 1; + table->pml4e[pml4e_i].present = 1; +mod_page_pdpe: + table->pdpe[pdpe_i].read_write = 1; + //TODO you just found out things are a lot more simple then you thought! + if(size == PAGE_SIZE_1G) { + table->pdpe[pdpe_i].size = 1; + table->pdpe[pdpe_i].base_ptr = pa_ptr >> 12; + table->pdpe[pdpe_i].present = 1; + return true; + } + table->pdpe[pdpe_i].base_ptr = (uintptr_t)&table->pde[pde_i] >> 12; + table->pdpe[pdpe_i].present = 1; +mod_page_pde: + table->pde[pde_i].read_write = 1; + if(size == PAGE_SIZE_2M) { + table->pde[pde_i].size = 1; + table->pde[pde_i].base_ptr = pa_ptr >> 12; + table->pde[pde_i].present = 1; + return true; + } + table->pde[pde_i].base_ptr = (uintptr_t)&table->pte[pte_i] >> 12; + table->pde[pde_i].present = 1; +mod_page_pte: + table->pte[pte_i].base_ptr = pa_ptr >> 12; + table->pte[pte_i].read_write = 1; + table->pte[pte_i].present = 1; + return true; + } +error: + printf("Page allocation error!\n"); + return false; +} diff --git a/src/bootloader/bios_functions/bios_disk.asm b/src/bootloader/bios_functions/bios_disk.asm index 7957814..195057a 100644 --- a/src/bootloader/bios_functions/bios_disk.asm +++ b/src/bootloader/bios_functions/bios_disk.asm @@ -19,7 +19,7 @@ popa ret .failed: - +debug: mov bx, .loadsectors_error mov cx, 0 call bios_print diff --git a/src/bootloader/bootloader.asm b/src/bootloader/bootloader.asm index 947965f..3ac10f3 100644 --- a/src/bootloader/bootloader.asm +++ b/src/bootloader/bootloader.asm @@ -115,7 +115,7 @@ nop pop cx -cmp cl, _kernel_size +cmp cl, _kernel_size+2 je .loop_end jmp .loop diff --git a/src/include/kernel.h b/src/include/kernel.h new file mode 100644 index 0000000..2a87f5e --- /dev/null +++ b/src/include/kernel.h @@ -0,0 +1,5 @@ +#define EASTEREGG_BLOATWARE //TODO move to some kind of global config file +void panic(); + +#define KERNEL_PANIC_INVOKED 0 +//more to come diff --git a/src/include/libc.h b/src/include/libc.h index cdf6dbc..c7ccda7 100644 --- a/src/include/libc.h +++ b/src/include/libc.h @@ -2,11 +2,12 @@ #define _STRING_H_ #include +void *strcpy(char *dest, char *src); +void *memcpy(void *dest, void *src, size_t n); //TODO +void *bzero(const void *dest, size_t size); +void *memset(void *s, char c, size_t n); int strcmp(const char *str1, const char *str2); int strncmp(const char *str1, const char *str2, size_t n); -void strcpy(char *dest, char *src); -void memcpy(void *dest, void *src, size_t n); //TODO int memcmp(const void *s1, const void *s2, size_t n); -void bzero(const void *dest, size_t size); -int ceil(float n1); +int ceil(double n1); #endif diff --git a/src/include/paging.h b/src/include/paging.h index 267da43..3d31ef2 100644 --- a/src/include/paging.h +++ b/src/include/paging.h @@ -45,19 +45,38 @@ typedef struct __attribute__((packed)) { #define PAGE_SIZE_2M 21 #define PAGE_SIZE_1G 30 +#define MAX_BUDDY_ORDER 8 + +#define MAX_ZONE_CNT 16 //should cover all cases + struct memory_table { - uint64_t base; + void *base; uint64_t length; uint32_t type; uint32_t ACPI; } __attribute__((packed)); +/** + * the bsizes are there so we don't have to calculate it every time. + * + * Keep in mind that at if the allocator reaches the last buddy, + * it _will_ have to calculate the bitwidth, even if it's a multiple of 64. + * This scenario hopefully won't happen much during time sensitive areas, + * and (I think) linux calculates the buddy size every single time anyway. +**/ struct phys_map { - uint64_t map_size; //this way we won't have to calculate it every time - void *chunk_start; - uint64_t chunk_size; - uint64_t *buddies; -} __attribute__((packed)); + struct phys_map *next; + void *zone_paddr; + uint64_t extra_bits; + uint64_t *buddy[MAX_BUDDY_ORDER]; +}; + +//clean up doing extra work some other time +#define LSIZE_FROM_BITLEN(bitlen) (((bitlen) + 63) / 64) +#define BITLEN_FROM_LSIZE(lsize) ((lsize) * 64) +#define GET_BUDDY_BITLEN(zone_len, order) ((zone_len) / (0x1000 << (order))) +#define GET_ORDER_CHUNKSIZE(order) (0x1000 << ((order))) + extern void* _meminfo_loc; @@ -66,6 +85,12 @@ extern void* _stage2_pagetable; bool map_page(void *virtual_addr, void *physical_addr, uint8_t PAGE_SIZE); void debug_print_memory(); void create_pagetable_stage2(uint64_t free_mem); -void init_memory(); +void init_memory(); //TODO removeme +void init_pmap(); +void *palloc(); +void *pfree(); +void debug_pmap(); + + #endif diff --git a/src/include/panic.h b/src/include/panic.h new file mode 100644 index 0000000..1386348 --- /dev/null +++ b/src/include/panic.h @@ -0,0 +1,27 @@ +#ifndef PANIC_INCLUDED +#define PANIC_INCLUDED + +#define EASTEREGG_BLOATWARE + +#include + +void panic(int reason, int type); +struct stack_frame { + struct stack_frame *next; + uint64_t function_base; +} __attribute__((packed)); + +//kernel panic reasons, likely to grow at an extremely fast rate +#define KERNEL_PANIC_PMAPSIZE 0 +#define KERNEL_PANIC_RSDP_UNFOUND 1 +#define KERNEL_PANIC_KERNEL_RETURNED 2 + + +//kernel panic types, may or may not expand once I get further in development +#define KERNEL_PANIC_INVOKED 0 +#define KERNEL_PANIC_ERROR 1 //i'll change this once I see what happends + +//TODO move this to some kind of global more accesable header +#define DEV_EMAIL "brett_weiland@bpcspace.com" + +#endif diff --git a/src/indigo_os b/src/indigo_os new file mode 100755 index 0000000000000000000000000000000000000000..9186bf2f3d4c54efd0c38e864cbc2a5fd301bf32 GIT binary patch literal 19760 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 literal 0 HcmV?d00001 diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index d7fc3e0..025dcf3 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -4,14 +4,29 @@ #include #include #include +#include -void panic() { // will fill with debugging info latter - printf("Kernel panic!\n"); - for(;;); + +void test4() { + char bruh[10]; + panic(KERNEL_PANIC_KERNEL_RETURNED, KERNEL_PANIC_INVOKED); +} +void test3() { + char bruh[5]; + test4(); +} +void test2() { + int a = 1; + test3(); +} +void test1() { + printf("fuck\n"); + test2(); } void main() { + test1(); if(!(init_serial(COM1))) { printf("\nKernal started on CPU 1!\n"); // will detect cpu later } @@ -20,15 +35,16 @@ void main() { rsdp = find_RSDP(); if(!(rsdp)) { printf("Couldn't find the RSDP... not sure what to do now.\n"); - panic(); + panic(KERNEL_PANIC_RSDP_UNFOUND, KERNEL_PANIC_INVOKED); } dump_video(); debug_print_memory(); - init_memory(); + init_pmap(); + debug_pmap(); - panic(); + panic(KERNEL_PANIC_KERNEL_RETURNED, KERNEL_PANIC_INVOKED); } diff --git a/src/kernel/libc.c b/src/kernel/libc.c index dc5c0ac..c786cd0 100644 --- a/src/kernel/libc.c +++ b/src/kernel/libc.c @@ -39,22 +39,33 @@ void strcpy(char *dest, char *src) { } } -void memcpy(char *dest, char *src, size_t n) { +void *memcpy(void *dest, char *src, size_t n) { + char *p = dest; for(unsigned int i = 0; i <= n; i++) { - dest[i] = src[i]; + p[i] = src[i]; } + return(dest); } -void bzero(void *dest, size_t size) { - unsigned char *p1 = dest; +void *bzero(void *dest, size_t size) { + char *p = dest; for(uint64_t i = 0; i < size; i++) { - p1[i] = 0; + p[i] = 0; } + return(dest); } //TODO move this function to a seperate math library -int ceil(float n) { +unsigned int ceil(double n) { int low_n = (int)n; - if(n == (float)low_n) return(low_n); + if(n == (double)low_n) return(low_n); return(low_n + 1); } + +void *memset(void *s, char c, size_t n) { + char *p = s; + for(size_t i = 0; i < n; i++) { + p[i] = c; + } + return(s); +} diff --git a/src/kernel/page.c b/src/kernel/page.c index 6f1dd7c..de4f557 100644 --- a/src/kernel/page.c +++ b/src/kernel/page.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include void debug_print_memory() { struct memory_table *memtable = (struct memory_table *)&_meminfo_loc; @@ -14,62 +16,194 @@ void debug_print_memory() { printf("----------------------------------------------------------------------------\n"); } +void debug_pmap() { + struct phys_map* pmap; + int pmap_i = 0, order; + uint64_t buddy_size, blong_i, bbit_i, buddy_chunksize, omit_cnt; + printf("Maximum buddy order: %u (up to %#x sized chunks)\n", MAX_BUDDY_ORDER, (0x1000 << MAX_BUDDY_ORDER - 1)); + for(pmap = (struct phys_map*)&_stage2_pagetable; pmap != 0; pmap = pmap->next) { + printf("Table %u:\n" + "\tPhysical Start:\t%#p\n" + "\tTable location:\t%#p\n", pmap_i, pmap->zone_paddr, pmap); + for(order = 0; order <= MAX_BUDDY_ORDER - 1; order++) { + buddy_chunksize = (0x1000 << order); //TODO just put it in the for loop + buddy_size = (((order == MAX_BUDDY_ORDER - 1) + ? (uint64_t *)pmap->next : pmap->buddy[order + 1]) - pmap->buddy[order]); + printf("\tbuddy[%u]:\n" + "\t\tAddress:\t%#x\n" + "\t\tSize:\t\t%u\n" + "\t\tBuddies:\t\t\n", order, pmap->buddy[order], buddy_size); -//uses buddy system allocation -void init_memory() { - struct memory_table *memtable = (struct memory_table *)&_meminfo_loc; - struct phys_map *map = (struct phys_map*)0x200000; - uintptr_t onpage = 0x200000; - unsigned int i, x, buddy_size, buddy_bitsize, prev_buddy_bsize; - uint64_t *buddy_ptr; - - map_page((void*)0x200000, (void*)0x200000, PAGE_SIZE_2M); - void *next_page = (void *)onpage + 0x200000; - // at this point, we are declaring our header and kernel itself as free (so don't forget to fix that!) - - for(i = 0; memtable[i].length > 0; i++) { - if((memtable[i].type == MEM_AVAILABLE) && (memtable[i].ACPI & 1)) { - - map->chunk_start = (void*)memtable[i].base; - map->chunk_size = memtable[i].length; - buddy_ptr = (void*)&map->buddies; + omit_cnt = 0; - - for(x = 0; x < 8; x++) { - - buddy_bitsize = memtable[i].length / (0x1000 * (1 << x)); - buddy_size = ceil(buddy_bitsize / (float)8); - - if((void *)buddy_ptr + buddy_size >= next_page) { - map_page(next_page, next_page, PAGE_SIZE_2M); - next_page += 0x200000; + for(blong_i = 0; blong_i < buddy_size; blong_i++) { + for(bbit_i = 0; bbit_i < 64; bbit_i++) { + if(*(pmap->buddy[order] + blong_i) & ((uint64_t)1 << bbit_i)) { + if((omit_cnt < 20) || (blong_i == buddy_size - 1)) { + printf("address %#x\tbit %u: %p\t is free\n", + pmap->buddy[order] + blong_i, bbit_i, (uint64_t)pmap->zone_paddr + (((blong_i * 64) + bbit_i) * buddy_chunksize)); + } + omit_cnt++; + if(omit_cnt == 20) { + printf("\t\t\t[more entries ommited]\n"); + } + } } - - bzero(buddy_ptr, buddy_size); //meant to be /8? - - if((buddy_bitsize * 2) != prev_buddy_bsize) { - buddy_ptr[-1] |= (1 << ((prev_buddy_bsize % 8) - 1)); - } - - buddy_ptr += buddy_size; - - prev_buddy_bsize = buddy_bitsize; - } - map->map_size = buddy_ptr - (uint64_t*)map; - map = (struct phys_map *)map + map->map_size; - - if((void *)map + 24 >= next_page) { - map_page(next_page, next_page, PAGE_SIZE_2M); - next_page += 0x200000; - } - } + } + pmap_i++; } } -//TODO this function was deleted due to it being wrong. -//I'll create it once I have the physical paging prerequisite set up. -void create_pagetable_stage2(uint64_t free_mem) { +void init_pmap() { + struct memory_table *zones = (struct memory_table *)&_meminfo_loc; + struct phys_map *pmap = (struct phys_map*)&_stage2_pagetable; + + unsigned int zone_i, pmap_i = 0; + int budorder; + + //we keep this info out of the struct because we won't need it after setting up + uint64_t zone_len[MAX_ZONE_CNT], buddy_bitlen[MAX_ZONE_CNT][MAX_BUDDY_ORDER], *buddy_end; + uint64_t pmap_size, pmap_bbitsize, pmap_blongsize, buddy_size, buddy_bit, pmap_bit; + uint64_t threshold_bitsize, threshold_longsize = 0; + + + void *paged_mem = (void *)&_stage2_pagetable + 0x200000; + map_page(&_stage2_pagetable, &_stage2_pagetable, PAGE_SIZE_2M); + + for(zone_i = 0; zones[zone_i].length > 0; zone_i++) { + + if((zones[zone_i].type == MEM_AVAILABLE) && (zones[zone_i].ACPI & 1)) { + + //hopefully this should never happen... + //I should dig into the docs to check before removing this. + //We also could forget about MAX_ZONE_CNT if we did. + + if(zone_i >= MAX_ZONE_CNT) { + printf("Only %u zones can be used! Modify MAX_ZONE_CNT in paging.h to use all memory.\n", MAX_ZONE_CNT); + break; + } + + + if((zones[zone_i].base <= (void*)&_stage2_pagetable) && + (zones[zone_i].base + zones[zone_i].length >= (void *)&_stage2_pagetable)) { + pmap->zone_paddr = &_stage2_pagetable; + zone_len[pmap_i] = zones[zone_i].length - (pmap->zone_paddr - zones[zone_i].base); + } + else { + pmap->zone_paddr = zones[zone_i].base; + zone_len[pmap_i] = zones[zone_i].length; + } + + pmap->buddy[0] = (void *)pmap + sizeof(*pmap); + + for(budorder = 1; budorder < MAX_BUDDY_ORDER; budorder++) { + buddy_bitlen[pmap_i][budorder - 1] = GET_BUDDY_BITLEN(zone_len[pmap_i], budorder - 1); + pmap->buddy[budorder] = (uint64_t *)pmap->buddy[budorder - 1] + + LSIZE_FROM_BITLEN(buddy_bitlen[pmap_i][budorder - 1]); + } + + buddy_bitlen[pmap_i][MAX_BUDDY_ORDER - 1] = GET_BUDDY_BITLEN(zone_len[pmap_i], MAX_BUDDY_ORDER - 1); + pmap->next = (void *)pmap->buddy[MAX_BUDDY_ORDER - 1] + + (LSIZE_FROM_BITLEN(buddy_bitlen[pmap_i][MAX_BUDDY_ORDER - 1]) * 8); + + pmap = pmap->next; + pmap_i++; + + //allocates by an extra sizeof(struct phys_map), + //but were about to discard anyway + while((void *)pmap + sizeof(*pmap) >= paged_mem) { + map_page(paged_mem, paged_mem, PAGE_SIZE_2M); + paged_mem += 0x200000; + } + + } + } + pmap_size = (void*)(pmap) - (void*)&_stage2_pagetable; + if(pmap_size >= zone_len[0]) panic(); //TODO debugging + + pmap_i = 0; + for(pmap = (struct phys_map*)&_stage2_pagetable; pmap->next != 0; pmap = pmap->next) { + for(budorder = MAX_BUDDY_ORDER - 1; budorder >= 0; budorder--) { + pmap_bbitsize = ceil((float)pmap_size / ((uint64_t)0x1000 << budorder)); + pmap_blongsize = pmap_bbitsize / 64; + + if(budorder == MAX_BUDDY_ORDER - 1) { + buddy_size = (uint64_t *)pmap->next - pmap->buddy[budorder]; + buddy_end = (uint64_t *)pmap->next - 1; + + threshold_bitsize = ((pmap_blongsize * 64) + pmap_bbitsize) * 2; + } + else { + buddy_size = pmap->buddy[budorder + 1] - pmap->buddy[budorder]; + buddy_end = pmap->buddy[budorder + 1] - 1; + + threshold_longsize = threshold_bitsize / 64; + } + pmap_bit = pmap_bbitsize & 63; + buddy_bit = buddy_bitlen[pmap_i][budorder] & 63; + + + if((pmap_bbitsize >= BITLEN_FROM_LSIZE(buddy_size)) && (pmap == (void *)&_stage2_pagetable)) { + bzero(pmap->buddy[budorder], buddy_size * 8); + } + else { + if(budorder == MAX_BUDDY_ORDER - 1) { + if(pmap == (void*)&_stage2_pagetable) { + if(pmap_blongsize) bzero(pmap->buddy[budorder], (pmap_blongsize - 1) * 8); + if(pmap_bit) { + *(pmap->buddy[budorder] + pmap_blongsize) = ~(((uint64_t)1 << pmap_bit) - 1); + } + else { + *(pmap->buddy[budorder] + pmap_blongsize) = UINT64_MAX; + } + if(pmap_blongsize + 1 == buddy_size) { + *buddy_end &= ((uint64_t)1 << buddy_bit) - 1; + } + else { + memset(pmap->buddy[budorder] + pmap_blongsize + 1, UINT8_MAX, (buddy_size - 1) * 8); + if(buddy_bit) { + *buddy_end = ((uint64_t)1 << buddy_bit) - 1; + } + else { + *buddy_end = UINT64_MAX; + } + } + threshold_bitsize = ((pmap_blongsize * 64) + pmap_bbitsize) * 2; + } + else { + memset(pmap->buddy[budorder], UINT8_MAX, (buddy_size - 1) * 8); + if(buddy_bit) { + *buddy_end = ((uint64_t)1 << buddy_bit) - 1; + } + else { + *buddy_end = UINT64_MAX; + } + } + } + else if(pmap == (void *)&_stage2_pagetable) { + if(threshold_longsize) bzero(pmap->buddy[budorder], (threshold_longsize - 1) * 8); + + if(threshold_bitsize > pmap_bbitsize) + *(pmap->buddy[budorder] + threshold_longsize) = ((uint64_t)1 << ((threshold_bitsize - 1) & 63)); + + if(buddy_size - threshold_longsize) + bzero(pmap->buddy[budorder] + threshold_longsize + 1, buddy_size - threshold_longsize); + if(buddy_bit & 1) { + *buddy_end = ((uint64_t)1 << (buddy_bit - 1)); + } + threshold_bitsize = ((pmap_blongsize * 64) + pmap_bbitsize) * 2; + } + else { + bzero(pmap->buddy[budorder], buddy_size); + if(buddy_bit & 1) { + *buddy_end = ((uint64_t)1 << ((buddy_bit) - 1)); + } + } + } + } + pmap_i++; + } } @@ -97,7 +231,7 @@ bool map_page(void *virtual_addr, void *physical_addr, uint8_t size) { if(table->pml4e[pml4e_i].base_ptr != (uintptr_t)&table->pdpe[pdpe_i] >> 12) goto error; if(table->pdpe[pdpe_i].present) { if(size == PAGE_SIZE_1G) { - if(table->pdpe[pdpe_i].base_ptr == (uintptr_t)pa_ptr >> 30 & 0x1ff) + if(table->pdpe[pdpe_i].base_ptr == ((uintptr_t)pa_ptr >> 30 & 0x1ff)) return true; goto error; } @@ -105,7 +239,7 @@ bool map_page(void *virtual_addr, void *physical_addr, uint8_t size) { if(table->pde[pde_i].present) { if(size == PAGE_SIZE_2M) { - if(table->pde[pde_i].base_ptr == (uintptr_t)pa_ptr >> 21 & 0x1ff) + if(table->pde[pde_i].base_ptr == ((uintptr_t)pa_ptr >> 21 & 0x1ff)) return true; goto error; } diff --git a/src/kernel/panic.c b/src/kernel/panic.c new file mode 100644 index 0000000..851684a --- /dev/null +++ b/src/kernel/panic.c @@ -0,0 +1,54 @@ +#include +#include +#include + +void panic(int reason, int type) { // will fill with debugging info latter + + struct stack_frame *frame; + +#ifdef EASTEREGG_BLOATWARE + printf("Kernel PANIC!!!!!!!\n"); + printf( +" _.-^^---....,,-- \n" +" _-- --_ \n" +"< >)\n" +"| BOOM | <------- your computer\n" +" \\._ _./ \n" +" ```--. . , ; .--''' \n" +" | | | \n" +" .-=|| | |=-. \n" +" `-=#$%&%$#=-' \n" +" | ; :| \n" +" _____.,-#%&$@%#&#~,._____\n"); +#else + printf("Kernel Panic!\n"); +#endif + + printf("Reason:\n"); + + switch(reason) { + case KERNEL_PANIC_PMAPSIZE : + printf("\tThe physical map can't fit in the first memory zone.\n" + "\tNote: If you have this issue, please contact me.\n" + "\tIt's a fixable bug caused by an unlikely scenario.\n"); + break; + case KERNEL_PANIC_RSDP_UNFOUND: + printf("\tRSDP unfound!\n"); + break; + case KERNEL_PANIC_KERNEL_RETURNED: + printf("\tThe kernel (almost) reached its return!\n"); + break; + } + printf("\nStack trace:\n"); + + asm("mov %%rbp,%0" : "=r"(frame) ::); + + for(; frame->next != 0; frame = frame->next) { + printf("\t%x\n", frame->function_base); + } + + //It's not public yet, but it will be + printf("\nAfter ensuring your computer meets the requirements specified, if you think this is a bug, please open an issue on the git repo or email me at %s.\n", DEV_EMAIL); + for(;;); + +} diff --git a/src/link.ld b/src/link.ld index 3bd7273..f45ddec 100644 --- a/src/link.ld +++ b/src/link.ld @@ -9,6 +9,7 @@ printf.o page.o acpi.o kernel.o +panic.o ) _kernel_stack_loc = 0x200000 - 8; @@ -33,5 +34,5 @@ SECTIONS } } -_kernel_size = (SIZEOF(kernel) / 512) + (SIZEOF(bootloader) / 512) + 2; -_bootloader_stage1_size = (SIZEOF(bootloader) / 512) - 1; +_kernel_size = ((SIZEOF(kernel) / 512) + (SIZEOF(bootloader) / 512)); /* there's a bug here I think!*/ +_bootloader_stage1_size = (SIZEOF(bootloader) / 512); diff --git a/src/makefile b/src/makefile index 4e51ff4..2398509 100644 --- a/src/makefile +++ b/src/makefile @@ -8,16 +8,18 @@ EMU_RAM=4G XRES=1024 YRES=768 +CCFLAGS=-g -ffreestanding -Wall make: nasm -g -felf64 bootloader/bootloader.asm -o objects/bootloader.o - $(CC) $(INC) -g -ffreestanding -c kernel/kernel.c -o objects/kernel.o - $(CC) $(INC) -g -ffreestanding -c kernel/acpi.c -o objects/acpi.o - $(CC) $(INC) -g -ffreestanding -c kernel/drivers/serial.c -o objects/serial.o - $(CC) $(INC) -g -ffreestanding -c kernel/drivers/video.c -o objects/video.o - $(CC) $(INC) -g -ffreestanding -c kernel/printf.c -o objects/printf.o - $(CC) $(INC) -g -ffreestanding -c kernel/page.c -o objects/page.o - $(CC) $(INC) -g -ffreestanding -c kernel/libc.c -o objects/libc.o + $(CC) $(INC) $(CCFLAGS) -c kernel/kernel.c -o objects/kernel.o + $(CC) $(INC) $(CCFLAGS) -c kernel/panic.c -o objects/panic.o + $(CC) $(INC) $(CCFLAGS) -c kernel/acpi.c -o objects/acpi.o + $(CC) $(INC) $(CCFLAGS) -c kernel/drivers/serial.c -o objects/serial.o + $(CC) $(INC) $(CCFLAGS) -c kernel/drivers/video.c -o objects/video.o + $(CC) $(INC) $(CCFLAGS) -c kernel/printf.c -o objects/printf.o + $(CC) $(INC) $(CCFLAGS) -c kernel/page.c -o objects/page.o + $(CC) $(INC) $(CCFLAGS) -c kernel/libc.c -o objects/libc.o $(LD) -o indigo_os.elf --oformat=elf64-x86-64 -T link.ld $(OBJCPY) --only-keep-debug indigo_os.elf debug/debug_syms.o $(OBJCPY) -O binary --strip-all indigo_os.elf indigo_os @@ -27,9 +29,19 @@ endif ifneq ("$(wildcard $(./debug/serial.out))","") mkfifo debug/serial.out endif - rm -f indigo_os.elf +# rm -f indigo_os.elf +preproc_debug: + nasm -g -felf64 bootloader/bootloader.asm + $(CC) $(INC) $(CCFLAGS) -E -c kernel/kernel.c + $(CC) $(INC) $(CCFLAGS) -E -c kernel/acpi.c + $(CC) $(INC) $(CCFLAGS) -E -c kernel/drivers/serial.c + $(CC) $(INC) $(CCFLAGS) -E -c kernel/drivers/video.c + $(CC) $(INC) $(CCFLAGS) -E -c kernel/printf.c + $(CC) $(INC) $(CCFLAGS) -E -c kernel/page.c + $(CC) $(INC) $(CCFLAGS) -E -c kernel/libc.c + run: qemu-system-x86_64 -smp $(EMU_CORES) -m $(EMU_RAM) -nographic -no-reboot -drive format=raw,file=./indigo_os diff --git a/tools/page/page.py b/tools/page/page.py index 95d1ccc..0a0c359 100755 --- a/tools/page/page.py +++ b/tools/page/page.py @@ -24,6 +24,22 @@ def get_table_size(addr): return((pte_cnt + pde_cnt + pdpe_cnt + pml4_cnt) * 8) -ts = get_table_size(34359738368) -print(ts) +def get_palloc_table_size(tb, base, size): + tsize = 24 + for x in range(8): + bs = tsize + tsize += c(((size / (0x1000 * (1 << x))) / 64)) * 8 + print(tsize - bs) + print("buddy: {} - {} > {}".format( + hex(bs + tb), + hex((tsize + tb) - 1), + (size / (0x1000 * (1 << x))) / 64 + )) + return(tsize) + +# tablebase, base, size +free_chunks = [[0x200000, 0x100000, 3220041728], [0x22fce0, 0x100000000, 1073741824]] + +ts = get_palloc_table_size(free_chunks[0][0], free_chunks[0][1], free_chunks[0][2]) +print(hex(ts))