硬核C++实现64位操作系统 内核巨页(5)

Aug 24, 2020

目前MOS内核使用48位地址最后4GB内存作为内核空间。

也就是0xFFFFFFFF00000000 ~ 0xFFFFFFFFFFFFFFFF

为了操作方便,直接将内核内存使用1GB页表映射到物理内存0x0开始处

这样在内核的访问就不会出现pagefault了(虽然pagefault功能已经实现

但内核并不一定要完全独占这4GB内存,只要管理好区域,这一段连续内存可以与userland的任务共享。

实现

1GB巨页只有两个页表入口,pml4和pdpe

pepe对应的entry指向映射的物理内存起点,范围是1GB

所以只需要在boot.asm里面加上第一个GB的映射

mov eax, 0x0
or  eax, (PAGE_PRESENT | PAGE_WRITE | PAGE_1GB)
mov [pdpe + 0xfe0], eax

偏移地址用计算器算,可以参考前一节,这里就省略了

这里首先映射1GB,然后剩下3GB还是用C++写好了

 在basic_init初始化中 首先就把这剩下3GB的内存给映射了

void do_1gb_mapping()
{
    auto pdpe_base = ((Page_PDPE *)&pdpe);
    pdpe_base[0x1fd].P = 1;
    pdpe_base[0x1fd].R_W = 1;
    pdpe_base[0x1fd].SIZE = 1;
    pdpe_base[0x1fd].NEXT = (0x40000000) >> PAGE_4K_SHIFT;

    pdpe_base[0x1fe].P = 1;
    pdpe_base[0x1fe].R_W = 1;
    pdpe_base[0x1fe].SIZE = 1;
    pdpe_base[0x1fe].NEXT = (0x80000000) >> PAGE_4K_SHIFT;

    pdpe_base[0x1ff].P = 1;
    pdpe_base[0x1ff].R_W = 1;
    pdpe_base[0x1ff].SIZE = 1;
    pdpe_base[0x1ff].NEXT = (0xc0000000) >> PAGE_4K_SHIFT;

    flush_tlb();
}

最后的效果如下

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.