mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 11:16:47 +00:00
🐛 修复了需要映射的物理地址跨越页表时,产生内存越界的问题
This commit is contained in:
parent
5df5d79900
commit
8d8fd391fb
@ -68,7 +68,7 @@ grub==2.06
|
|||||||
|
|
||||||
- [x] VFS虚拟文件系统
|
- [x] VFS虚拟文件系统
|
||||||
|
|
||||||
- [ ] 解析ELF文件格式
|
- [x] 解析ELF文件格式
|
||||||
|
|
||||||
- [x] 浮点数支持
|
- [x] 浮点数支持
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ grub==2.06
|
|||||||
|
|
||||||
- [x] virtual file system
|
- [x] virtual file system
|
||||||
|
|
||||||
- [ ] Parsing ELF file format
|
- [x] Parsing ELF file format
|
||||||
|
|
||||||
- [x] Floating point support
|
- [x] Floating point support
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ int printk_init(const int char_size_x, const int char_size_y)
|
|||||||
|
|
||||||
// ======== 临时的将物理地址填写到0x0000000003000000处 之后会在mm内将帧缓存区重新映射=====
|
// ======== 临时的将物理地址填写到0x0000000003000000处 之后会在mm内将帧缓存区重新映射=====
|
||||||
|
|
||||||
global_CR3 = get_CR3();
|
ul global_CR3 = (ul)get_CR3();
|
||||||
ul fb_virt_addr = (ul)pos.FB_address;
|
ul fb_virt_addr = (ul)pos.FB_address;
|
||||||
ul fb_phys_addr = VBE_FB_phys_addr;
|
ul fb_phys_addr = VBE_FB_phys_addr;
|
||||||
|
|
||||||
|
270
kernel/mm/mm.c
270
kernel/mm/mm.c
@ -15,10 +15,10 @@ static ul root_page_table_phys_addr = 0; // 内核层根页表的物理地址
|
|||||||
*/
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
uint64_t num_PML4E;
|
int64_t num_PML4E;
|
||||||
uint64_t *num_PDPTE;
|
int64_t num_PDPTE;
|
||||||
uint64_t *num_PDE;
|
int64_t num_PDE;
|
||||||
uint64_t num_PTE;
|
int64_t num_PTE;
|
||||||
} mm_pgt_entry_num_t;
|
} mm_pgt_entry_num_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -230,7 +230,6 @@ void mm_init()
|
|||||||
--tmp_page->zone->count_pages_free;
|
--tmp_page->zone->count_pages_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
global_CR3 = get_CR3();
|
|
||||||
// root_page_table_phys_addr = global_CR3;
|
// root_page_table_phys_addr = global_CR3;
|
||||||
// kdebug("global_CR3\t:%#018lx", global_CR3);
|
// 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(global_CR3) & (~0xff));
|
||||||
@ -460,7 +459,7 @@ void free_pages(struct Page *page, int number)
|
|||||||
void page_table_init()
|
void page_table_init()
|
||||||
{
|
{
|
||||||
kinfo("Re-Initializing page table...");
|
kinfo("Re-Initializing page table...");
|
||||||
global_CR3 = get_CR3();
|
ul *global_CR3 = get_CR3();
|
||||||
/*
|
/*
|
||||||
// 由于CR3寄存器的[11..0]位是PCID标志位,因此将低12位置0后,就是PML4页表的基地址
|
// 由于CR3寄存器的[11..0]位是PCID标志位,因此将低12位置0后,就是PML4页表的基地址
|
||||||
ul *pml4_addr = (ul *)((ul)phys_2_virt((ul)global_CR3 & (~0xfffUL)));
|
ul *pml4_addr = (ul *)((ul)phys_2_virt((ul)global_CR3 & (~0xfffUL)));
|
||||||
@ -499,39 +498,11 @@ void page_table_init()
|
|||||||
void init_frame_buffer()
|
void init_frame_buffer()
|
||||||
{
|
{
|
||||||
kinfo("Re-mapping VBE frame buffer...");
|
kinfo("Re-mapping VBE frame buffer...");
|
||||||
global_CR3 = get_CR3();
|
uint64_t global_CR3 = (uint64_t)get_CR3();
|
||||||
ul fb_virt_addr = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + FRAME_BUFFER_MAPPING_OFFSET;
|
ul fb_virt_addr = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + FRAME_BUFFER_MAPPING_OFFSET;
|
||||||
ul fb_phys_addr = get_VBE_FB_phys_addr();
|
ul fb_phys_addr = get_VBE_FB_phys_addr();
|
||||||
|
// mm_map_phys_addr(fb_virt_addr, fb_phys_addr, get_VBE_FB_length(), PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
|
||||||
// 计算帧缓冲区的线性地址对应的pml4页表项的地址
|
mm_map_proc_page_table(global_CR3, true, fb_virt_addr, fb_phys_addr, get_VBE_FB_length() << 2, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false);
|
||||||
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);
|
|
||||||
memset(virt_addr, 0, PAGE_4K_SIZE);
|
|
||||||
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);
|
|
||||||
memset(virt_addr, 0, PAGE_4K_SIZE);
|
|
||||||
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 << 2); i += PAGE_2M_SIZE)
|
|
||||||
{
|
|
||||||
// 计算当前2M物理页对应的pdt的页表项的物理地址
|
|
||||||
tmp1 = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + (((ul)(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((uint *)fb_virt_addr);
|
set_pos_VBE_FB_addr((uint *)fb_virt_addr);
|
||||||
flush_tlb();
|
flush_tlb();
|
||||||
@ -547,78 +518,15 @@ void init_frame_buffer()
|
|||||||
*/
|
*/
|
||||||
void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flags)
|
void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flags)
|
||||||
{
|
{
|
||||||
global_CR3 = get_CR3();
|
uint64_t global_CR3 = (uint64_t)get_CR3();
|
||||||
|
|
||||||
// 计算线性地址对应的pml4页表项的地址
|
mm_map_proc_page_table(global_CR3, true, virt_addr_start, phys_addr_start, length, flags, false);
|
||||||
ul *tmp = phys_2_virt((ul *)((ul)global_CR3 & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff));
|
|
||||||
if (*tmp == 0)
|
|
||||||
{
|
|
||||||
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
|
|
||||||
memset(virt_addr, 0, PAGE_4K_SIZE);
|
|
||||||
set_pml4t(tmp, mk_pml4t(virt_2_phys(virt_addr), PAGE_KERNEL_PGT));
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff));
|
|
||||||
|
|
||||||
if (*tmp == 0)
|
|
||||||
{
|
|
||||||
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
|
|
||||||
memset(virt_addr, 0, PAGE_4K_SIZE);
|
|
||||||
set_pdpt(tmp, mk_pdpt(virt_2_phys(virt_addr), PAGE_KERNEL_DIR));
|
|
||||||
}
|
|
||||||
|
|
||||||
ul *tmp1;
|
|
||||||
// 初始化2M物理页
|
|
||||||
for (ul i = 0; i < (length); i += PAGE_2M_SIZE)
|
|
||||||
{
|
|
||||||
// 计算当前2M物理页对应的pdt的页表项的物理地址
|
|
||||||
tmp1 = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff));
|
|
||||||
|
|
||||||
// 页面写穿,禁止缓存
|
|
||||||
set_pdt(tmp1, mk_pdt((ul)phys_addr_start + i, flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_tlb();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul flags)
|
void mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul flags)
|
||||||
{
|
{
|
||||||
global_CR3 = get_CR3();
|
uint64_t global_CR3 = (uint64_t)get_CR3();
|
||||||
|
mm_map_proc_page_table(global_CR3, true, virt_addr_start, phys_addr_start, length, flags, true);
|
||||||
// 计算线性地址对应的pml4页表项的地址
|
|
||||||
ul *tmp = phys_2_virt((ul *)((ul)global_CR3 & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff));
|
|
||||||
if (*tmp == 0)
|
|
||||||
{
|
|
||||||
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
|
|
||||||
memset(virt_addr, 0, PAGE_4K_SIZE);
|
|
||||||
set_pml4t(tmp, mk_pml4t(virt_2_phys(virt_addr), PAGE_USER_PGT));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
kdebug("*tmp != 0!!! \t tmp = %#018lx\t *tmp = %#018lx", tmp, *tmp);
|
|
||||||
|
|
||||||
tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff));
|
|
||||||
|
|
||||||
if (*tmp == 0)
|
|
||||||
{
|
|
||||||
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
|
|
||||||
memset(virt_addr, 0, PAGE_4K_SIZE);
|
|
||||||
set_pdpt(tmp, mk_pdpt(virt_2_phys(virt_addr), PAGE_USER_DIR));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
kdebug("*tmp != 0!!! \t tmp = %#018lx\t *tmp = %#018lx", tmp, *tmp);
|
|
||||||
|
|
||||||
ul *tmp1;
|
|
||||||
// 初始化2M物理页
|
|
||||||
for (ul i = 0; i < (length); i += PAGE_2M_SIZE)
|
|
||||||
{
|
|
||||||
// 计算当前2M物理页对应的pdt的页表项的物理地址
|
|
||||||
tmp1 = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff));
|
|
||||||
|
|
||||||
// 页面写穿,禁止缓存
|
|
||||||
set_pdt(tmp1, mk_pdt((ul)phys_addr_start + i, flags | PAGE_USER_PAGE));
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_tlb();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -634,51 +542,73 @@ void mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul
|
|||||||
void mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul phys_addr_start, ul length, ul flags, bool user)
|
void mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul phys_addr_start, ul length, ul flags, bool user)
|
||||||
{
|
{
|
||||||
|
|
||||||
// kdebug("proc_page_table_addr=%#018lx", proc_page_table_addr);
|
|
||||||
// 计算线性地址对应的pml4页表项的地址
|
// 计算线性地址对应的pml4页表项的地址
|
||||||
mm_pgt_entry_num_t pgt_num;
|
mm_pgt_entry_num_t pgt_num;
|
||||||
mm_calculate_entry_num(length, &pgt_num);
|
mm_calculate_entry_num(length, &pgt_num);
|
||||||
kdebug("ent1=%d ent2=%d ent3=%d, ent4=%d", pgt_num.num_PML4E, pgt_num.num_PDPTE, pgt_num.num_PDE, pgt_num.num_PTE);
|
// kdebug("ent1=%d ent2=%d ent3=%d, ent4=%d", pgt_num.num_PML4E, pgt_num.num_PDPTE, pgt_num.num_PDE, pgt_num.num_PTE);
|
||||||
|
// 已映射的内存大小
|
||||||
|
uint64_t length_mapped = 0;
|
||||||
|
|
||||||
uint64_t pml4e_id = ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff);
|
uint64_t pml4e_id = ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff);
|
||||||
|
uint64_t *pml4_ptr;
|
||||||
|
if (is_phys)
|
||||||
|
pml4_ptr = phys_2_virt((ul *)((ul)proc_page_table_addr & (~0xfffUL)));
|
||||||
|
else
|
||||||
|
pml4_ptr = (ul *)((ul)proc_page_table_addr & (~0xfffUL));
|
||||||
|
|
||||||
// 循环填写顶层页表
|
// 循环填写顶层页表
|
||||||
for (int num_pml4e = 0; num_pml4e < pgt_num.num_PML4E && pml4e_id < 512; ++num_pml4e, ++pml4e_id)
|
for (; (pgt_num.num_PML4E > 0) && pml4e_id < 512; ++pml4e_id)
|
||||||
{
|
{
|
||||||
ul *tmp;
|
// 剩余需要处理的pml4E -1
|
||||||
if (is_phys)
|
--(pgt_num.num_PML4E);
|
||||||
tmp = phys_2_virt((ul *)((ul)proc_page_table_addr & (~0xfffUL)) + pml4e_id);
|
|
||||||
else
|
|
||||||
tmp = (ul *)((ul)proc_page_table_addr & (~0xfffUL) + pml4e_id);
|
|
||||||
|
|
||||||
if (*tmp == 0)
|
ul *pml4e_ptr = pml4_ptr + pml4e_id;
|
||||||
|
|
||||||
|
// 创建新的二级页表
|
||||||
|
if (*pml4e_ptr == 0)
|
||||||
{
|
{
|
||||||
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
|
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
|
||||||
memset(virt_addr, 0, PAGE_4K_SIZE);
|
memset(virt_addr, 0, PAGE_4K_SIZE);
|
||||||
set_pml4t(tmp, mk_pml4t(virt_2_phys(virt_addr), (user ? PAGE_USER_PGT : PAGE_KERNEL_PGT)));
|
set_pml4t(pml4e_ptr, mk_pml4t(virt_2_phys(virt_addr), (user ? PAGE_USER_PGT : PAGE_KERNEL_PGT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff));
|
uint64_t pdpte_id = (((virt_addr_start + length_mapped) >> PAGE_1G_SHIFT) & 0x1ff);
|
||||||
|
uint64_t *pdpt_ptr = (uint64_t *)phys_2_virt(*pml4e_ptr & (~0xfffUL));
|
||||||
|
// kdebug("pdpt_ptr=%#018lx", pdpt_ptr);
|
||||||
|
|
||||||
if (*tmp == 0)
|
// 循环填写二级页表
|
||||||
|
for (; (pgt_num.num_PDPTE > 0) && pdpte_id < 512; ++pdpte_id)
|
||||||
{
|
{
|
||||||
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
|
--pgt_num.num_PDPTE;
|
||||||
memset(virt_addr, 0, PAGE_4K_SIZE);
|
uint64_t *pdpte_ptr = (pdpt_ptr + pdpte_id);
|
||||||
set_pdpt(tmp, mk_pdpt(virt_2_phys(virt_addr), (user ? PAGE_USER_DIR : PAGE_KERNEL_DIR)));
|
// kdebug("pgt_num.num_PDPTE=%ld pdpte_ptr=%#018lx", pgt_num.num_PDPTE, pdpte_ptr);
|
||||||
}
|
|
||||||
|
|
||||||
ul *tmp1;
|
// 创建新的三级页表
|
||||||
// 初始化2M物理页
|
if (*pdpte_ptr == 0)
|
||||||
for (ul i = 0; i < (length); i += PAGE_2M_SIZE)
|
{
|
||||||
{
|
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
|
||||||
// 计算当前2M物理页对应的pdt的页表项的物理地址
|
memset(virt_addr, 0, PAGE_4K_SIZE);
|
||||||
|
set_pdpt(pdpte_ptr, mk_pdpt(virt_2_phys(virt_addr), (user ? PAGE_USER_DIR : PAGE_KERNEL_DIR)));
|
||||||
|
// kdebug("created new pdt, *pdpte_ptr=%#018lx, virt_addr=%#018lx", *pdpte_ptr, virt_addr);
|
||||||
|
}
|
||||||
|
|
||||||
tmp1 = phys_2_virt(((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff)));
|
uint64_t pde_id = (((virt_addr_start + length_mapped) >> PAGE_2M_SHIFT) & 0x1ff);
|
||||||
|
uint64_t *pd_ptr = (uint64_t *)phys_2_virt(*pdpte_ptr & (~0xfffUL));
|
||||||
|
// kdebug("pd_ptr=%#018lx, *pd_ptr=%#018lx", pd_ptr, *pd_ptr);
|
||||||
|
|
||||||
// 页面写穿,禁止缓存
|
// 循环填写三级页表,初始化2M物理页
|
||||||
set_pdt(tmp1, mk_pdt((ul)phys_addr_start + i, flags | (user ? PAGE_USER_PAGE : PAGE_KERNEL_PAGE)));
|
for (; (pgt_num.num_PDE > 0) && pde_id < 512; ++pde_id)
|
||||||
|
{
|
||||||
|
--pgt_num.num_PDE;
|
||||||
|
// 计算当前2M物理页对应的pdt的页表项的物理地址
|
||||||
|
ul *pde_ptr = pd_ptr + pde_id;
|
||||||
|
|
||||||
|
// 页面写穿,禁止缓存
|
||||||
|
set_pdt(pde_ptr, mk_pdt((ul)phys_addr_start + length_mapped, flags | (user ? PAGE_USER_PAGE : PAGE_KERNEL_PAGE)));
|
||||||
|
length_mapped += PAGE_2M_SIZE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flush_tlb();
|
flush_tlb();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,32 +658,70 @@ uint64_t mm_get_PDE(ul proc_page_table_addr, bool is_phys, ul virt_addr, bool cl
|
|||||||
*/
|
*/
|
||||||
void mm_unmap_proc_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul length)
|
void mm_unmap_proc_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_start, ul length)
|
||||||
{
|
{
|
||||||
ul *tmp;
|
|
||||||
|
// 计算线性地址对应的pml4页表项的地址
|
||||||
|
mm_pgt_entry_num_t pgt_num;
|
||||||
|
mm_calculate_entry_num(length, &pgt_num);
|
||||||
|
// kdebug("ent1=%d ent2=%d ent3=%d, ent4=%d", pgt_num.num_PML4E, pgt_num.num_PDPTE, pgt_num.num_PDE, pgt_num.num_PTE);
|
||||||
|
// 已取消映射的内存大小
|
||||||
|
uint64_t length_unmapped = 0;
|
||||||
|
|
||||||
|
uint64_t pml4e_id = ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff);
|
||||||
|
uint64_t *pml4_ptr;
|
||||||
if (is_phys)
|
if (is_phys)
|
||||||
tmp = phys_2_virt((ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff));
|
pml4_ptr = phys_2_virt((ul *)((ul)proc_page_table_addr & (~0xfffUL)));
|
||||||
else
|
else
|
||||||
tmp = (ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff);
|
pml4_ptr = (ul *)((ul)proc_page_table_addr & (~0xfffUL));
|
||||||
|
|
||||||
// pml4页表项为0
|
// 循环填写顶层页表
|
||||||
if (*tmp == 0)
|
for (; (pgt_num.num_PML4E > 0) && pml4e_id < 512; ++pml4e_id)
|
||||||
return;
|
|
||||||
|
|
||||||
tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff));
|
|
||||||
|
|
||||||
// pdpt页表项为0
|
|
||||||
if (*tmp == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ul *tmp1;
|
|
||||||
|
|
||||||
for (ul i = 0; i < (length); i += PAGE_2M_SIZE)
|
|
||||||
{
|
{
|
||||||
// 计算当前2M物理页对应的pdt的页表项的物理地址
|
// 剩余需要处理的pml4E -1
|
||||||
tmp1 = phys_2_virt(((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff)));
|
--(pgt_num.num_PML4E);
|
||||||
// 清除映射
|
|
||||||
*tmp1 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ul *pml4e_ptr = NULL;
|
||||||
|
pml4e_ptr = pml4_ptr + pml4e_id;
|
||||||
|
|
||||||
|
// 二级页表不存在
|
||||||
|
if (*pml4e_ptr == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t pdpte_id = (((virt_addr_start + length_unmapped) >> PAGE_1G_SHIFT) & 0x1ff);
|
||||||
|
uint64_t *pdpt_ptr = (uint64_t *)phys_2_virt(*pml4e_ptr & (~0xfffUL));
|
||||||
|
// kdebug("pdpt_ptr=%#018lx", pdpt_ptr);
|
||||||
|
|
||||||
|
// 循环处理二级页表
|
||||||
|
for (; (pgt_num.num_PDPTE > 0) && pdpte_id < 512; ++pdpte_id)
|
||||||
|
{
|
||||||
|
--pgt_num.num_PDPTE;
|
||||||
|
uint64_t *pdpte_ptr = (pdpt_ptr + pdpte_id);
|
||||||
|
// kdebug("pgt_num.num_PDPTE=%ld pdpte_ptr=%#018lx", pgt_num.num_PDPTE, pdpte_ptr);
|
||||||
|
|
||||||
|
// 三级页表为空
|
||||||
|
if (*pdpte_ptr == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t pde_id = (((virt_addr_start + length_unmapped) >> PAGE_2M_SHIFT) & 0x1ff);
|
||||||
|
uint64_t *pd_ptr = (uint64_t *)phys_2_virt(*pdpte_ptr & (~0xfffUL));
|
||||||
|
// kdebug("pd_ptr=%#018lx, *pd_ptr=%#018lx", pd_ptr, *pd_ptr);
|
||||||
|
|
||||||
|
// 循环处理三级页表
|
||||||
|
for (; (pgt_num.num_PDE > 0) && pde_id < 512; ++pde_id)
|
||||||
|
{
|
||||||
|
--pgt_num.num_PDE;
|
||||||
|
// 计算当前2M物理页对应的pdt的页表项的物理地址
|
||||||
|
ul *pde_ptr = pd_ptr + pde_id;
|
||||||
|
|
||||||
|
*pde_ptr = 0;
|
||||||
|
|
||||||
|
length_unmapped += PAGE_2M_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
flush_tlb();
|
flush_tlb();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -840,7 +808,7 @@ uint64_t mm_do_brk(uint64_t old_brk_end_addr, int64_t offset)
|
|||||||
{
|
{
|
||||||
for (uint64_t i = old_brk_end_addr; i < end_addr; i += PAGE_2M_SIZE)
|
for (uint64_t i = old_brk_end_addr; i < end_addr; i += PAGE_2M_SIZE)
|
||||||
{
|
{
|
||||||
kdebug("map [%#018lx]", i);
|
// kdebug("map [%#018lx]", i);
|
||||||
mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, i, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true);
|
mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, i, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true);
|
||||||
}
|
}
|
||||||
current_pcb->mm->brk_end = end_addr;
|
current_pcb->mm->brk_end = end_addr;
|
||||||
|
@ -233,7 +233,6 @@ int ZONE_DMA_INDEX = 0;
|
|||||||
int ZONE_NORMAL_INDEX = 0; // low 1GB RAM ,was mapped in pagetable
|
int ZONE_NORMAL_INDEX = 0; // low 1GB RAM ,was mapped in pagetable
|
||||||
int ZONE_UNMAPPED_INDEX = 0; // above 1GB RAM,unmapped in pagetable
|
int ZONE_UNMAPPED_INDEX = 0; // above 1GB RAM,unmapped in pagetable
|
||||||
|
|
||||||
ul *global_CR3 = NULL;
|
|
||||||
|
|
||||||
// 初始化内存管理单元
|
// 初始化内存管理单元
|
||||||
void mm_init();
|
void mm_init();
|
||||||
|
@ -647,7 +647,7 @@ int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigne
|
|||||||
void process_init()
|
void process_init()
|
||||||
{
|
{
|
||||||
kinfo("Initializing process...");
|
kinfo("Initializing process...");
|
||||||
initial_mm.pgd = (pml4t_t *)global_CR3;
|
initial_mm.pgd = (pml4t_t *)get_CR3();
|
||||||
|
|
||||||
initial_mm.code_addr_start = memory_management_struct.kernel_code_start;
|
initial_mm.code_addr_start = memory_management_struct.kernel_code_start;
|
||||||
initial_mm.code_addr_end = memory_management_struct.kernel_code_end;
|
initial_mm.code_addr_end = memory_management_struct.kernel_code_end;
|
||||||
|
@ -41,7 +41,7 @@ void smp_init()
|
|||||||
set_intr_gate(i, 0, SMP_interrupt_table[i - 200]);
|
set_intr_gate(i, 0, SMP_interrupt_table[i - 200]);
|
||||||
|
|
||||||
memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM);
|
memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM);
|
||||||
|
|
||||||
// 注册接收bsp处理器的hpet中断转发的处理函数
|
// 注册接收bsp处理器的hpet中断转发的处理函数
|
||||||
ipi_regiserIPI(0xc8, NULL, &ipi_0xc8_handler, NULL, NULL, "IPI 0xc8");
|
ipi_regiserIPI(0xc8, NULL, &ipi_0xc8_handler, NULL, NULL, "IPI 0xc8");
|
||||||
|
|
||||||
@ -90,6 +90,7 @@ void smp_init()
|
|||||||
kinfo("Cleaning page table remapping...\n");
|
kinfo("Cleaning page table remapping...\n");
|
||||||
|
|
||||||
// 由于ap处理器初始化过程需要用到0x00处的地址,因此初始化完毕后才取消内存地址的重映射
|
// 由于ap处理器初始化过程需要用到0x00处的地址,因此初始化完毕后才取消内存地址的重映射
|
||||||
|
uint64_t *global_CR3 = get_CR3();
|
||||||
for (int i = 0; i < 128; ++i)
|
for (int i = 0; i < 128; ++i)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -153,13 +154,13 @@ void smp_ap_start()
|
|||||||
current_pcb->preempt_count = 0;
|
current_pcb->preempt_count = 0;
|
||||||
sti();
|
sti();
|
||||||
|
|
||||||
while(1)
|
while (1)
|
||||||
hlt();
|
hlt();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (proc_current_cpu_id == 1)
|
if (proc_current_cpu_id == 1)
|
||||||
process_init();
|
process_init();
|
||||||
*/
|
*/
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
printk_color(BLACK, WHITE, "CPU:%d IDLE process.\n", proc_current_cpu_id);
|
printk_color(BLACK, WHITE, "CPU:%d IDLE process.\n", proc_current_cpu_id);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user