mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-18 20:36:31 +00:00
🆕 重新初始化页表并重映射了VBE帧缓存区
This commit is contained in:
151
kernel/mm/mm.c
151
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!");
|
||||
}
|
Reference in New Issue
Block a user