From: Minep Date: Tue, 1 Mar 2022 23:34:38 +0000 (+0000) Subject: grow on demand heap X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/commitdiff_plain/f1036cb8c8899f38e97e45d345a0c28585d9a000?hp=9406e904ddad5db2ba2dd550e21bbb224899fd79 grow on demand heap add simple page fault handler for debugging correct the accidentally used sti instruction which is too early at this stage --- diff --git a/lunaix-os/arch/x86/boot.S b/lunaix-os/arch/x86/boot.S index ddcd891..7bf3005 100644 --- a/lunaix-os/arch/x86/boot.S +++ b/lunaix-os/arch/x86/boot.S @@ -42,6 +42,7 @@ */ start_: cld + # 确保屏蔽所有外中断,直到我们准备好PIC为止 cli movl $stack_top, %esp diff --git a/lunaix-os/includes/arch/x86/interrupts.h b/lunaix-os/includes/arch/x86/interrupts.h index 6265720..3fb86d6 100644 --- a/lunaix-os/includes/arch/x86/interrupts.h +++ b/lunaix-os/includes/arch/x86/interrupts.h @@ -40,6 +40,9 @@ _asm_isr0(); void _asm_isr13(); +void +_asm_isr14(); + void interrupt_handler(isr_param* param); diff --git a/lunaix-os/kernel/asm/x86/idt.c b/lunaix-os/kernel/asm/x86/idt.c index 19b63e0..296fa15 100644 --- a/lunaix-os/kernel/asm/x86/idt.c +++ b/lunaix-os/kernel/asm/x86/idt.c @@ -19,4 +19,5 @@ void _init_idt() { _set_idt_entry(FAULT_DIVISION_ERROR, 0x08, _asm_isr0, 0); _set_idt_entry(FAULT_GENERAL_PROTECTION, 0x08, _asm_isr13, 0); + _set_idt_entry(FAULT_PAGE_FAULT, 0x08, _asm_isr14, 0); } \ No newline at end of file diff --git a/lunaix-os/kernel/asm/x86/interrupt.S b/lunaix-os/kernel/asm/x86/interrupt.S index 5f3d333..10fa393 100644 --- a/lunaix-os/kernel/asm/x86/interrupt.S +++ b/lunaix-os/kernel/asm/x86/interrupt.S @@ -12,6 +12,7 @@ .section .text isr_template 0 isr_template 13, no_error_code=0 + isr_template 14, no_error_code=0 interrupt_wrapper: diff --git a/lunaix-os/kernel/asm/x86/interrupts.c b/lunaix-os/kernel/asm/x86/interrupts.c index 7ed3427..925c13d 100644 --- a/lunaix-os/kernel/asm/x86/interrupts.c +++ b/lunaix-os/kernel/asm/x86/interrupts.c @@ -3,14 +3,13 @@ #include void panic (const char* msg, isr_param* param) { - tty_set_theme(VGA_COLOR_BLACK, VGA_COLOR_LIGHT_RED); + tty_set_theme(VGA_COLOR_WHITE, VGA_COLOR_RED); tty_clear_line(10); tty_clear_line(11); tty_clear_line(12); tty_set_cpos(0, 11); - printf(" INT %u: [0x%x: 0x%x] %s", param->vector, param->cs, param->eip, msg); - __spin: - goto __spin; + printf(" INT %u: (%x) [0x%x: 0x%x] %s", param->vector, param->err_code, param->cs, param->eip, msg); + while(1); } void @@ -23,6 +22,9 @@ interrupt_handler(isr_param* param) { case FAULT_GENERAL_PROTECTION: panic("General Protection", param); break; // never reach + case FAULT_PAGE_FAULT: + panic("Page Fault", param); + break; // never reach default: panic("Unknown Interrupt", param); break; // never reach diff --git a/lunaix-os/kernel/asm/x86/prologue.S b/lunaix-os/kernel/asm/x86/prologue.S index ca72830..fe1b645 100644 --- a/lunaix-os/kernel/asm/x86/prologue.S +++ b/lunaix-os/kernel/asm/x86/prologue.S @@ -52,8 +52,7 @@ addl $6, %esp - sti - + movl $mb_info, (%esp) call _kernel_init /* diff --git a/lunaix-os/kernel/k_main.c b/lunaix-os/kernel/k_main.c index 3899336..3f56166 100644 --- a/lunaix-os/kernel/k_main.c +++ b/lunaix-os/kernel/k_main.c @@ -31,11 +31,14 @@ _kernel_main() arr[i] = (uint32_t*) lx_malloc((i + 1) * 2); } + void* big_ = lx_malloc(8192); + for (size_t i = 0; i < 10; i++) { lx_free(arr[i]); } lx_free(arr); + lx_free(big_); // assert(0); } \ No newline at end of file diff --git a/lunaix-os/kernel/mm/dmm.c b/lunaix-os/kernel/mm/dmm.c index 81426da..e15e432 100644 --- a/lunaix-os/kernel/mm/dmm.c +++ b/lunaix-os/kernel/mm/dmm.c @@ -2,7 +2,7 @@ * @file dmm.c * @author Lunaixsky * @brief Dynamic memory manager dedicated to kernel heap. It is not portable at - * this moment. + * this moment. Implicit free list implementation. * @version 0.1 * @date 2022-02-28 * @@ -18,8 +18,6 @@ #include #include -#include - #define M_ALLOCATED 0x1 #define M_PREV_FREE 0x2 @@ -53,6 +51,8 @@ coalesce(uint8_t* chunk_ptr); void* lx_grow_heap(size_t sz); +void place_chunk(uint8_t* ptr, size_t size); + int dmm_init() { @@ -99,9 +99,7 @@ lxbrk(size_t size) { // if next do require new pages to be allocated if (!vmm_alloc_pages(heap_top_pg + PG_SIZE, ROUNDUP(size, PG_SIZE), PG_PRESENT | PG_WRITE)) { - // TODO: OOM, panic here! Rather than spinning. - spin(); - // return NULL + return NULL; } } @@ -143,34 +141,51 @@ lx_malloc(size_t size) size_t chunk_size = CHUNK_S(header); if (chunk_size >= size && !CHUNK_A(header)) { // found! - *((uint32_t*)ptr) = PACK(size, CHUNK_PF(header) | M_ALLOCATED); - uint8_t* n_hdrptr = (uint8_t*)(ptr + size); - uint32_t diff = chunk_size - size; - if (!diff) { - // if the current free block is fully occupied - uint32_t n_hdr = LW(n_hdrptr); - // notify the next block about our avaliability - SW(n_hdrptr, n_hdr & ~0x2); - } else { - // if there is remaining free space left - uint32_t remainder_hdr = - PACK(diff, M_NOT_ALLOCATED | M_PREV_ALLOCATED); - SW(n_hdrptr, remainder_hdr); - SW(FPTR(n_hdrptr, diff), remainder_hdr); - - coalesce(n_hdrptr); - } + place_chunk(ptr, size); return BPTR(ptr); } ptr += chunk_size; } + // if heap is full (seems to be!), then allocate more space (if it's okay...) + if ((ptr = lx_grow_heap(size))) { + place_chunk(ptr, size); + return BPTR(ptr); + } + + // Well, we are officially OOM! return NULL; } +void place_chunk(uint8_t* ptr, size_t size) { + uint32_t header = *((uint32_t*)ptr); + size_t chunk_size = CHUNK_S(header); + *((uint32_t*)ptr) = PACK(size, CHUNK_PF(header) | M_ALLOCATED); + uint8_t* n_hdrptr = (uint8_t*)(ptr + size); + uint32_t diff = chunk_size - size; + if (!diff) { + // if the current free block is fully occupied + uint32_t n_hdr = LW(n_hdrptr); + // notify the next block about our avaliability + SW(n_hdrptr, n_hdr & ~0x2); + } else { + // if there is remaining free space left + uint32_t remainder_hdr = + PACK(diff, M_NOT_ALLOCATED | M_PREV_ALLOCATED); + SW(n_hdrptr, remainder_hdr); + SW(FPTR(n_hdrptr, diff), remainder_hdr); + + coalesce(n_hdrptr); + } +} + void lx_free(void* ptr) { + if (!ptr) { + return; + } + uint8_t* chunk_ptr = (uint8_t*)ptr - WSIZE; uint32_t hdr = LW(chunk_ptr); uint8_t* next_hdr = chunk_ptr + CHUNK_S(hdr);