Bläddra i källkod

feat: free kinit memory

greatbridf 2 år sedan
förälder
incheckning
cb96ca109a

+ 0 - 1
CMakeLists.txt

@@ -53,7 +53,6 @@ set(KERNEL_MAIN_SOURCES src/fs/fat.cpp
                         src/types/bitmap.c
                         src/types/elf.cpp
                         src/types/libstdcpp.cpp
-                        include/asm/boot.h
                         include/asm/port_io.h
                         include/asm/sys.h
                         include/fs/fat.hpp

+ 0 - 24
include/asm/boot.h

@@ -1,24 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-
-#define KERNEL_EARLY_STACK_ADDR ((phys_ptr_t)0x01000000)
-#define KERNEL_EARLY_STACK_SIZE ((size_t)0x100000)
-
-struct __attribute__((__packed__)) gdt_descriptor {
-    uint16_t size;
-    uint32_t address;
-};
-
-extern struct gdt_descriptor asm_gdt_descriptor;
-
-extern struct mem_size_info asm_mem_size_info;
-
-extern uint8_t asm_e820_mem_map[1024];
-extern uint32_t asm_e820_mem_map_count;
-extern uint32_t asm_e820_mem_map_entry_size;
-
-extern const uint32_t kernel_size;
-
-extern char* const bss_addr;
-extern const uint32_t bss_len;

+ 3 - 1
include/asm/sys.h

@@ -18,7 +18,9 @@ void asm_load_gdt(uint32_t limit, pptr_t addr);
 
 void asm_load_tr(uint16_t index);
 
-extern void* __real_kernel_end;
+extern const uint32_t kernel_size;
+extern char* const bss_addr;
+extern const uint32_t bss_len;
 
 #ifdef __cplusplus
 }

+ 8 - 5
include/kernel/mem.h

@@ -4,6 +4,7 @@
 #include <types/size.h>
 
 #define PAGE_SIZE (4096)
+#define IDENTICALLY_MAPPED_HEAP_SIZE ((size_t)0x400000)
 #define KERNEL_IDENTICALLY_MAPPED_AREA_LIMIT ((void*)0x30000000)
 
 #ifdef __cplusplus
@@ -89,10 +90,11 @@ typedef union pte_t {
 } pte_t;
 typedef pte_t (*pt_t)[1024];
 
-inline uint8_t e820_mem_map[1024];
-inline uint32_t e820_mem_map_count;
-inline uint32_t e820_mem_map_entry_size;
-inline struct mem_size_info mem_size_info;
+// in mem.cpp
+extern uint8_t e820_mem_map[1024];
+extern uint32_t e820_mem_map_count;
+extern uint32_t e820_mem_map_entry_size;
+extern struct mem_size_info mem_size_info;
 
 #define KERNEL_HEAP_START ((void*)0x30000000)
 #define KERNEL_HEAP_LIMIT ((void*)0x40000000)
@@ -134,7 +136,8 @@ typedef struct segment_descriptor_struct {
     uint64_t base_high : 8;
 } segment_descriptor;
 
