From: acevest Date: Thu, 4 Nov 2021 15:00:50 +0000 (+0800) Subject: 加快bootmem初始化 X-Git-Url: http://zhaoyanbai.com/repos/CHANGES?a=commitdiff_plain;h=64949203e935275b181ae9814f710192b5479ba2;p=kernel.git 加快bootmem初始化 --- diff --git a/boot/boot.c b/boot/boot.c index 35b9fc4..f8feddc 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -60,3 +60,14 @@ void check_kernel(unsigned long addr, unsigned long magic) { init_boot_params(mbi); } + +extern void *kernel_begin; +extern void *kernel_end; +extern void *bootmem_bitmap_begin; +void init_system_info() { + system.kernel_begin = &kernel_begin; + system.kernel_end = &kernel_end; + system.bootmem_bitmap_begin = &bootmem_bitmap_begin; + + printk("kernel [%x, %x] bootmem bitmap: %x\n", system.kernel_begin, system.kernel_end, system.bootmem_bitmap_begin); +} diff --git a/boot/multiboot.S b/boot/multiboot.S index 2209b1e..e41297b 100644 --- a/boot/multiboot.S +++ b/boot/multiboot.S @@ -20,6 +20,7 @@ .global kernel_entry .global main .extern check_kernel +.extern init_system_info .extern setup_kernel .extern init_pgd .extern init_pgt @@ -112,10 +113,12 @@ main: ljmp $0x08,$Label Label: - - call check_kernel - addl $8,%esp movl $root_task + TASK_SIZE, %esp + + call check_kernel + + call init_system_info + call setup_kernel movl $root_task_entry, %eax diff --git a/include/bits.h b/include/bits.h index 50f37fd..c938993 100644 --- a/include/bits.h +++ b/include/bits.h @@ -30,7 +30,7 @@ static inline void btc(unsigned int *v, unsigned int b) { asm("btc %1,%0" : "=m"(*v) : "Ir"(b)); } -static inline int test_and_set_bit(long nr, volatile unsigned long *addr) { +static inline int test_and_set_bit(unsigned int nr, volatile unsigned long *addr) { int oldbit; asm("bts %2,%1\n\t" @@ -40,7 +40,7 @@ static inline int test_and_set_bit(long nr, volatile unsigned long *addr) { return oldbit; } -static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) { +static inline int test_and_clear_bit(unsigned int nr, volatile unsigned long *addr) { int oldbit; asm volatile( diff --git a/include/processor.h b/include/processor.h index a35db2c..eda56f2 100644 --- a/include/processor.h +++ b/include/processor.h @@ -102,10 +102,7 @@ extern Desc gdt[NGDT]; #define TRAP_GATE 0x0F // Keep 'IF' bit. #define TSS_DESC 0x09 -static inline void _init_desc(pDesc desc) { - if (0xc010a1c8 == (unsigned long)desc) asm("xchg %bx,%bx"); - memset((char *)desc, 0, sizeof(Desc)); -} +static inline void _init_desc(pDesc desc) { memset((char *)desc, 0, sizeof(Desc)); } static inline Desc _create_seg(u8 type, u8 DPL) { Desc d; diff --git a/include/stdio.h b/include/stdio.h index b6ba90d..042c269 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -24,9 +24,6 @@ static inline int printf(const char *fmt, ...) { char ptfbuf[512]; char *args = (char *)(((char *)&fmt) + 4); vsprintf(ptfbuf, fmt, args); - - // asm("xchg %bx,%bx;"); - return write(0, ptfbuf, strlen(ptfbuf)); } diff --git a/include/system.h b/include/system.h index 8c0de38..8ce574a 100644 --- a/include/system.h +++ b/include/system.h @@ -143,7 +143,9 @@ typedef struct system { u32 *pte_start; u32 *pte_end; - u32 kernel_end; + void *kernel_begin; + void *kernel_end; + void *bootmem_bitmap_begin; // +-------+-------+-------+-------+ // | drive | part1 | part2 | part3 | diff --git a/kernel/init.c b/kernel/init.c index 3a6dd76..e3dfa51 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -28,7 +28,7 @@ char idtr[6] __attribute__((__aligned__(4))); #define __ring3bss__ __attribute__((__section__(".ring3.bss"), __aligned__(PAGE_SIZE))) char __ring3data__ ring3_stack[PAGE_SIZE] = {0}; -char __ring3bss__ ring3_stack[PAGE_SIZE]; +char __ring3bss__ ring3_bss[PAGE_SIZE + 1234]; int ring3_sysctest(); void __ring3text__ __attribute__((__aligned__(PAGE_SIZE))) ring3_entry() { while (1) { @@ -61,7 +61,6 @@ void user_task_entry() { unsigned long *pt_bss_page = (unsigned long *)(alloc_one_page(0)); unsigned long *p = (unsigned long *)(pa2va(current->cr3)); - // asm volatile("xchg %%bx, %%bx;mov %%eax, %%ebx;xchg %%bx, %%bx;"::"a"(p)); printk("page dir : %x %x %x %x\n", p, pt_text_page, ring3_text_page); printk("pt bss page %x %x", pt_bss_page, ring3_bss_page); @@ -85,7 +84,6 @@ void user_task_entry() { // 现在要准备返回用户态 // eip --> edx // esp --> ecx - asm volatile("xchg %bx, %bx"); asm volatile("sysexit;" ::"d"(0x08000000), "c"(0x30000000 + PAGE_SIZE - 100)); } diff --git a/kernel/setup.c b/kernel/setup.c index fcddc9d..606192e 100644 --- a/kernel/setup.c +++ b/kernel/setup.c @@ -56,14 +56,12 @@ const char *version = "Kernel version " VERSION " @ " BUILDER "\n"; void setup_kernel() { - extern char kernel_begin, kernel_end; - vga_init(); - printk("kernel: %08x - %08x\n", &kernel_begin, &kernel_end); - init_mm(); + // printk("kernel: %08x - %08x\n", system.kernel_begin, system.kernel_end); + setup_gdt(); setup_idt(); setup_gate(); diff --git a/mm/bootmem.c b/mm/bootmem.c index 99c52e5..597a593 100644 --- a/mm/bootmem.c +++ b/mm/bootmem.c @@ -9,10 +9,9 @@ #include #include #include +#include #include -extern char kernel_begin, kernel_end; - static void e820_print_type(unsigned long type) { switch (type) { case E820_RAM: @@ -36,6 +35,32 @@ static void e820_print_type(unsigned long type) { } } +// op: 0 clear bit, 1 set bit +void fast_init_bootmem_bitmap(unsigned long bgn_pfn, unsigned long end_pfn, int op) { + int (*bit_func)(unsigned int, volatile unsigned long *); + + bit_func = op == 0 ? test_and_clear_bit : test_and_set_bit; + + u8 data = op == 0 ? 0x00 : 0xFF; + + // 先设置头部不是从单个字节开始的比特 + unsigned int i = 0; // 这个变更不能放到for循环里定义 + for (i = bgn_pfn; i < end_pfn && (i % 8 != 0); i++) { + bit_func(i, bootmem_data.bitmap); + } + + // 算出中间的整字节数 + unsigned int bytes = (end_pfn - i) / 8; + + // 直接清零 + memset((char *)(bootmem_data.bitmap) + (i / 8), data, bytes); + + // 最后设置尾部不是整字节的比特 + for (i += bytes * 8; i < end_pfn; i++) { + bit_func(i, bootmem_data.bitmap); + } +} + void e820_print_map() { unsigned int i = 0; @@ -108,22 +133,7 @@ void register_bootmem_pages() { #if 1 // 用一个相对快的方式 - // 先设置头部不是从单个字节开始的比特 - unsigned int j = 0; // 这个变更不能放到for循环里定义 - for (j = bgn_pfn; j < end_pfn && (j % 8 != 0); j++) { - test_and_clear_bit(j, bootmem_data.bitmap); - } - - // 算出中间的整字节数 - unsigned int bytes = (end_pfn - j) / 8; - - // 直接清零 - memset((char *)(bootmem_data.bitmap) + (j / 8), 0x00, bytes); - - // 最后设置尾部不是整字节的比特 - for (j += bytes * 8; j < end_pfn; j++) { - test_and_clear_bit(j, bootmem_data.bitmap); - } + fast_init_bootmem_bitmap(bgn_pfn, end_pfn, 0); #else for (unsigned int j = bgn_pfn; j < end_pfn; j++) { test_and_clear_bit(j, bootmem_data.bitmap); @@ -133,18 +143,18 @@ void register_bootmem_pages() { } void reserve_bootmem(unsigned long bgn_pfn, unsigned long end_pfn) { - // printk("reserve %d %d\n", bgn_pfn, end_pfn); - +#if 1 + // 用一个相对快的方式 + fast_init_bootmem_bitmap(bgn_pfn, end_pfn, 1); +#else int i = 0; for (i = bgn_pfn; i < end_pfn; ++i) { test_and_set_bit(i, bootmem_data.bitmap); } +#endif } -void reserve_kernel_pages() { - reserve_bootmem(PFN_DW(va2pa(&kernel_begin)), PFN_UP(va2pa(&kernel_end))); - // reserve_bootmem(0, PFN_UP(va2pa(&kernel_end))); -} +void reserve_kernel_pages() { reserve_bootmem(PFN_DW(va2pa(system.kernel_begin)), PFN_UP(va2pa(system.kernel_end))); } void reserve_bootmem_bitmap() { unsigned long bgn_pfn = PFN_DW(va2pa(bootmem_data.bitmap)); @@ -157,7 +167,7 @@ void reserve_bootmem_bitmap() { void init_bootmem_allocator() { int mapsize = (bootmem_data.max_pfn + 7) / 8; - bootmem_data.bitmap = &kernel_end; + bootmem_data.bitmap = system.bootmem_bitmap_begin; bootmem_data.mapsize = mapsize; memset(bootmem_data.bitmap, 0xFF, mapsize); diff --git a/scripts/link.ld b/scripts/link.ld index 1f9d6f0..df9ce80 100644 --- a/scripts/link.ld +++ b/scripts/link.ld @@ -53,30 +53,24 @@ SECTIONS .ring3.text : AT(phys_addr) ALIGN(0x1000) { phys_addr = . - kernel_virtual_addr_start; - *(.ring3.text); + *(.ring3.text); } .ring3.data : AT(phys_addr) ALIGN(0x1000) { phys_addr = . - kernel_virtual_addr_start; - *(.ring3.data); + *(.ring3.data); } .ring3.bss : AT(phys_addr) ALIGN(0x1000) { phys_addr = . - kernel_virtual_addr_start; - *(.ring3.bss); - } - - - .init.data : AT(phys_addr) ALIGN(0x1000) - { - initdata = .; - phys_addr = . - kernel_virtual_addr_start; - *(.init.data); + *(.ring3.bss); } end = .; _end = .; - kernel_end = ALIGN(0x1000); + kernel_end = .; + + bootmem_bitmap_begin = ALIGN(0x1000); }