From db8604c1e30edd4f2c77997b15b4285311c30085 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Tue, 1 Mar 2022 20:21:32 +0800 Subject: [PATCH] =?UTF-8?q?:new:=20=E9=87=8D=E6=96=B0=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E9=A1=B5=E8=A1=A8=E5=B9=B6=E9=87=8D=E6=98=A0=E5=B0=84?= =?UTF-8?q?=E4=BA=86VBE=E5=B8=A7=E7=BC=93=E5=AD=98=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/common/printk.c | 49 ++++++++++--- kernel/common/printk.h | 51 +++++++++----- kernel/head.S | 74 ++++++++++---------- kernel/main.c | 6 +- kernel/mm/mm.c | 151 ++++++++++++++++++++++++++++++++--------- kernel/mm/mm.h | 71 ++++++++++++++++++- kernel/mm/slab.c | 8 +-- kernel/mm/slab.h | 2 +- 8 files changed, 304 insertions(+), 108 deletions(-) diff --git a/kernel/common/printk.c b/kernel/common/printk.c index b436a6c9..42964416 100644 --- a/kernel/common/printk.c +++ b/kernel/common/printk.c @@ -8,6 +8,7 @@ //#include "linkage.h" struct screen_info pos; +ul VBE_FB_phys_addr; // 由bootloader传来的帧缓存区的物理地址 int calculate_max_charNum(int len, int size) { @@ -33,7 +34,8 @@ int printk_init(const int char_size_x, const int char_size_y) pos.max_y = calculate_max_charNum(pos.height, char_size_y); // @todo:将来需要将帧缓冲区物理地址填写到这个地址的页表项中 - pos.FB_address = (unsigned int*)0x3000000; + VBE_FB_phys_addr = (ul *)info.framebuffer_addr; + pos.FB_address = (unsigned int *)0x0000000003000000; pos.FB_length = pos.width * pos.height; pos.x = 0; @@ -81,9 +83,9 @@ void auto_newline() if (pos.y > pos.max_y) { pos.y = pos.max_y; - int lines_to_scroll=2; - scroll(true, lines_to_scroll*pos.char_size_y, false); - pos.y-=lines_to_scroll; + int lines_to_scroll = 2; + scroll(true, lines_to_scroll * pos.char_size_y, false); + pos.y -= lines_to_scroll; } } @@ -690,8 +692,8 @@ int do_scroll(bool direction, int pixels) unsigned int src = pixels * pos.width; unsigned int count = pos.FB_length - src; - memcpy(pos.FB_address, (pos.FB_address + src), sizeof(unsigned int)*(pos.FB_length - src)); - memset(pos.FB_address+(pos.FB_length-src), 0, sizeof(unsigned int)*(src)); + memcpy(pos.FB_address, (pos.FB_address + src), sizeof(unsigned int) * (pos.FB_length - src)); + memset(pos.FB_address + (pos.FB_length - src), 0, sizeof(unsigned int) * (src)); return 0; } else @@ -742,18 +744,17 @@ int scroll(bool direction, int pixels, bool animation) trace[js_trace] = (int)(accelerate * i + 0.5); current_pixels += trace[js_trace]; do_scroll(direction, trace[js_trace]); - + ++js_trace; } - // 强制使得位置位于1/2*pixels if (current_pixels < pixels / 2) { delta_x = pixels / 2 - current_pixels; do_scroll(direction, delta_x); } - + // 减速阶段,是加速阶段的重放 for (int i = js_trace - 1; i >= 0; --i) { @@ -763,7 +764,7 @@ int scroll(bool direction, int pixels, bool animation) if (current_pixels > pixels) kerror("During scrolling: scrolled pixels over bound!"); - + // 强制使得位置位于pixels if (current_pixels < pixels) { @@ -771,7 +772,7 @@ int scroll(bool direction, int pixels, bool animation) do_scroll(direction, delta_x); } } - + return 0; } @@ -785,4 +786,30 @@ int cls() pos.x = 0; pos.y = 0; return 0; +} + +/** + * @brief 获取VBE帧缓存区的物理地址 + * + */ +ul get_VBE_FB_phys_addr() +{ + return VBE_FB_phys_addr; +} + +/** + * @brief 获取VBE帧缓冲区长度 + */ +ul get_VBE_FB_length() +{ + return pos.FB_length; +} + +/** + * @brief 设置pos变量中的VBE帧缓存区的线性地址 + * @param virt_addr VBE帧缓存区线性地址 + */ +void set_pos_VBE_FB_addr(ul virt_addr) +{ + pos.FB_address = virt_addr; } \ No newline at end of file diff --git a/kernel/common/printk.h b/kernel/common/printk.h index 874ddc0e..53e41395 100644 --- a/kernel/common/printk.h +++ b/kernel/common/printk.h @@ -3,7 +3,6 @@ // #pragma once - #define PAD_ZERO 1 // 0填充 #define LEFT 2 // 靠左对齐 #define RIGHT 4 // 靠右对齐 @@ -47,31 +46,31 @@ struct screen_info int char_size_x, char_size_y; unsigned int *FB_address; //帧缓冲区首地址 - unsigned long FB_length; // 帧缓冲区长度 -}; + unsigned long FB_length; // 帧缓冲区长度 +}; extern unsigned char font_ascii[256][16]; //导出ascii字体的bitmap(8*16大小) ps:位于font.h中 -char buf[4096]; //vsprintf()的缓冲区 +char buf[4096]; // vsprintf()的缓冲区 /** * @brief 初始化printk的屏幕信息 - * + * * @param char_size_x 字符的列坐标 * @param char_size_y 字符的行坐标 */ int printk_init(const int char_size_x, const int char_size_y); /** * @brief Set the printk pos object - * + * * @param x 列坐标 * @param y 行坐标 */ int set_printk_pos(const int x, const int y); /** * @brief 将字符串按照fmt和args中的内容进行格式化,然后保存到buf中 - * + * * @param buf 结果缓冲区 * @param fmt 格式化字符串 * @param args 内容 @@ -81,22 +80,21 @@ static int vsprintf(char *buf, const char *fmt, va_list args); /** * @brief 将数字按照指定的要求转换成对应的字符串(2~36进制) - * + * * @param str 要返回的字符串 * @param num 要打印的数值 * @param base 基数 - * @param field_width 区域宽度 + * @param field_width 区域宽度 * @param precision 精度 * @param flags 标志位 */ -static char* write_num(char *str, ull num, int base, int field_width, int precision, int flags); - +static char *write_num(char *str, ull num, int base, int field_width, int precision, int flags); static char *write_float_point_num(char *str, double num, int field_width, int precision, int flags); /** * @brief 在屏幕上指定位置打印字符 - * + * * @param fb 帧缓存线性地址 * @param Xsize 行分辨率 * @param x 左上角列像素点位置 @@ -109,20 +107,19 @@ static void putchar(unsigned int *fb, int Xsize, int x, int y, unsigned int FRco /** * @brief 格式化打印字符串 - * + * * @param FRcolor 前景色 * @param BKcolor 背景色 * @param ... 格式化字符串 */ +#define printk(...) printk_color(WHITE, BLACK, __VA_ARGS__) -#define printk(...) printk_color( WHITE, BLACK, __VA_ARGS__ ) - -int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char*fmt, ...); +int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, ...); /** * @brief 滚动窗口(尚不支持向下滚动) - * + * * @param direction 方向,向上滑动为true,否则为false * @param pixels 要滑动的像素数量 * @param animation 是否包含滑动动画 @@ -131,6 +128,24 @@ int scroll(bool direction, int pixels, bool animation); /** * @brief 清屏 + * + */ +int cls(); + +/** + * @brief 获取VBE帧缓存区的物理地址 * */ -int cls(); \ No newline at end of file +ul get_VBE_FB_phys_addr(); + +/** + * @brief 获取VBE帧缓冲区长度 + + */ +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 diff --git a/kernel/head.S b/kernel/head.S index ad63659b..201a2de8 100644 --- a/kernel/head.S +++ b/kernel/head.S @@ -354,13 +354,13 @@ ENTRY(_start64) // 最高级 mov $__PML4E, %eax mov $__PDPTE, %ebx - or $0x7, %ebx + or $0x3, %ebx mov %ebx, 0(%eax) // 次级 mov $__PDPTE, %eax mov $__PDE, %ebx - or $0x7, %ebx + or $0x3, %ebx mov %ebx, 0(%eax) @@ -493,56 +493,56 @@ ENTRY(_stack_start) .org 0x1000 //设置页表位置为内核执行头程序的0x1000处 __PML4E: - .quad 0x103007 // 用户访问,可读写,已存在, 地址在31~12位 + .quad 0x103003 // 用户访问,可读写,已存在, 地址在31~12位 .fill 255,8,0 - .quad 0x103007 + .quad 0x103003 .fill 255,8,0 .org 0x2000 __PDPTE: - .quad 0x104007 // 用户访问,可读写,已存在 + .quad 0x104003 // 用户访问,可读写,已存在 .fill 511,8,0 .org 0x3000 __PDE: - .quad 0x000087 // 用户访问,可读写,已存在 - .quad 0x200087 - .quad 0x400087 - .quad 0x600087 - .quad 0x800087 - .quad 0xa00087 - .quad 0xc00087 - .quad 0xe00087 - .quad 0x1000087 - .quad 0x1200087 - .quad 0x1400087 - .quad 0x1600087 - .quad 0x1800087 - .quad 0x1a00087 - .quad 0x1c00087 - .quad 0x1e00087 - .quad 0x2000087 - .quad 0x2200087 - .quad 0x2400087 - .quad 0x2600087 - .quad 0x2800087 - .quad 0x2a00087 - .quad 0x2c00087 - .quad 0x2e00087 + .quad 0x000083 // 用户访问,可读写,已存在 + .quad 0x200083 + .quad 0x400083 + .quad 0x600083 + .quad 0x800083 + .quad 0xa00083 + .quad 0xc00083 + .quad 0xe00083 + .quad 0x1000083 + .quad 0x1200083 + .quad 0x1400083 + .quad 0x1600083 + .quad 0x1800083 + .quad 0x1a00083 + .quad 0x1c00083 + .quad 0x1e00083 + .quad 0x2000083 + .quad 0x2200083 + .quad 0x2400083 + .quad 0x2600083 + .quad 0x2800083 + .quad 0x2a00083 + .quad 0x2c00083 + .quad 0x2e00083 - .quad 0xe0000087 /*虚拟地址0x 3000000 帧缓冲区映射到这里*/ - .quad 0xe0200087 - .quad 0xe0400087 - .quad 0xe0600087 /*0x1000000*/ - .quad 0xe0800087 - .quad 0xe0a00087 - .quad 0xe0c00087 - .quad 0xe0e00087 + .quad 0xe0000083 /*虚拟地址0x 3000000 初始情况下,帧缓冲区映射到这里*/ + .quad 0xe0200083 + .quad 0xe0400083 + .quad 0xe0600083 /*0x1000000*/ + .quad 0xe0800083 + .quad 0xe0a00083 + .quad 0xe0c00083 + .quad 0xe0e00083 .fill 480,8,0 // GDT表 diff --git a/kernel/main.c b/kernel/main.c index 6ae95cfd..151fdb3f 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -17,7 +17,7 @@ unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址 struct memory_desc memory_management_struct = {{0}, 0}; // struct Global_Memory_Descriptor memory_management_struct = {{0}, 0}; - +void test_slab(); void show_welcome() { /** @@ -157,9 +157,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 ab59e0eb..8a97ea61 100644 --- a/kernel/mm/mm.c +++ b/kernel/mm/mm.c @@ -191,8 +191,6 @@ void mm_init() global_CR3 = get_CR3(); - flush_tlb(); - kdebug("global_CR3\t:%#018lx", global_CR3); kdebug("*global_CR3\t:%#018lx", *phys_2_virt(global_CR3) & (~0xff)); kdebug("**global_CR3\t:%#018lx", *phys_2_virt(*phys_2_virt(global_CR3) & (~0xff)) & (~0xff)); @@ -201,8 +199,18 @@ void mm_init() kinfo("Memory management unit initialize complete!"); + /* + kinfo("Cleaning page table remapping at 0x0000"); + for (int i = 0; i < 10; ++i) + *(phys_2_virt(global_CR3) + i) = 0UL; + kinfo("Successfully cleaned page table remapping!\n"); + */ + + flush_tlb(); // 初始化slab内存池 slab_init(); + init_frame_buffer(); + page_table_init(); } /** @@ -224,35 +232,6 @@ unsigned long page_init(struct Page *page, ul flags) ++page->zone->total_pages_link; } return 0; - /* - // 全新的页面 - if (!page->attr) - { - // 将bmp对应的标志位置位 - *(memory_management_struct.bmp + ((page->addr_phys >> PAGE_2M_SHIFT) >> 6)) |= 1UL << (page->addr_phys >> PAGE_2M_SHIFT) % 64; - page->attr = flags; - ++(page->ref_counts); - ++(page->zone->count_pages_using); - --(page->zone->count_pages_free); - ++(page->zone->total_pages_link); - } - // 不是全新的页面,而是含有引用属性/共享属性 - else if ((page->attr & PAGE_REFERENCED) || (page->attr & PAGE_K_SHARE_TO_U) || (flags & PAGE_REFERENCED) || (flags & PAGE_K_SHARE_TO_U)) - { - page->attr |= flags; - ++(page->ref_counts); - ++(page->zone->total_pages_link); - } - else - { - // 将bmp对应的标志位置位 - //*(memory_management_struct.bmp + ((page->addr_phys >> PAGE_2M_SHIFT) >> 6)) |= (1UL << ((page->addr_phys >> PAGE_2M_SHIFT) % 64)); - *(memory_management_struct.bmp + ((page->addr_phys >> PAGE_2M_SHIFT) >> 6)) |= 1UL << (page->addr_phys >> PAGE_2M_SHIFT) % 64; - - page->attr |= flags; - } - return 0; - */ } /** @@ -438,3 +417,113 @@ void free_pages(struct Page *page, int number) return; } + +/** + * @brief 重新初始化页表的函数 + * 将0~4GB的物理页映射到线性地址空间 + */ +void page_table_init() +{ + kinfo("Initializing page table..."); + global_CR3 = get_CR3(); + // 由于CR3寄存器的[11..0]位是PCID标志位,因此将低12位置0后,就是PML4页表的基地址 + ul *pml4_addr = (ul *)((ul)phys_2_virt((ul)global_CR3 & (~0xfffUL))); + kdebug("PML4 addr=%#018lx *pml4=%#018lx", pml4_addr, *pml4_addr); + + ul *pdpt_addr = phys_2_virt(*pml4_addr & (~0xfffUL)); + kdebug("pdpt addr=%#018lx *pdpt=%#018lx", pdpt_addr, *pdpt_addr); + + ul *pd_addr = phys_2_virt(*pdpt_addr & (~0xfffUL)); + kdebug("pd addr=%#018lx *pd=%#018lx", pd_addr, *pd_addr); + + ul *tmp_addr; + for (int i = 0; i < memory_management_struct.count_zones; ++i) + { + struct Zone *z = memory_management_struct.zones_struct + i; + struct Page *p = z->pages_group; + + if (i == ZONE_UNMAPPED_INDEX) + break; + + for (int j = 0; j < z->count_pages; ++j) + { + // 计算出PML4页表中的页表项的地址 + tmp_addr = (ul *)((ul)pml4_addr + ((((ul)phys_2_virt(p->addr_phys)) >> PAGE_GDT_SHIFT) & 0x1ff) * 8); + + // 说明该页还没有分配pdpt页表,使用kmalloc分配一个 + if (*tmp_addr = 0) + { + ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0); + set_pml4t(tmp_addr, mk_pml4t(virt_2_phys(virt_addr), PAGE_KERNEL_PGT)); + } + + // 计算出pdpt页表的页表项的地址 + tmp_addr = (ul *)((ul)(phys_2_virt(*tmp_addr & (~0xfffUL))) + ((((ul)phys_2_virt(p->addr_phys)) >> PAGE_1G_SHIFT) & 0x1ff) * 8); + + // 说明该页还没有分配pd页表,使用kmalloc分配一个 + if (*tmp_addr = 0) + { + ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0); + set_pdpt(tmp_addr, mk_pdpt(virt_2_phys(virt_addr), PAGE_KERNEL_DIR)); + } + + // 计算出pd页表的页表项的地址 + tmp_addr = (ul *)((ul)(phys_2_virt(*tmp_addr & (~0xfffUL))) + ((((ul)phys_2_virt(p->addr_phys)) >> PAGE_2M_SHIFT) & 0x1ff) * 8); + + // 填入pd页表的页表项,映射2MB物理页 + set_pdt(tmp_addr, mk_pdt(virt_2_phys(p->addr_phys), PAGE_KERNEL_PAGE)); + + // 测试 + if (j % 50 == 0) + kdebug("pd_addr=%#018lx, *pd_addr=%#018lx", tmp_addr, *tmp_addr); + } + } + + flush_tlb(); + + kinfo("Page table Initialized."); +} + +/** + * @brief VBE帧缓存区的地址重新映射 + * 将帧缓存区映射到地址0xffff800003000000处 + */ +void init_frame_buffer() +{ + kinfo("Re-mapping VBE frame buffer..."); + global_CR3 = get_CR3(); + ul fb_virt_addr = 0xffff800003000000; + ul fb_phys_addr = get_VBE_FB_phys_addr(); + + // 计算帧缓冲区的线性地址对应的pml4页表项的地址 + ul *tmp = phys_2_virt((ul *)((ul)global_CR3 & (~0xfffUL)) + ((fb_virt_addr >> PAGE_GDT_SHIFT) & 0x1ff)); + if (*tmp == 0) + { + ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0); + set_pml4t(tmp, mk_pml4t(virt_2_phys(virt_addr), PAGE_KERNEL_PGT)); + } + + tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((fb_virt_addr >> PAGE_1G_SHIFT) & 0x1ff)); + + if (*tmp == 0) + { + ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0); + set_pdpt(tmp, mk_pdpt(virt_2_phys(virt_addr), PAGE_KERNEL_DIR)); + } + + ul vbe_fb_length = get_VBE_FB_length(); + ul *tmp1; + // 初始化2M物理页 + for (ul i = 0; i < vbe_fb_length; 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)); + } + + set_pos_VBE_FB_addr(fb_virt_addr); + flush_tlb(); + kinfo("VBE frame buffer successfully Re-mapped!"); +} \ No newline at end of file diff --git a/kernel/mm/mm.h b/kernel/mm/mm.h index b9a9d4fd..a6267bf1 100644 --- a/kernel/mm/mm.h +++ b/kernel/mm/mm.h @@ -13,6 +13,7 @@ #define PAGE_4K_SHIFT 12 #define PAGE_2M_SHIFT 21 #define PAGE_1G_SHIFT 30 +#define PAGE_GDT_SHIFT 39 // 不同大小的页的容量 #define PAGE_4K_SIZE (1UL << PAGE_4K_SHIFT) @@ -58,6 +59,55 @@ // 共享的页 shared=1 single-use=0 #define PAGE_SHARED (1<<4) +// =========== 页表项权限 ======== + +// bit 63 Execution Disable: +#define PAGE_XD (1UL << 63) + +// bit 12 Page Attribute Table +#define PAGE_PAT (1UL << 12) + +// bit 8 Global Page:1,global;0,part +#define PAGE_GLOBAL (1UL << 8) + +// bit 7 Page Size:1,big page;0,small page; +#define PAGE_PS (1UL << 7) + +// bit 6 Dirty:1,dirty;0,clean; +#define PAGE_DIRTY (1UL << 6) + +// bit 5 Accessed:1,visited;0,unvisited; +#define PAGE_ACCESSED (1UL << 5) + +// bit 4 Page Level Cache Disable +#define PAGE_PCD (1UL << 4) + +// bit 3 Page Level Write Through +#define PAGE_PWT (1UL << 3) + +// bit 2 User Supervisor:1,user and supervisor;0,supervisor; +#define PAGE_U_S (1UL << 2) + +// bit 1 Read Write:1,read and write;0,read; +#define PAGE_R_W (1UL << 1) + +// bit 0 Present:1,present;0,no present; +#define PAGE_PRESENT (1UL << 0) + +//1,0 +#define PAGE_KERNEL_PGT (PAGE_R_W | PAGE_PRESENT) + +//1,0 +#define PAGE_KERNEL_DIR (PAGE_R_W | PAGE_PRESENT) + +//7,1,0 +#define PAGE_KERNEL_PAGE (PAGE_PS | PAGE_R_W | PAGE_PRESENT) + +//2,1,0 +#define PAGE_USER_DIR (PAGE_U_S | PAGE_R_W | PAGE_PRESENT) + +//7,2,1,0 +#define PAGE_USER_PAGE (PAGE_PS | PAGE_U_S | PAGE_R_W | PAGE_PRESENT) // ===== 错误码定义 ==== @@ -253,7 +303,12 @@ typedef struct unsigned long pml4t; } pml4t_t; #define mk_pml4t(addr, attr) ((unsigned long)(addr) | (unsigned long)(attr)) -#define set_pml4t(mpl4tptr, mpl4tval) (*(mpl4tptr) = (mpl4tval)) +/** + * @brief 设置pml4页表的页表项 + * @param pml4tptr pml4页表项的地址 + * @param pml4val pml4页表项的值 + */ +#define set_pml4t(pml4tptr, pml4tval) (*(pml4tptr) = (pml4tval)) typedef struct { @@ -274,4 +329,16 @@ typedef struct unsigned long pt; } pt_t; #define mk_pt(addr, attr) ((unsigned long)(addr) | (unsigned long)(attr)) -#define set_pt(ptptr, ptval) (*(ptptr) = (ptval)) \ No newline at end of file +#define set_pt(ptptr, ptval) (*(ptptr) = (ptval)) + +/** + * @brief 重新初始化页表的函数 + * 将0~4GB的物理页映射到线性地址空间 + */ +void page_table_init(); + +/** + * @brief VBE帧缓存区的地址重新映射 + * 将帧缓存区映射到地址0xffff800003000000处 + */ +void init_frame_buffer(); \ No newline at end of file diff --git a/kernel/mm/slab.c b/kernel/mm/slab.c index 56789ece..83847f06 100644 --- a/kernel/mm/slab.c +++ b/kernel/mm/slab.c @@ -188,7 +188,7 @@ void *slab_malloc(struct slab *slab_pool, ul arg) memset(tmp_slab_obj->bmp, 0, tmp_slab_obj->bmp_len); - list_add(&slab_pool->cache_pool_entry->list, tmp_slab_obj); + list_add(&slab_pool->cache_pool_entry->list, &tmp_slab_obj->list); slab_pool->count_total_free += tmp_slab_obj->count_free; @@ -382,10 +382,8 @@ ul slab_init() page_init(page, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT); - // 这里很神奇,给page赋值之后,list_next就会改变,我找不到原因,于是就直接重新初始化这个list好了 - // @todo: 找到这个bug的原因 + kmalloc_cache_group[i].cache_pool_entry->page = page; - list_init(&kmalloc_cache_group[i].cache_pool_entry->list); kmalloc_cache_group[i].cache_pool_entry->vaddr = virt; } @@ -468,7 +466,7 @@ struct slab_obj *kmalloc_create_slab_obj(ul size) case 262144: case 524288: case 1048576: // 1MB - slab_obj_ptr = (struct Slab *)kmalloc(sizeof(struct slab_obj), 0); + slab_obj_ptr = (struct slab_obj *)kmalloc(sizeof(struct slab_obj), 0); slab_obj_ptr->count_free = PAGE_2M_SIZE / size; slab_obj_ptr->count_using = 0; diff --git a/kernel/mm/slab.h b/kernel/mm/slab.h index 23e0cb18..4aa4431f 100644 --- a/kernel/mm/slab.h +++ b/kernel/mm/slab.h @@ -15,7 +15,7 @@ struct slab_obj { - struct List *list; + struct List list; // 当前slab对象所使用的内存页 struct Page *page;