Skip to content

Commit

Permalink
修改页表
Browse files Browse the repository at this point in the history
  • Loading branch information
min0911Y committed Dec 30, 2024
1 parent a08b93f commit ae9c56d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 56 deletions.
2 changes: 1 addition & 1 deletion include/kernel/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ u32 page_get_alloced();
*\param cr3 分页设置(cr3)
*\param map_addr 源(物理)地址
*/
void page_link_addr_pde(usize addr, usize cr3, usize map_addr);
void page_link_addr_pde(usize addr, usize pd, usize map_addr);

// u8 PageType
enum {
Expand Down
107 changes: 52 additions & 55 deletions src/kernel/mm/vpage.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,62 +103,85 @@ static void page_link_pde(u32 addr, u32 pd) {
asm_set_cr3(PD_ADDRESS);
u32 t, p;
t = PDI(addr);
p = (addr >> 12) & 0x3ff;
u32 *pte = (u32 *)((pd + t * 4));
p = PTI(addr);
PDE *pde = (PDE *)((pd + t * 4));

if (pages[IDX(*pte)].count > 1) {
// 其实我们应该判断一下这里user能不能写的
// 但是大多数情况下pde都比较干净,所以先不判断了
if (pages[pde->addr].count > 1) {
// 这个页目录还有人引用,所以需要复制
pages[IDX(*pte)].count--;
u32 old = *pte & 0xfffff000;
*pte = (u32)page_malloc_one_count_from_4gb();
memcpy((void *)(*pte), (void *)old, PAGE_SIZE);
*pte |= 7;
pages[pde->addr].count--;
void *old = (void *)PAGE(pde->addr);
pde->addr = IDX(page_malloc_one_count_from_4gb());
memcpy((void *)(PAGE(pde->addr)), old, PAGE_SIZE);
pde->wrable = true;
pde->user = true;
pde->present = true;
} else {
*pte |= 7;
pde->wrable = true;
pde->user = true;
pde->present = true;
}

u32 *physics = (u32 *)((*pte & 0xfffff000) + p * 4); // PTE页表
PTE *physics = (PTE *)(PAGE(pde->addr) + p * 4); // PTE页表
// COW
if (pages[IDX(*physics)].count > 1) { pages[IDX(*physics)].count--; }
*physics = (u32)page_malloc_one_count_from_4gb();
*physics |= 7;
flush_tlb((u32)pte);
// 本来就不是给你用户访问的就不需要操作引用计数了
// 这里不需要大于1,因为我们就相当于是抛弃了原来的页
if (pages[physics->addr].count && physics->user) { pages[physics->addr].count--; }
physics->addr = IDX(page_malloc_one_count_from_4gb());
physics->wrable = true;
physics->user = true;
physics->present = true;
flush_tlb((void *)pde);
flush_tlb(addr);
current_task->cr3 = cr3_backup;
asm_set_cr3(cr3_backup);
}

void page_link_addr_pde(usize addr, usize pde, usize map_addr) {
void page_link_addr_pde(usize addr, usize pd, usize map_addr) {
u32 cr3_backup = current_task->cr3;
current_task->cr3 = PD_ADDRESS;
asm_set_cr3(PD_ADDRESS);
u32 t, p;
t = PDI(addr);
p = (addr >> 12) & 0x3ff;
u32 *pte = (u32 *)((pde + t * 4));
p = PTI(addr);
PDE *pde = (PDE *)((pd + t * 4));

if (pages[IDX(*pte)].count > 1) {
// 其实我们应该判断一下这里user能不能写的
// 但是大多数情况下pde都比较干净,所以先不判断了
if (pages[pde->addr].count > 1) {
// 这个页目录还有人引用,所以需要复制
pages[IDX(*pte)].count--;
u32 old = *pte & 0xfffff000;
*pte = (u32)page_malloc_one_count_from_4gb();
memcpy((void *)(*pte), (void *)old, PAGE_SIZE);
*pte |= 7;
pages[pde->addr].count--;
void *old = (void *)PAGE(pde->addr);
pde->addr = IDX(page_malloc_one_count_from_4gb());
memcpy((void *)(PAGE(pde->addr)), old, PAGE_SIZE);
pde->wrable = true;
pde->user = true;
pde->present = true;
} else {
*pte |= 7;
pde->wrable = true;
pde->user = true;
pde->present = true;
}

u32 *physics = (u32 *)((*pte & 0xfffff000) + p * 4); // PTE页表
PTE *physics = (PTE *)(PAGE(pde->addr) + p * 4); // PTE页表

// COW
if (pages[IDX(*physics)].count > 1) { pages[IDX(*physics)].count--; }
*physics = (u32)map_addr;
*physics |= 7;
flush_tlb((u32)pte);
// 这里不需要大于1,因为我们就相当于是抛弃了原来的页
if (pages[physics->addr].count && physics->user) { pages[physics->addr].count--; }
physics->addr = IDX(map_addr);
physics->wrable = true;
physics->user = true;
physics->present = true;
flush_tlb((void *)pde);
flush_tlb(addr);
current_task->cr3 = cr3_backup;
asm_set_cr3(cr3_backup);
}

// share 和 没有share的区别是
// share会处理PAGE_SHARED标志,如果这个PDE已经被多个进程引用,那么则会直接覆写
// 而没有share遇到PAGE_SHARED标志,那么如果这个PDE已经被多个进程引用,那么会复制一份
static void page_link_pde_share(u32 addr, u32 pde) {
u32 cr3_backup = current_task->cr3;
current_task->cr3 = PD_ADDRESS;
Expand Down Expand Up @@ -240,32 +263,6 @@ u32 page_get_alloced() {
return r;
}

void page_links_pde(u32 start, u32 numbers, u32 pde) {
int i = 0;
int times = 0;
u32 a[2];
int j = 0;
for (i = IDX(total_mem_size) - 1; i >= 0 && times < numbers; i--) {
if (pages[i].count == 0) {
u32 addr = PAGE(i);
pages[i].count++;
a[j++] = addr;
}
if (j == 2) {
page_link_pde_paddr(start, pde, &(a[0]), a[1]);
times++;
start += PAGE_SIZE;
j = 0;
if (a[0] != 0) { j = 1; }
}
}
if (j) { page_free((void *)a[j - 1], PAGE_SIZE); }
}

void page_links(u32 start, u32 numbers) {
page_links_pde(start, numbers, current_task->cr3);
}

void page_link(u32 addr) {
page_link_pde(addr, current_task->cr3);
}
Expand Down

0 comments on commit ae9c56d

Please sign in to comment.