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

This commit is contained in:
fslongjin
2022-03-01 20:21:32 +08:00
parent 1faa84d942
commit db8604c1e3
8 changed files with 304 additions and 108 deletions

View File

@ -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!");
}