-inline segment_descriptor gdt[6];
+// in mem.cpp
+extern segment_descriptor gdt[6];
 
 void create_segment_descriptor(
     segment_descriptor* sd,

+ 1 - 1
src/asm/a20.s

@@ -1,4 +1,4 @@
-.text
+.section .text.kinit
 
 .globl check_a20_on
 .type  check_a20_on @function

+ 14 - 12
src/asm/interrupt.s

@@ -182,18 +182,6 @@ irq15:
     popal
     iret
 
-.globl asm_load_idt
-.type  asm_load_idt @function
-asm_load_idt:
-    movl 4(%esp), %edx
-    lidt (%edx)
-    movl 8(%esp), %edx
-    cmpl $0, %edx
-    je asm_load_idt_skip
-    sti
-asm_load_idt_skip:
-    ret
-
 .globl syscall_stub
 .type  syscall_stub @function
 syscall_stub:
@@ -251,3 +239,17 @@ asm_ctx_switch:
 
 _ctx_switch_return:
     ret
+
+.section .text.kinit
+
+.globl asm_load_idt
+.type  asm_load_idt @function
+asm_load_idt:
+    movl 4(%esp), %edx
+    lidt (%edx)
+    movl 8(%esp), %edx
+    cmpl $0, %edx
+    je asm_load_idt_skip
+    sti
+asm_load_idt_skip:
+    ret

+ 1 - 0
src/asm/port_io.s

@@ -41,6 +41,7 @@ asm_sti:
     sti
     ret
 
+.section .text.kinit
 .globl asm_enable_sse
 .type  asm_enable_sse @function
 asm_enable_sse:

+ 8 - 6
src/asm/sys.s

@@ -9,6 +9,14 @@ asm_switch_pd:
     movl %eax, %cr3
     ret
 
+.global current_pd
+.type   current_pd @function
+current_pd:
+    movl %cr3, %eax
+    ret
+
+.section .text.kinit
+
 .global asm_enable_paging
 .type   asm_enable_paging @function
 asm_enable_paging:
@@ -24,12 +32,6 @@ asm_enable_paging:
 
     ret
 
-.global current_pd
-.type   current_pd @function
-current_pd:
-    movl %cr3, %eax
-    ret
-
 .global asm_load_gdt
 .type   asm_load_gdt @function
 asm_load_gdt:

+ 9 - 15
src/boot.s

@@ -197,11 +197,6 @@ loader_halt:
 asm_gdt_descriptor:
     .word (5 * 8) - 1 # size
     .long asm_gdt_table  # address
-
-.globl asm_gdt_descriptor
-.type asm_gdt_descriptor @object
-.size asm_gdt_descriptor, (.-asm_gdt_descriptor)
-
 asm_gdt_table:
     .8byte 0         # null descriptor
 
@@ -237,26 +232,25 @@ asm_gdt_table:
     .byte 0b11001111 # flag and limit 16:20
     .byte 0x00       # base 24:31
 
-asm_mem_size_info:
-    .word 0x12
-    .word 0x34
-
 .globl asm_mem_size_info
 .type  asm_mem_size_info @object
 .size  asm_mem_size_info, (.-asm_mem_size_info)
+asm_mem_size_info:
+    .word 0x12
+    .word 0x34
 
-asm_e820_mem_map:
-    .space 1024
 .globl asm_e820_mem_map
 .type  asm_e820_mem_map @object
 .size  asm_e820_mem_map, (.-asm_e820_mem_map)
+asm_e820_mem_map:
+    .space 1024
 
-asm_e820_mem_map_count:
-    .long 0
 .globl asm_e820_mem_map_count
 .type  asm_e820_mem_map_count @object
-
-asm_e820_mem_map_entry_size:
+asm_e820_mem_map_count:
     .long 0
+
 .globl asm_e820_mem_map_entry_size
 .type  asm_e820_mem_map_entry_size @object
+asm_e820_mem_map_entry_size:
+    .long 0

+ 4 - 0
src/kernel.ld

@@ -29,6 +29,8 @@ SECTIONS
 
         *(.rodata.kinit)
 
+        . = ALIGN(16);
+
         start_ctors = .;
         KEEP(*(.init_array));
         KEEP(*(SORT_BY_INIT_PRIORITY(.init_array*)));
@@ -74,6 +76,8 @@ SECTIONS
         *(.rodata)
         *(.rodata*)
 
+        . = ALIGN(16);
+
         bss_addr = .;
         LONG(ABSOLUTE(__bss_start));
         bss_len = .;

+ 1 - 0
src/kernel/hw/ata.cpp

@@ -200,6 +200,7 @@ static inline void mbr_part_probe(fs::inode* drive, uint16_t major, uint16_t min
 }
 
 // data: void (*func_to_call_next)(void)
+SECTION(".text.kinit")
 void hw::init_ata(void)
 {
     ata_pri = types::pnew<types::kernel_allocator>(ata_pri, ATA_PRIMARY_BUS_BASE);

+ 1 - 0
src/kernel/hw/serial.cpp

@@ -4,6 +4,7 @@
 #include <stdio.h>
 #include <types/status.h>
 
+SECTION(".text.kinit")
 int32_t init_serial_port(port_id_t port)
 {
     // taken from osdev.org

+ 1 - 0
src/kernel/hw/timer.c

@@ -3,6 +3,7 @@
 
 static time_t _current_ticks = 0;
 
+SECTION(".text.kinit")
 void init_pit(void)
 {
     // set interval

+ 2 - 0
src/kernel/interrupt.cpp

@@ -36,6 +36,7 @@ static inline void NORETURN die(regs_32& regs, ptr_t eip)
     freeze();
 }
 
+SECTION(".text.kinit")
 void init_idt()
 {
     asm_cli();
@@ -61,6 +62,7 @@ void init_idt()
     asm_load_idt(idt_descriptor, 0);
 }
 
+SECTION(".text.kinit")
 void init_pic(void)
 {
     asm_cli();

+ 12 - 3
src/kernel/mem.cpp

@@ -1,4 +1,3 @@
-#include <asm/boot.h>
 #include <asm/port_io.h>
 #include <asm/sys.h>
 #include <assert.h>
@@ -20,13 +19,19 @@
 #define EMPTY_PAGE_ADDR ((pptr_t)0x0000)
 #define EMPTY_PAGE_END ((pptr_t)0x1000)
 
-#define IDENTICALLY_MAPPED_HEAP_SIZE ((size_t)0x400000)
-
 // ---------------------
 
 static size_t mem_size;
 static char mem_bitmap[1024 * 1024 / 8];
 
+// global
+segment_descriptor gdt[6];
+
+uint8_t e820_mem_map[1024];
+uint32_t e820_mem_map_count;
+uint32_t e820_mem_map_entry_size;
+struct mem_size_info mem_size_info;
+
 class brk_memory_allocator {
 public:
     using byte = uint8_t;
@@ -348,6 +353,7 @@ void dealloc_pt(pt_t pt)
     free_page(pg);
 }
 
+SECTION(".text.kinit")
 static inline void init_mem_layout(void)
 {
     mem_size = 1024 * mem_size_info.n_1k_blks;
@@ -509,6 +515,7 @@ static inline void _init_map_page_identically(page_t page)
     pt->in.page = page;
 }
 
+SECTION(".text.kinit")
 static inline void init_paging_map_low_mem_identically(void)
 {
     for (pptr_t addr = 0x01000000; addr < 0x30000000; addr += 0x1000) {
@@ -519,6 +526,7 @@ static inline void init_paging_map_low_mem_identically(void)
     }
 }
 
+SECTION(".text.kinit")
 void init_mem(void)
 {
     init_mem_layout();
@@ -545,6 +553,7 @@ void init_mem(void)
         KERNEL_HEAP_START, vptrdiff(KERNEL_HEAP_LIMIT, KERNEL_HEAP_START));
 }
 
+SECTION(".text.kinit")
 void create_segment_descriptor(
     segment_descriptor* sd,
     uint32_t base,

+ 10 - 0
src/kernel/process.cpp

@@ -160,6 +160,15 @@ void kernel_threadd_main(void)
 
 void NORETURN _kernel_init(void)
 {
+    // free kinit memory
+    {
+        extern char __kinit_start[];
+        extern char __kinit_end[];
+        free_n_raw_pages(
+            to_page((pptr_t)__kinit_start),
+            (__kinit_end - __kinit_start) >> 12);
+    }
+
     // pid 2 is kernel thread daemon
     auto* proc = &procs->emplace(1)->value;
 
@@ -241,6 +250,7 @@ void k_new_thread(void (*func)(void*), void* data)
     kthreadd_new_thd_data = data;
 }
 
+SECTION(".text.kinit")
 void NORETURN init_scheduler(void)
 {
     procs = types::pnew<types::kernel_allocator>(procs);

+ 1 - 0
src/kernel/syscall.cpp

@@ -291,6 +291,7 @@ void _syscall_getcwd(interrupt_stack* data)
     SYSCALL_SET_RETURN_VAL_EAX(buf);
 }
 
+SECTION(".text.kinit")
 void init_syscall(void)
 {
     syscall_handlers[0] = _syscall_fork;

+ 1 - 0
src/kernel/vfs.cpp

@@ -589,6 +589,7 @@ static size_t console_write(fs::special_node*, const char* buf, size_t, size_t n
     return orig_n;
 }
 
+SECTION(".text.kinit")
 void init_vfs(void)
 {
     using namespace fs;

+ 20 - 68
src/kinit.cpp

@@ -1,4 +1,3 @@
-#include <asm/boot.h>
 #include <asm/port_io.h>
 #include <asm/sys.h>
 #include <assert.h>
@@ -19,22 +18,16 @@
 #include <types/status.h>
 #include <types/types.h>
 
-#define KERNEL_MAIN_BUF_SIZE (128)
-
-#define printkf(x...)                       \
-    snprintf(buf, KERNEL_MAIN_BUF_SIZE, x); \
-    console->print(buf)
-
 typedef void (*constructor)(void);
-extern constructor start_ctors;
-extern constructor end_ctors;
-void call_constructors_for_cpp(void)
-{
-    for (constructor* ctor = &start_ctors; ctor != &end_ctors; ++ctor) {
-        (*ctor)();
-    }
-}
+extern constructor const SECTION(".rodata.kinit") start_ctors;
+extern constructor const SECTION(".rodata.kinit") end_ctors;
+
+extern struct mem_size_info SECTION(".stage1") asm_mem_size_info;
+extern uint8_t SECTION(".stage1") asm_e820_mem_map[1024];
+extern uint32_t SECTION(".stage1") asm_e820_mem_map_count;
+extern uint32_t SECTION(".stage1") asm_e820_mem_map_entry_size;
 
+SECTION(".text.kinit")
 static inline void save_loader_data(void)
 {
     memcpy(e820_mem_map, asm_e820_mem_map, sizeof(e820_mem_map));
@@ -43,50 +36,8 @@ static inline void save_loader_data(void)
     memcpy(&mem_size_info, &asm_mem_size_info, sizeof(struct mem_size_info));
 }
 
-static inline void show_mem_info(char* buf)
-{
-    uint32_t mem_size = 0;
-    mem_size += 1024 * mem_size_info.n_1k_blks;
-    mem_size += 64 * 1024 * mem_size_info.n_64k_blks;
-
-    printkf(
-        "Memory size: %d bytes (%d MB), 16k blocks: %d, 64k blocks: %d\n",
-        mem_size,
-        mem_size / 1024 / 1024,
-        (int32_t)mem_size_info.n_1k_blks,
-        (int32_t)mem_size_info.n_64k_blks);
-
-    printkf(
-        "mem_map_entry_count: %d , mem_map_entry_size: %d \n",
-        e820_mem_map_count,
-        e820_mem_map_entry_size);
-
-    if (e820_mem_map_entry_size == 20) {
-        struct e820_mem_map_entry_20* entry = (struct e820_mem_map_entry_20*)e820_mem_map;
-        for (uint32_t i = 0; i < e820_mem_map_count; ++i, ++entry) {
-            printkf(
-                "[mem] entry %d: %llx ~ %llx, type: %d\n",
-                i,
-                entry->base,
-                entry->base + entry->len,
-                entry->type);
-        }
-    } else {
-        struct e820_mem_map_entry_24* entry = (struct e820_mem_map_entry_24*)e820_mem_map;
-        for (uint32_t i = 0; i < e820_mem_map_count; ++i, ++entry) {
-            printkf(
-                "[mem] entry %d: %lld ~ %lld, type: %d, acpi_attr: %d\n",
-                i,
-                entry->in.base,
-                entry->in.base + entry->in.len,
-                entry->in.type,
-                entry->acpi_extension_attr);
-        }
-    }
-    printkf("kernel size: %x\n", kernel_size);
-}
-
-void load_new_gdt(void)
+SECTION(".text.kinit")
+static inline void load_new_gdt(void)
 {
     create_segment_descriptor(gdt + 0, 0, 0, 0, 0);
     create_segment_descriptor(gdt + 1, 0, ~0, 0b1100, SD_TYPE_CODE_SYSTEM);
@@ -101,12 +52,14 @@ void load_new_gdt(void)
     asm_cli();
 }
 
-void init_bss_section(void)
+SECTION(".text.kinit")
+static inline void init_bss_section(void)
 {
     memset(bss_addr, 0x00, bss_len);
 }
 
-int init_console(const char* name)
+SECTION(".text.kinit")
+static inline int init_console(const char* name)
 {
     if (name[0] == 't' && name[1] == 't' && name[2] == 'y') {
         if (name[3] == 'S' || name[3] == 's') {
@@ -130,7 +83,7 @@ int init_console(const char* name)
 extern void init_vfs();
 extern "C" uint32_t check_a20_on(void);
 
-extern "C" void NORETURN kernel_main(void)
+extern "C" SECTION(".text.kinit") void NORETURN kernel_main(void)
 {
     int ret;
     ret = check_a20_on();
@@ -144,12 +97,13 @@ extern "C" void NORETURN kernel_main(void)
 
     load_new_gdt();
 
+    // call global ctors
     // NOTE:
-    // the initializer of c++ global objects MUST NOT contain
+    // the initializer of global objects MUST NOT contain
     // all kinds of memory allocations
-    call_constructors_for_cpp();
-
-    char buf[KERNEL_MAIN_BUF_SIZE] = { 0 };
+    for (const constructor* ctor = &start_ctors; ctor != &end_ctors; ++ctor) {
+        (*ctor)();
+    }
 
     ret = init_serial_port(PORT_SERIAL0);
     assert(ret == GB_OK);
@@ -162,8 +116,6 @@ extern "C" void NORETURN kernel_main(void)
     ret = init_console("ttyS0");
     assert(ret == GB_OK);
 
-    show_mem_info(buf);
-
     init_vfs();
 
     kmsg("switching execution to the scheduler...\n");