a bit refactoring on kernel_init
authorMinep <zelong56@gmail.com>
Sun, 27 Feb 2022 23:39:31 +0000 (23:39 +0000)
committerMinep <zelong56@gmail.com>
Sun, 27 Feb 2022 23:39:31 +0000 (23:39 +0000)
add assertions support for debugging
add ss and esp in isr_param to handling stack switch.

lunaix-os/includes/arch/x86/interrupts.h
lunaix-os/includes/lunaix/assert.h [new file with mode: 0644]
lunaix-os/includes/lunaix/tty/tty.h
lunaix-os/kernel/asm/x86/prologue.S
lunaix-os/kernel/assert.c [new file with mode: 0644]
lunaix-os/kernel/k_init.c [new file with mode: 0644]
lunaix-os/kernel/k_main.c
lunaix-os/kernel/tty/tty.c

index fb4eb79a96b004ea92abae1c3d8187b36248edb8..b608cd6217a2f22d028746ac42ecaf0c2f637148 100644 (file)
@@ -7,6 +7,8 @@ typedef struct {
     unsigned int eip;
     unsigned int cs;
     unsigned int eflags;
     unsigned int eip;
     unsigned int cs;
     unsigned int eflags;
+    unsigned int esp;
+    unsigned int ss;
 } __attribute__((packed)) isr_param;
 
 void
 } __attribute__((packed)) isr_param;
 
 void
@@ -15,5 +17,4 @@ _asm_isr0();
 void
 interrupt_handler(isr_param* param);
 
 void
 interrupt_handler(isr_param* param);
 
-
 #endif /* __LUNAIX_INTERRUPTS_H */
 #endif /* __LUNAIX_INTERRUPTS_H */
