From e573e6f1db6e14f05927b4a68c570cee8665abc7 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Wed, 2 Mar 2022 13:07:13 +0800 Subject: [PATCH] :bug: bug fix --- kernel/common/printk.c | 44 +++++++++++++++++++++++++++++++++++++----- kernel/common/printk.h | 10 ++++++---- kernel/head.S | 14 +++++++++++++- kernel/main.c | 9 +++++---- kernel/mm/mm.c | 8 ++++---- kernel/mm/slab.c | 25 +++++++++++++++--------- run.sh | 4 ++-- 7 files changed, 85 insertions(+), 29 deletions(-) diff --git a/kernel/common/printk.c b/kernel/common/printk.c index 42964416..b5ed9e13 100644 --- a/kernel/common/printk.c +++ b/kernel/common/printk.c @@ -35,13 +35,42 @@ int printk_init(const int char_size_x, const int char_size_y) // @todo:将来需要将帧缓冲区物理地址填写到这个地址的页表项中 VBE_FB_phys_addr = (ul *)info.framebuffer_addr; - pos.FB_address = (unsigned int *)0x0000000003000000; - pos.FB_length = pos.width * pos.height; + pos.FB_address = (uint *)0x0000000003000000; + pos.FB_length = pos.width * pos.height*2; + + // ======== 临时的将物理地址填写到0x0000000003000000处 之后会在mm内将帧缓存区重新映射===== + + global_CR3 = get_CR3(); + ul fb_virt_addr = pos.FB_address; + ul fb_phys_addr = VBE_FB_phys_addr; + + // 计算帧缓冲区的线性地址对应的pml4页表项的地址 + ul *tmp = phys_2_virt((ul *)((ul)global_CR3 & (~0xfffUL)) + ((fb_virt_addr >> PAGE_GDT_SHIFT) & 0x1ff)); + + tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((fb_virt_addr >> PAGE_1G_SHIFT) & 0x1ff)); + + ul *tmp1; + // 初始化2M物理页 + for (ul i = 0; i < (PAGE_2M_SIZE<<3); i += PAGE_2M_SIZE) + { + // 计算当前2M物理页对应的pdt的页表项的物理地址 + tmp1 = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + (((fb_virt_addr + i) >> PAGE_2M_SHIFT) & 0x1ff)); + + // 页面写穿,禁止缓存 + set_pdt(tmp1, mk_pdt((ul)fb_phys_addr + i, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD)); + } + + flush_tlb(); pos.x = 0; pos.y = 0; + cls(); + kdebug("width=%d\theight=%d", pos.width, pos.height); + + while(1) + return 0; } @@ -571,7 +600,7 @@ static char *write_float_point_num(char *str, double num, int field_width, int p return str; } -static void putchar(unsigned int *fb, int Xsize, int x, int y, unsigned int FRcolor, unsigned int BKcolor, unsigned char font) +static void putchar(uint *fb, int Xsize, int x, int y, unsigned int FRcolor, unsigned int BKcolor, unsigned char font) { /** * @brief 在屏幕上指定位置打印字符 @@ -809,7 +838,12 @@ ul get_VBE_FB_length() * @brief 设置pos变量中的VBE帧缓存区的线性地址 * @param virt_addr VBE帧缓存区线性地址 */ -void set_pos_VBE_FB_addr(ul virt_addr) +void set_pos_VBE_FB_addr(uint *virt_addr) { - pos.FB_address = virt_addr; + pos.FB_address = (uint *)virt_addr; +} + +uint* get_pos_VBE_FB_addr() +{ + return pos.FB_address; } \ No newline at end of file diff --git a/kernel/common/printk.h b/kernel/common/printk.h index 53e41395..35c7e92e 100644 --- a/kernel/common/printk.h +++ b/kernel/common/printk.h @@ -45,7 +45,7 @@ struct screen_info int char_size_x, char_size_y; - unsigned int *FB_address; //帧缓冲区首地址 + uint *FB_address; //帧缓冲区首地址 unsigned long FB_length; // 帧缓冲区长度 }; @@ -103,7 +103,7 @@ static char *write_float_point_num(char *str, double num, int field_width, int p * @param BKcolor 背景颜色 * @param font 字符的bitmap */ -static void putchar(unsigned int *fb, int Xsize, int x, int y, unsigned int FRcolor, unsigned int BKcolor, unsigned char font); +static void putchar(uint *fb, int Xsize, int x, int y, unsigned int FRcolor, unsigned int BKcolor, unsigned char font); /** * @brief 格式化打印字符串 @@ -134,7 +134,7 @@ int cls(); /** * @brief 获取VBE帧缓存区的物理地址 - * + * */ ul get_VBE_FB_phys_addr(); @@ -148,4 +148,6 @@ ul get_VBE_FB_length(); * @brief 设置pos变量中的VBE帧缓存区的线性地址 * @param virt_addr VBE帧缓存区线性地址 */ -void set_pos_VBE_FB_addr(ul virt_addr); \ No newline at end of file +void set_pos_VBE_FB_addr(uint* virt_addr); + +uint* get_pos_VBE_FB_addr(); \ No newline at end of file diff --git a/kernel/head.S b/kernel/head.S index 201a2de8..1dff7b91 100644 --- a/kernel/head.S +++ b/kernel/head.S @@ -533,6 +533,10 @@ __PDE: .quad 0x2a00083 .quad 0x2c00083 .quad 0x2e00083 + .quad 0x3000083 + .quad 0x3200083 + .quad 0x3400083 + .quad 0x3600083 .quad 0xe0000083 /*虚拟地址0x 3000000 初始情况下,帧缓冲区映射到这里*/ @@ -543,7 +547,15 @@ __PDE: .quad 0xe0a00083 .quad 0xe0c00083 .quad 0xe0e00083 - .fill 480,8,0 + .quad 0xe1000083 + .quad 0xe1200083 + .quad 0xe1400083 + .quad 0xe1600083 + .quad 0xe1800083 + .quad 0xe1a00083 + .quad 0xe1c00083 + .quad 0xe1e00083 + .fill 468,8,0 // GDT表 .section .data diff --git a/kernel/main.c b/kernel/main.c index 151fdb3f..3ccb52c1 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -80,7 +80,7 @@ void test_mm() free_pages(page, 1); printk_color(ORANGE, BLACK, "7.memory_management_struct.bmp:%#018lx\tmemory_management_struct.bmp+1:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *(memory_management_struct.bmp + (page->addr_phys >> PAGE_2M_SHIFT >> 6)), *(memory_management_struct.bmp + 1 + (page->addr_phys >> PAGE_2M_SHIFT >> 6)), (memory_management_struct.zones_struct + ZONE_UNMAPPED_INDEX)->count_pages_using, (memory_management_struct.zones_struct + ZONE_UNMAPPED_INDEX)->count_pages_free); - + test_slab(); kinfo("Memory management module test completed!"); } @@ -133,9 +133,10 @@ void system_initialize() { // 初始化printk - printk_init(8, 16); + kinfo("Kernel Starting..."); + load_TR(10); // 加载TR寄存器 ul tss_item_addr = 0x7c00; @@ -157,9 +158,9 @@ void system_initialize() cpu_init(); // test_slab(); - //test_mm(); + // test_mm(); // 再初始化进程模块。顺序不能调转 - //process_init(); + // process_init(); } //操作系统内核从这里开始执行 diff --git a/kernel/mm/mm.c b/kernel/mm/mm.c index 8a97ea61..60ae1a54 100644 --- a/kernel/mm/mm.c +++ b/kernel/mm/mm.c @@ -492,7 +492,7 @@ void init_frame_buffer() { kinfo("Re-mapping VBE frame buffer..."); global_CR3 = get_CR3(); - ul fb_virt_addr = 0xffff800003000000; + ul fb_virt_addr = 0xffff800008000000; ul fb_phys_addr = get_VBE_FB_phys_addr(); // 计算帧缓冲区的线性地址对应的pml4页表项的地址 @@ -514,16 +514,16 @@ void init_frame_buffer() ul vbe_fb_length = get_VBE_FB_length(); ul *tmp1; // 初始化2M物理页 - for (ul i = 0; i < vbe_fb_length; i += PAGE_2M_SIZE) + for (ul i = 0; i < (PAGE_2M_SIZE<<3); i += PAGE_2M_SIZE) { // 计算当前2M物理页对应的pdt的页表项的物理地址 - tmp1 = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + (((fb_virt_addr + i) >> PAGE_2M_SHIFT) & 0x1ff)); + tmp1 = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + (((ul)(fb_virt_addr + i) >> PAGE_2M_SHIFT) & 0x1ff)); // 页面写穿,禁止缓存 set_pdt(tmp1, mk_pdt((ul)fb_phys_addr+i, PAGE_KERNEL_PAGE| PAGE_PWT| PAGE_PCD)); } - set_pos_VBE_FB_addr(fb_virt_addr); + set_pos_VBE_FB_addr((uint*)fb_virt_addr); flush_tlb(); kinfo("VBE frame buffer successfully Re-mapped!"); } \ No newline at end of file diff --git a/kernel/mm/slab.c b/kernel/mm/slab.c index 83847f06..9b282e17 100644 --- a/kernel/mm/slab.c +++ b/kernel/mm/slab.c @@ -332,6 +332,7 @@ ul slab_init() { // 将slab内存池对象的空间放置在mms的后面,并且预留4个unsigned long 的空间以防止内存越界 kmalloc_cache_group[i].cache_pool_entry = (struct slab_obj *)memory_management_struct.end_of_struct; + memory_management_struct.end_of_struct += sizeof(struct slab_obj) + (sizeof(ul) << 2); list_init(&kmalloc_cache_group[i].cache_pool_entry->list); @@ -362,14 +363,18 @@ ul slab_init() // 将上面初始化内存池组时,所占用的内存页进行初始化 ul tmp_page_mms_end = virt_2_phys(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT; + ul page_num = 0; for (int i = PAGE_2M_ALIGN(virt_2_phys(tmp_addr)) >> PAGE_2M_SHIFT; i <= tmp_page_mms_end; ++i) { page = memory_management_struct.pages_struct + i; - + page_num = page->addr_phys >> PAGE_2M_SHIFT; + *(memory_management_struct.bmp + (page_num >> 6)) |= (1UL << (page_num % 64)); + ++page->zone->count_pages_using; + --page->zone->count_pages_free; page_init(page, PAGE_KERNEL_INIT | PAGE_KERNEL | PAGE_PGT_MAPPED); } - printk_color(ORANGE, BLACK, "2.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free); + kdebug("2.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free); // 为slab内存池对象分配内存空间 ul *virt = NULL; @@ -380,14 +385,17 @@ ul slab_init() page = Virt_To_2M_Page(virt); + page_num = page->addr_phys >> PAGE_2M_SHIFT; + *(memory_management_struct.bmp + (page_num >> 6)) |= (1UL << (page_num % 64)); + ++page->zone->count_pages_using; + --page->zone->count_pages_free; page_init(page, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT); - kmalloc_cache_group[i].cache_pool_entry->page = page; kmalloc_cache_group[i].cache_pool_entry->vaddr = virt; } - printk_color(ORANGE, BLACK, "3.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free); + kdebug("3.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free); kinfo("SLAB initialized successfully!"); @@ -487,7 +495,7 @@ struct slab_obj *kmalloc_create_slab_obj(ul size) break; // size 错误 default: - kerror("kamlloc_create(): Wrong size%d\n", size); + kerror("kamlloc_create(): Wrong size%d", size); free_pages(page, 1); return NULL; break; @@ -520,7 +528,7 @@ void *kmalloc(unsigned long size, unsigned long flags) struct slab_obj *slab_obj_ptr = kmalloc_cache_group[index].cache_pool_entry; - kdebug("count_total_free=%d", kmalloc_cache_group[index].count_total_free); + //kdebug("count_total_free=%d", kmalloc_cache_group[index].count_total_free); // 内存池没有可用的内存对象,需要进行扩容 if (kmalloc_cache_group[index].count_total_free == 0) @@ -551,17 +559,16 @@ void *kmalloc(unsigned long size, unsigned long flags) } // 寻找一块可用的内存对象 int md; - kdebug("slab_obj_ptr->count_free=%d", slab_obj_ptr->count_free); for (int i = 0; i < slab_obj_ptr->bmp_count; ++i) { + // 当前bmp全部被使用 - if (*slab_obj_ptr->bmp + (i >> 6) == 0xffffffffffffffffUL) + if (*(slab_obj_ptr->bmp + (i >> 6)) == 0xffffffffffffffffUL) { i += 63; continue; } md = i % 64; - // 找到相应的内存对象 if ((*(slab_obj_ptr->bmp + (i >> 6)) & (1UL << md)) == 0) { diff --git a/run.sh b/run.sh index 5a82d3d6..a193ecd0 100644 --- a/run.sh +++ b/run.sh @@ -12,7 +12,7 @@ if [ ! "$1" == "--nobuild" ]; then make clean fi -IA32_USE_QEMU=0 +IA32_USE_QEMU=1 bochsrc="./bochsrc" ARCH="x86_64" @@ -92,7 +92,7 @@ if [ $flag_can_run -eq 1 ]; then if [ ${IA32_USE_QEMU} == 0 ]; then bochs -q -f ${bochsrc} -rc ./tools/bochsinit else - qemu-system-x86_64 -cdrom ${iso} -m 128M \ + qemu-system-x86_64 -cdrom ${iso} -m 512M \ -monitor telnet::2333,server,nowait -serial stdio -s fi else