Просмотр исходного кода

:new: 重新初始化页表并重映射了VBE帧缓存区

fslongjin 3 лет назад
Родитель
Сommit
db8604c1e3
8 измененных файлов с 306 добавлено и 110 удалено
  1. 38 11
      kernel/common/printk.c
  2. 33 18
      kernel/common/printk.h
  3. 39 39
      kernel/head.S
  4. 3 3
      kernel/main.c
  5. 120 31
      kernel/mm/mm.c
  6. 69 2
      kernel/mm/mm.h
  7. 3 5
      kernel/mm/slab.c
  8. 1 1
      kernel/mm/slab.h

+ 38 - 11
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;
 }

+ 33 - 18
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();
+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);

+ 39 - 39
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	0xe0000087		/*虚拟地址0x 3000000 帧缓冲区映射到这里*/ 
-	.quad	0xe0200087
-	.quad	0xe0400087
-	.quad	0xe0600087		/*0x1000000*/
-	.quad	0xe0800087
-	.quad	0xe0a00087
-	.quad	0xe0c00087
-	.quad	0xe0e00087
+	.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	0xe0000083		/*虚拟地址0x 3000000 初始情况下,帧缓冲区映射到这里*/ 
+	.quad	0xe0200083
+	.quad	0xe0400083
+	.quad	0xe0600083		/*0x1000000*/
+	.quad	0xe0800083
+	.quad	0xe0a00083
+	.quad	0xe0c00083
+	.quad	0xe0e00083
 	.fill	480,8,0
 
 // GDT表

+ 3 - 3
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();
 }
 
 //操作系统内核从这里开始执行

+ 120 - 31
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!");
+}

+ 69 - 2
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))
+#define set_pt(ptptr, ptval) (*(ptptr) = (ptval))
+
+/**
+ * @brief 重新初始化页表的函数
+ * 将0~4GB的物理页映射到线性地址空间
+ */
+void page_table_init();
+
+/**
+ * @brief VBE帧缓存区的地址重新映射
+ * 将帧缓存区映射到地址0xffff800003000000处
+ */
+void init_frame_buffer();

+ 3 - 5
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;

+ 1 - 1
kernel/mm/slab.h

@@ -15,7 +15,7 @@
 
 struct slab_obj
 {
-    struct List *list;
+    struct List list;
     // 当前slab对象所使用的内存页
     struct Page *page;