diff --git a/lunaix-os/includes/lunaix/assert.h b/lunaix-os/includes/lunaix/assert.h
new file mode 100644 (file)
index 0000000..0697b33
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __LUNAIX_ASSERT_H
+#define __LUNAIX_ASSERT_H
+
+#include <libc/stdio.h>
+#include <lunaix/tty/tty.h>
+
+#ifdef __LUNAIXOS_DEBUG__
+#define assert(cond)                                  \
+    if (!(cond)) {                                    \
+        __assert_fail(#cond, __FILE__, __LINE__);     \
+    }
+#else
+#define assert(cond) //nothing
+#endif
+
+
+void __assert_fail(const char* expr, const char* file, unsigned int line) __attribute__((noinline, noreturn));
+
+#endif /* __LUNAIX_ASSERT_H */
index 3d723ca169a08853636145ba7c1f5f79c582a2cb..5c03ca29a845a0d3e76986b4ca89679376f831ac 100644 (file)
@@ -40,5 +40,14 @@ tty_scroll_up();
 void
 tty_clear();
 
 void
 tty_clear();
 
+void 
+tty_clear_line(unsigned int y);
+
+void
+tty_set_cpos(unsigned int x, unsigned int y);
+
+void
+tty_get_cpos(unsigned int* x, unsigned int* y);
+
 
 #endif /* __LUNAIX_TTY_H */
 
 #endif /* __LUNAIX_TTY_H */
index 0716b4898b76078ba2888be16882ced6d443d117..ca72830b7a6fec17ef4f3ce3680ce4d908055032 100644 (file)
     _after_gdt:
 
         movl $mb_info, (%esp)
     _after_gdt:
 
         movl $mb_info, (%esp)
-        call _kernel_init
 
 
-        /* 
-            加载新的栈指针,位于0xffbfffff,但因为16字节对齐的需求,低四位清零。
-            为什么不是0xffffffff? 因为0xffc00000 - 0xffffffff 这4MiB的空间用于
-            对页表与页目录的循环映射。
-        */
-        mov $0xffbffff0, %esp
-
-        call _kernel_post_init
+        call _kernel_pre_init
 
         subl $6, %esp
 
 
         subl $6, %esp
 
 
         addl $6, %esp
 
 
         addl $6, %esp
 
+        sti
+
+        call _kernel_init
+
+        /* 
+            加载新的栈指针,位于0xffbfffff,但因为16字节对齐的需求,低四位清零。
+            为什么不是0xffffffff? 因为0xffc00000 - 0xffffffff 这4MiB的空间用于
+            对页表与页目录的循环映射。
+        */
+        mov $0xffbffff0, %esp
+
+        call _kernel_post_init
+
         /* 进入内核 */  
         call _kernel_main
 
         /* 进入内核 */  
         call _kernel_main
 
diff --git a/lunaix-os/kernel/assert.c b/lunaix-os/kernel/assert.c
new file mode 100644 (file)
index 0000000..10fb78b
--- /dev/null
@@ -0,0 +1,12 @@
+#include <lunaix/assert.h>
+
+void __assert_fail(const char* expr, const char* file, unsigned int line) {
+    tty_set_theme(VGA_COLOR_BLACK, VGA_COLOR_LIGHT_RED);
+    tty_clear_line(10);
+    tty_clear_line(11);
+    tty_clear_line(12);
+    tty_set_cpos(0, 11);
+    printf("  Assert %s failed (%s:%u)", expr, file, line);
+    __spin:
+        goto __spin;
+}
\ No newline at end of file
diff --git a/lunaix-os/kernel/k_init.c b/lunaix-os/kernel/k_init.c
new file mode 100644 (file)
index 0000000..642a421
--- /dev/null
@@ -0,0 +1,107 @@
+#include <lunaix/constants.h>
+#include <lunaix/tty/tty.h>
+
+#include <lunaix/mm/page.h>
+#include <lunaix/mm/pmm.h>
+#include <lunaix/mm/vmm.h>
+
+#include <arch/x86/boot/multiboot.h>
+
+#include <stdint.h>
+#include <stddef.h>
+
+
+extern uint8_t __kernel_start;
+extern uint8_t __kernel_end;
+extern uint8_t __init_hhk_end;
+
+void
+_kernel_pre_init(multiboot_info_t* mb_info) {
+    _init_idt();
+
+    pmm_init(MEM_1MB + (mb_info->mem_upper << 10));
+    vmm_init();
+
+    tty_init((void*)VGA_BUFFER_PADDR);
+    tty_set_theme(VGA_COLOR_GREEN, VGA_COLOR_BLACK);
+}
+
+void
+_kernel_init(multiboot_info_t* mb_info) {
+    printf("[KERNEL] === Initialization === \n");
+
+    printf("[MM] Mem: %d KiB, Extended Mem: %d KiB\n",
+           mb_info->mem_lower,
+           mb_info->mem_upper);
+
+    unsigned int map_size = mb_info->mmap_length / sizeof(multiboot_memory_map_t);
+    setup_memory(mb_info->mmap_addr, map_size);
+    setup_kernel_runtime();
+}
+
+void 
+_kernel_post_init() {
+    printf("[KERNEL] === Post Initialization === \n");
+    size_t hhk_init_pg_count = ((uintptr_t)(&__init_hhk_end)) >> PG_SIZE_BITS;
+    printf("[MM] Releaseing %d pages from 0x0.\n", hhk_init_pg_count);
+
+    // 清除 hhk_init 与前1MiB的映射
+    for (size_t i = 0; i < hhk_init_pg_count; i++) {
+        vmm_unmap_page((void*)(i << PG_SIZE_BITS));
+    }
+}
+
+// 按照 Memory map 标识可用的物理页
+void
+setup_memory(multiboot_memory_map_t* map, size_t map_size) {
+    for (unsigned int i = 0; i < map_size; i++) {
+        multiboot_memory_map_t mmap = map[i];
+        printf("[MM] Base: 0x%x, len: %u KiB, type: %u\n",
+               map[i].addr_low,
+               map[i].len_low >> 10,
+               map[i].type);
+        if (mmap.type == MULTIBOOT_MEMORY_AVAILABLE) {
+            // 整数向上取整除法
+            uintptr_t pg = map[i].addr_low + 0x0fffU;
+            pmm_mark_chunk_free(pg >> PG_SIZE_BITS, map[i].len_low >> PG_SIZE_BITS);
+            printf("[MM] Freed %u pages start from 0x%x\n",
+                   map[i].len_low >> PG_SIZE_BITS,
+                   pg & ~0x0fffU);
+        }
+    }
+
+    // 将内核占据的页设为已占用
+    size_t pg_count = (uintptr_t)(&__kernel_end - &__kernel_start) >> PG_SIZE_BITS;
+    pmm_mark_chunk_occupied(V2P(&__kernel_start) >> PG_SIZE_BITS, pg_count);
+    printf("[MM] Allocated %d pages for kernel.\n", pg_count);
+
+
+    size_t vga_buf_pgs = VGA_BUFFER_SIZE >> PG_SIZE_BITS;
+    
+    // 首先,标记VGA部分为已占用
+    pmm_mark_chunk_occupied(VGA_BUFFER_PADDR >> PG_SIZE_BITS, vga_buf_pgs);
+    
+    // 重映射VGA文本缓冲区(以后会变成显存,i.e., framebuffer)
+    for (size_t i = 0; i < vga_buf_pgs; i++)
+    {
+        vmm_map_page(
+            (void*)(VGA_BUFFER_VADDR + (i << PG_SIZE_BITS)), 
+            (void*)(VGA_BUFFER_PADDR + (i << PG_SIZE_BITS)), 
+            PG_PREM_RW, PG_PREM_RW
+        );
+    }
+    
+    // 更新VGA缓冲区位置至虚拟地址
+    tty_set_buffer((void*)VGA_BUFFER_VADDR);
+
+    printf("[MM] Mapped VGA to %p.\n", VGA_BUFFER_VADDR);
+}
+
+void
+setup_kernel_runtime() {
+    // 为内核创建一个专属栈空间。
+    for (size_t i = 0; i < (K_STACK_SIZE >> PG_SIZE_BITS); i++) {
+        vmm_alloc_page((void*)(K_STACK_START + (i << PG_SIZE_BITS)), PG_PREM_RW, PG_PREM_RW);
+    }
+    printf("[MM] Allocated %d pages for stack start at %p\n", K_STACK_SIZE>>PG_SIZE_BITS, K_STACK_START);
+}
\ No newline at end of file
index 731ba9b14e8266b2b5132b077638e739b70289a3..b1fe4886184c7aa98c1b442cb924fc7751754920 100644 (file)
@@ -1,120 +1,9 @@
 #include <stdint.h>
 #include <stdint.h>
-
-#include <lunaix/constants.h>
-#include <lunaix/tty/tty.h>
-
-#include <lunaix/mm/page.h>
-#include <lunaix/mm/pmm.h>
 #include <lunaix/mm/vmm.h>
 #include <lunaix/mm/vmm.h>
-
 #include <hal/cpu.h>
 #include <hal/cpu.h>
-
-#include <arch/x86/boot/multiboot.h>
-#include <arch/x86/gdt.h>
-#include <arch/x86/idt.h>
-
 #include <libc/stdio.h>
 
 extern uint8_t __kernel_start;
 #include <libc/stdio.h>
 
 extern uint8_t __kernel_start;
-extern uint8_t __kernel_end;
-extern uint8_t __init_hhk_end;
-
-void
-_kernel_init(multiboot_info_t* mb_info)
-{
-    _init_idt();
-
-    multiboot_memory_map_t* map = (multiboot_memory_map_t*)mb_info->mmap_addr;
-
-    // TODO: 内核初始化
-    //   (v) 根据memory map初始化内存管理器
-    //   (v) 分配新的栈空间
-    //       调整映射:
-    //   ( )    + 映射 memory map (APCI,APIC,IO映射) (以后)
-    //   (v)    + 释放 hhk_init 所占据的空间
-
-#pragma region INIT_MM
-    // 初始化物理内存管理器
-    pmm_init(MEM_1MB + (mb_info->mem_upper << 10));
-    vmm_init();
-#pragma endregion
-
-    // 初始化VGA
-    tty_init((void*)VGA_BUFFER_PADDR);
-    tty_set_theme(VGA_COLOR_GREEN, VGA_COLOR_BLACK);
-
-    printf("[KERNEL] === Initialization === \n");
-    unsigned int map_size =
-      mb_info->mmap_length / sizeof(multiboot_memory_map_t);
-    printf("[MM] Mem: %d KiB, Extended Mem: %d KiB\n",
-           mb_info->mem_lower,
-           mb_info->mem_upper);
-
-#pragma region MMAP_SCAN_RESERVING_KERNEL_PGS
-    // 按照 Memory map 标识可用的物理页
-    for (unsigned int i = 0; i < map_size; i++) {
-        multiboot_memory_map_t mmap = map[i];
-        printf("[MM] Base: 0x%x, len: %u KiB, type: %u\n",
-               map[i].addr_low,
-               map[i].len_low >> 10,
-               map[i].type);
-        if (mmap.type == MULTIBOOT_MEMORY_AVAILABLE) {
-            // 整数向上取整除法
-            uintptr_t pg = map[i].addr_low + 0x0fffU;
-            pmm_mark_chunk_free(pg >> 12, map[i].len_low >> 12);
-            printf("[MM] Freed %u pages start from 0x%x\n",
-                   map[i].len_low >> 12,
-                   pg & ~0x0fffU);
-        }
-    }
-
-    // 将内核占据的页设为已占用
-    size_t pg_count = (uintptr_t)(&__kernel_end - &__kernel_start) >> 12;
-    pmm_mark_chunk_occupied(V2P(&__kernel_start) >> 12, pg_count);
-    printf("[MM] Allocated %d pages for kernel.\n", pg_count);
-#pragma endregion
-    
-    size_t vga_buf_pgs = VGA_BUFFER_SIZE >> 12;
-    
-    // 首先,标记VGA部分为已占用
-    pmm_mark_chunk_occupied(VGA_BUFFER_PADDR >> 12, vga_buf_pgs);
-    
-    // 重映射VGA文本缓冲区(以后会变成显存,i.e., framebuffer)
-    for (size_t i = 0; i < vga_buf_pgs; i++)
-    {
-        vmm_map_page(
-            (void*)(VGA_BUFFER_VADDR + (i << 12)), 
-            (void*)(VGA_BUFFER_PADDR + (i << 12)), 
-            PG_PREM_RW, PG_PREM_RW
-        );
-    }
-    
-    // 更新VGA缓冲区位置至虚拟地址
-    tty_set_buffer((void*)VGA_BUFFER_VADDR);
-
-    printf("[MM] Mapped VGA to %p.\n", VGA_BUFFER_VADDR);
-
-    // 为内核创建一个专属栈空间。
-    for (size_t i = 0; i < (K_STACK_SIZE >> 12); i++) {
-        vmm_alloc_page((void*)(K_STACK_START + (i << 12)), PG_PREM_RW, PG_PREM_RW);
-    }
-    printf("[MM] Allocated %d pages for stack start at %p\n", K_STACK_SIZE>>12, K_STACK_START);
-
-    printf("[KERNEL] === Initialization Done === \n\n");
-}
-
-void
-_kernel_post_init() {
-    printf("[KERNEL] === Post Initialization === \n");
-    size_t hhk_init_pg_count = ((uintptr_t)(&__init_hhk_end)) >> 12;
-    printf("[MM] Releaseing %d pages from 0x0.\n", hhk_init_pg_count);
-
-    // 清除 hhk_init 与前1MiB的映射
-    for (size_t i = 0; i < hhk_init_pg_count; i++) {
-        vmm_unmap_page((void*)(i << 12));
-    }
-    printf("[KERNEL] === Post Initialization Done === \n\n");
-}
 
 void
 _kernel_main()
 
 void
 _kernel_main()
@@ -129,5 +18,6 @@ _kernel_main()
 
     void* k_start = vmm_v2p(&__kernel_start);
     printf("The kernel's base address mapping: %p->%p\n", &__kernel_start, k_start);
 
     void* k_start = vmm_v2p(&__kernel_start);
     printf("The kernel's base address mapping: %p->%p\n", &__kernel_start, k_start);
-    // __asm__("int $0\n");
+
+    // assert(0);
 }
\ No newline at end of file
 }
\ No newline at end of file
index 325595edbef5db11f0780fc87a19c46df937cacc..1ad0dd47e0390aad672ecd180d09cf1239bde5a3 100644 (file)
@@ -84,4 +84,24 @@ tty_clear()
     }
     tty_x = 0;
     tty_y = 0;
     }
     tty_x = 0;
     tty_y = 0;
+}
+
+void
+tty_clear_line(unsigned int y) {
+    for (size_t i = 0; i < TTY_WIDTH; i++)
+    {
+        *(tty_vga_buffer + i + y * TTY_WIDTH) = tty_theme_color;
+    }
+}
+
+void
+tty_set_cpos(unsigned int x, unsigned int y) {
+    tty_x = x % TTY_WIDTH;
+    tty_y = y % TTY_HEIGHT;
+}
+
+void
+tty_get_cpos(unsigned int* x, unsigned int* y) {
+    *x = tty_x;
+    *y = tty_y;
 }
\ No newline at end of file
 }
\ No newline at end of file