From dd468a7a376905ed3996408c919bf0a375fa9bdb Mon Sep 17 00:00:00 2001 From: copi143 Date: Thu, 19 Dec 2024 21:28:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E9=A1=B5=E8=A1=A8=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/kernel/cpu.h | 2 +- include/kernel/mtask.h | 2 +- include/kernel/page.h | 23 ++++--- src/kernel/cpu/v86.c | 2 +- src/kernel/exec/exec.c | 14 ++--- src/kernel/init/init.c | 2 +- src/kernel/mm/vpage.c | 128 ++++++++++++++++++-------------------- src/kernel/syscall/mmap.c | 2 +- src/kernel/task/mtask.c | 12 ++-- 9 files changed, 90 insertions(+), 97 deletions(-) diff --git a/include/kernel/cpu.h b/include/kernel/cpu.h index 42b84e41..b33ed5a9 100755 --- a/include/kernel/cpu.h +++ b/include/kernel/cpu.h @@ -94,7 +94,7 @@ typedef struct regs64 { } regs64; void v86_int(byte intnum, regs16 *regs); // 调用虚拟86模式中断 -void init_page(); // 初始化分页 +void init_paging(); // 初始化分页 void init_gdtidt(); // 初始化全局描述符表和中断描述符表 void init_error_inthandler(); // 初始化错误中断处理程序 void fpu_disable(); // 禁用浮点运算单元 diff --git a/include/kernel/mtask.h b/include/kernel/mtask.h index 43eabd54..bc072a07 100755 --- a/include/kernel/mtask.h +++ b/include/kernel/mtask.h @@ -20,7 +20,7 @@ typedef void (*cb_keyboard_t)(u8 data, u32 task); typedef struct __PACKED__ task { stack_frame *esp; - u32 pde; + u32 cr3; u32 user_mode; u32 stack_bottom; // ring0 栈底 u32 running; // 已经占用了多少时间片 diff --git a/include/kernel/page.h b/include/kernel/page.h index ddf91c2b..bc1a1250 100755 --- a/include/kernel/page.h +++ b/include/kernel/page.h @@ -1,16 +1,19 @@ #pragma once #include -#define PAGE_P MASK(0) -#define PAGE_WRABLE MASK(1) -#define PAGE_USER MASK(2) -#define PAGE_WT MASK(3) // 使用直写而不是写回 -#define PAGE_CD MASK(4) // 禁用缓存 -#define PAGE_SHARED 1024 // 自定义的 +#define PAGE_PRESENT MASK(0) // 存在 +#define PAGE_WRABLE MASK(1) // 可写 +#define PAGE_USER MASK(2) // 用户态 +#define PAGE_WT MASK(3) // 使用直写而不是写回 +#define PAGE_CD MASK(4) // 禁用缓存 +#define PAGE_ACCESS MASK(5) // 访问位 +#define PAGE_DIRTY MASK(6) // 脏页 +#define PAGE_GLOBAL MASK(8) // 全局页 +#define PAGE_SHARED MASK(10) // 自定义的 -#define PDE_ADDRESS 0x400000 -#define PTE_ADDRESS (PDE_ADDRESS + 0x1000) -#define PAGE_END (PTE_ADDRESS + 0x400000) +#define PD_ADDRESS 0x400000 +#define PT_ADDRESS (PD_ADDRESS + 0x1000) +#define PAGE_END (PT_ADDRESS + 0x400000) #define PAGE_MANNAGER PAGE_END typedef struct __PACKED__ PageInfo { @@ -54,7 +57,7 @@ void *page_alloc(size_t size); void page_free(void *p, size_t size); void task_free_all_pages(u32 tid); void change_page_task_id(int task_id, void *p, u32 size); -u32 pde_clone(u32 addr); +u32 pd_clone(u32 addr); void *page_malloc_one(); void *page_malloc_one_no_mark(); void page_link(u32 addr); diff --git a/src/kernel/cpu/v86.c b/src/kernel/cpu/v86.c index af3e5e0d..bde12fcb 100644 --- a/src/kernel/cpu/v86.c +++ b/src/kernel/cpu/v86.c @@ -32,7 +32,7 @@ void v86_task() { assert(p, "open /fatfs2/v86_service.bin failed"); vfs_read(p, code, 0, p->size); // 映射页面 - u32 pde = current_task->pde; + u32 pde = current_task->cr3; page_link_addr_pde(0x2000, pde, (u32)code); page_link_addr_pde(0x3000, pde, (u32)ptr); page_link_addr_pde(0x0, pde, 0x0); diff --git a/src/kernel/exec/exec.c b/src/kernel/exec/exec.c index e1db1d50..f7f75f16 100755 --- a/src/kernel/exec/exec.c +++ b/src/kernel/exec/exec.c @@ -26,11 +26,11 @@ void task_app() { current_task->alloc_size = (u32 *)malloc(4); current_task->alloced = 1; *(current_task->alloc_size) = 2 * 1024 * 1024; - u32 pde = current_task->pde; + u32 pde = current_task->cr3; asm_cli; - asm_set_cr3(PDE_ADDRESS); - current_task->pde = PDE_ADDRESS; - klogd("P1 %08x", current_task->pde); + asm_set_cr3(PD_ADDRESS); + current_task->cr3 = PD_ADDRESS; + klogd("P1 %08x", current_task->cr3); for (int i = DIDX(0x70000000) * 4; i < PAGE_SIZE; i += 4) { u32 *pde_entry = (u32 *)(pde + i); @@ -45,7 +45,7 @@ void task_app() { *pde_entry = (u32)page_malloc_one_count_from_4gb(); memcpy((void *)(*pde_entry), (void *)old, PAGE_SIZE); pages[IDX(old)].count--; - *pde_entry |= PAGE_USER | PAGE_P | PAGE_WRABLE; + *pde_entry |= PAGE_USER | PAGE_PRESENT | PAGE_WRABLE; } else { *pde_entry &= 0xfffff; *pde_entry |= 7; @@ -56,11 +56,11 @@ void task_app() { u32 *pte_entry = (u32 *)(p + j); if ((*pte_entry & PAGE_SHARED)) { *pte_entry &= 0xfffff000; - *pte_entry |= PAGE_USER | PAGE_P; + *pte_entry |= PAGE_USER | PAGE_PRESENT; } } } - current_task->pde = pde; + current_task->cr3 = pde; asm_sti; asm_set_cr3(pde); klogd("go to task_to_usermode_elf"); diff --git a/src/kernel/init/init.c b/src/kernel/init/init.c index b33d34c5..035ac17b 100755 --- a/src/kernel/init/init.c +++ b/src/kernel/init/init.c @@ -19,7 +19,7 @@ void init_serial(); void sysinit() { total_mem_size = memtest(0x00400000, 0xbfffffff); - init_page(); + init_paging(); cpuid_do_cache(); // 缓存 CPUID 信息 diff --git a/src/kernel/mm/vpage.c b/src/kernel/mm/vpage.c index 04023b90..f4480009 100755 --- a/src/kernel/mm/vpage.c +++ b/src/kernel/mm/vpage.c @@ -14,20 +14,12 @@ finline void flush_tlb(size_t vaddr) { PageInfo *pages = (PageInfo *)PAGE_MANNAGER; -void init_pdepte(size_t pde_addr, size_t pte_addr, size_t page_end) { - memset((void *)pde_addr, 0, page_end - pde_addr); - { // 这是初始化 PDE (页目录) - size_t *addr = (void *)pde_addr; - for (size_t i = 0; addr + i < (size_t *)pte_addr; i++) { - addr[i] = (pte_addr + i * PAGE_SIZE) | PAGE_P | PAGE_WRABLE; - } +static void init_pdepte(size_t *pd, size_t *pt, size_t *page_end) { + for (size_t i = 0; pd + i < pt; i++) { + pd[i] = ((size_t)pt + i * PAGE_SIZE) | PAGE_PRESENT | PAGE_WRABLE; } - - { // 这是初始化 PTE (页表) - size_t *addr = (void *)PTE_ADDRESS; - for (size_t i = 0; addr + i < (size_t *)PAGE_END; i++) { - addr[i] = (i * PAGE_SIZE) | PAGE_P | PAGE_WRABLE; - } + for (size_t i = 0; pt + i < page_end; i++) { + pt[i] = (i * PAGE_SIZE) | PAGE_PRESENT | PAGE_WRABLE; } } @@ -54,7 +46,7 @@ void page_set_alloced(PageInfo *pg, u32 start, u32 end) { // 为了防止应用程序和操作系统抢占前0x70000000的内存,所以page_link和copy_on_write是从后往前分配的 // OS应该是用不完0x70000000的,所以应用程序大概是可以用满2GB -u32 pde_clone(u32 addr) { +u32 pd_clone(u32 addr) { for (int i = DIDX(0x70000000) * 4; i < PAGE_SIZE; i += 4) { u32 *pde_entry = (u32 *)(addr + i); u32 p = *pde_entry & (0xfffff000); @@ -89,14 +81,14 @@ static void pde_reset(u32 addr) { } void free_pde(u32 addr) { - if (addr == PDE_ADDRESS) return; + if (addr == PD_ADDRESS) return; for (int i = DIDX(0x70000000) * 4; i < DIDX(0xf1000000) * 4; i += 4) { u32 *pde_entry = (u32 *)(addr + i); u32 p = *pde_entry & (0xfffff000); - if (!(*pde_entry & PAGE_USER) && !(*pde_entry & PAGE_P)) { continue; } + if (!(*pde_entry & PAGE_USER) && !(*pde_entry & PAGE_PRESENT)) { continue; } for (int j = 0; j < PAGE_SIZE; j += 4) { u32 *pte_entry = (u32 *)(p + j); - if (*pte_entry & PAGE_USER && *pte_entry & PAGE_P) { pages[IDX(*pte_entry)].count--; } + if (*pte_entry & PAGE_USER && *pte_entry & PAGE_PRESENT) { pages[IDX(*pte_entry)].count--; } } pages[IDX(*pde_entry)].count--; @@ -106,9 +98,9 @@ void free_pde(u32 addr) { } static void page_link_pde(u32 addr, u32 pde) { - u32 pde_backup = current_task->pde; - current_task->pde = PDE_ADDRESS; - asm_set_cr3(PDE_ADDRESS); + u32 cr3_backup = current_task->cr3; + current_task->cr3 = PD_ADDRESS; + asm_set_cr3(PD_ADDRESS); u32 t, p; t = DIDX(addr); p = (addr >> 12) & 0x3ff; @@ -132,14 +124,14 @@ static void page_link_pde(u32 addr, u32 pde) { *physics |= 7; flush_tlb((u32)pte); flush_tlb(addr); - current_task->pde = pde_backup; - asm_set_cr3(pde_backup); + current_task->cr3 = cr3_backup; + asm_set_cr3(cr3_backup); } void page_link_addr_pde(u32 addr, u32 pde, u32 map_addr) { - u32 pde_backup = current_task->pde; - current_task->pde = PDE_ADDRESS; - asm_set_cr3(PDE_ADDRESS); + u32 cr3_backup = current_task->cr3; + current_task->cr3 = PD_ADDRESS; + asm_set_cr3(PD_ADDRESS); u32 t, p; t = DIDX(addr); p = (addr >> 12) & 0x3ff; @@ -163,14 +155,14 @@ void page_link_addr_pde(u32 addr, u32 pde, u32 map_addr) { *physics |= 7; flush_tlb((u32)pte); flush_tlb(addr); - current_task->pde = pde_backup; - asm_set_cr3(pde_backup); + current_task->cr3 = cr3_backup; + asm_set_cr3(cr3_backup); } static void page_link_pde_share(u32 addr, u32 pde) { - u32 pde_backup = current_task->pde; - current_task->pde = PDE_ADDRESS; - asm_set_cr3(PDE_ADDRESS); + u32 cr3_backup = current_task->cr3; + current_task->cr3 = PD_ADDRESS; + asm_set_cr3(PD_ADDRESS); u32 t, p; t = DIDX(addr); p = (addr >> 12) & 0x3ff; @@ -200,14 +192,14 @@ static void page_link_pde_share(u32 addr, u32 pde) { if (flag) { *physics |= PAGE_SHARED; } flush_tlb((u32)pte); flush_tlb(addr); - current_task->pde = pde_backup; - asm_set_cr3(pde_backup); + current_task->cr3 = cr3_backup; + asm_set_cr3(cr3_backup); } static void page_link_pde_paddr(u32 addr, u32 pde, u32 *paddr1, u32 paddr2) { - u32 pde_backup = current_task->pde; - current_task->pde = PDE_ADDRESS; - asm_set_cr3(PDE_ADDRESS); + u32 cr3_backup = current_task->cr3; + current_task->cr3 = PD_ADDRESS; + asm_set_cr3(PD_ADDRESS); u32 t, p; t = DIDX(addr); p = (addr >> 12) & 0x3ff; @@ -236,8 +228,8 @@ static void page_link_pde_paddr(u32 addr, u32 pde, u32 *paddr1, u32 paddr2) { if (flag) { *physics |= PAGE_SHARED; } flush_tlb((u32)pte); flush_tlb(addr); - current_task->pde = pde_backup; - asm_set_cr3(pde_backup); + current_task->cr3 = cr3_backup; + asm_set_cr3(cr3_backup); } u32 page_get_alloced() { @@ -272,15 +264,15 @@ void page_links_pde(u32 start, u32 numbers, u32 pde) { } void page_links(u32 start, u32 numbers) { - page_links_pde(start, numbers, current_task->pde); + page_links_pde(start, numbers, current_task->cr3); } void page_link(u32 addr) { - page_link_pde(addr, current_task->pde); + page_link_pde(addr, current_task->cr3); } void page_link_share(u32 addr) { - page_link_pde_share(addr, current_task->pde); + page_link_pde_share(addr, current_task->cr3); } void copy_from_phy_to_line(u32 phy, u32 line, u32 pde, u32 size) { @@ -303,9 +295,9 @@ void set_line_address(u32 val, u32 line, u32 pde, u32 size) { } void page_unlink_pde(u32 addr, u32 pde) { - u32 pde_backup = current_task->pde; - current_task->pde = PDE_ADDRESS; - asm_set_cr3(PDE_ADDRESS); + u32 cr3_backup = current_task->cr3; + current_task->cr3 = PD_ADDRESS; + asm_set_cr3(PD_ADDRESS); u32 t, p; t = DIDX(addr); p = (addr >> 12) & 0x3ff; @@ -328,29 +320,29 @@ void page_unlink_pde(u32 addr, u32 pde) { *physics = NULL; flush_tlb((u32)pte); flush_tlb(addr); - current_task->pde = pde_backup; - asm_set_cr3(pde_backup); + current_task->cr3 = cr3_backup; + asm_set_cr3(cr3_backup); } void page_unlink(u32 addr) { - page_unlink_pde(addr, current_task->pde); + page_unlink_pde(addr, current_task->cr3); } -void init_page() { +void init_paging() { inthandler_set(0x0e, &page_fault); - init_pdepte(PDE_ADDRESS, PTE_ADDRESS, PAGE_END); + init_pdepte((void *)PD_ADDRESS, (void *)PT_ADDRESS, (void *)PAGE_END); page_manager_init(pages); // kernel 加载到0x280000 // 保留 0 到 0xb00000 (不含) page_set_alloced(pages, 0, 0xb00000); // 0xc0000000 到 0xffffffff 物理内存保留地址 page_set_alloced(pages, 0xc0000000, 0xffffffff); - asm_set_cr3(PDE_ADDRESS); + asm_set_cr3(PD_ADDRESS); asm_set_pg; } void pf_set(u32 memsize) { - u32 *pte = (u32 *)PTE_ADDRESS; + u32 *pte = (u32 *)PT_ADDRESS; for (int i = 0; pte != (u32 *)PAGE_END; pte++, i++) { if (i >= memsize / 4096 && i <= 0xc0000000 / 4096) { *pte = 0; } } @@ -442,7 +434,7 @@ void task_free_all_pages(u32 tid) { int get_pageinpte_address(int t, int p) { int page; tpo2page(&page, t, p); - return (PTE_ADDRESS + page * 4); + return (PT_ADDRESS + page * 4); } int find_kpage(int line, int n) { @@ -536,7 +528,7 @@ u32 page_get_phy(u32 pde, u32 vaddr) { } void copy_on_write(u32 vaddr) { - void *pd = (void *)current_task->pde; // PDE页目录地址 + void *pd = (void *)current_task->cr3; // PDE页目录地址 void *pde = (void *)((u32)pd + (u32)(DIDX(vaddr) * 4)); // PTE地址 void *pde_phy = (void *)(*(u32 *)(pde) & 0xfffff000); // 页 @@ -548,15 +540,15 @@ void copy_on_write(u32 vaddr) { // 设置可写属性,然后进入下一步 *(u32 *)pde |= PAGE_WRABLE; *(u32 *)pde |= PAGE_USER; - *(u32 *)pde |= PAGE_P; + *(u32 *)pde |= PAGE_PRESENT; goto PDE_FLUSH; } // 进行COW *(u32 *)(pde) = (u32)page_malloc_one_count_from_4gb(); // 分配一页 memcpy((void *)(*(u32 *)pde), pde_phy, PAGE_SIZE); // 复制内容 *(u32 *)(pde) |= - (backup & 0x00000fff) | PAGE_WRABLE | PAGE_USER | PAGE_P; // 设置属性(并且可读) - pages[IDX(backup)].count--; // 原有引用减少 + (backup & 0x00000fff) | PAGE_WRABLE | PAGE_USER | PAGE_PRESENT; // 设置属性(并且可读) + pages[IDX(backup)].count--; // 原有引用减少 PDE_FLUSH: // 刷新快表 flush_tlb(*(u32 *)(pde)); @@ -601,13 +593,13 @@ void copy_on_write(u32 vaddr) { // 设置页属性和物理地址 void page_set_physics_attr(u32 vaddr, void *paddr, u32 attr) { - u32 pde_backup = current_task->pde; - current_task->pde = PDE_ADDRESS; - asm_set_cr3(PDE_ADDRESS); + u32 cr3_backup = current_task->cr3; + current_task->cr3 = PD_ADDRESS; + asm_set_cr3(PD_ADDRESS); u32 t, p; t = DIDX(vaddr); p = (vaddr >> 12) & 0x3ff; - u32 *pte = (u32 *)((pde_backup + t * 4)); + u32 *pte = (u32 *)((cr3_backup + t * 4)); if (pages[IDX(*pte)].count > 1 && !(*pte & PAGE_SHARED)) { // 这里SHARED页就不进行COW操作 pages[IDX(*pte)].count--; u32 old = *pte & 0xfffff000; @@ -625,15 +617,15 @@ void page_set_physics_attr(u32 vaddr, void *paddr, u32 attr) { *physics |= attr; flush_tlb((u32)pte); flush_tlb(vaddr); - current_task->pde = pde_backup; - asm_set_cr3(pde_backup); + current_task->cr3 = cr3_backup; + asm_set_cr3(cr3_backup); } -void page_set_physics_attr_pde(u32 vaddr, void *paddr, u32 attr, u32 pde_backup) { +void page_set_physics_attr_pde(u32 vaddr, void *paddr, u32 attr, u32 cr3_backup) { u32 t, p; t = DIDX(vaddr); p = (vaddr >> 12) & 0x3ff; - u32 *pte = (u32 *)((pde_backup + t * 4)); + u32 *pte = (u32 *)((cr3_backup + t * 4)); if (pages[IDX(*pte)].count > 1) { // 这里SHARED页就不进行COW操作 pages[IDX(*pte)].count--; u32 old = *pte & 0xfffff000; @@ -655,16 +647,14 @@ void page_set_physics_attr_pde(u32 vaddr, void *paddr, u32 attr, u32 pde_backup) flush_tlb(vaddr); } -extern TSS32 tss; - __attr(fastcall) void page_fault(i32 id, regs32 *regs) { asm_cli; - u32 pde = current_task->pde; - asm_set_cr3(PDE_ADDRESS); // 设置一个安全的页表 + u32 pde = current_task->cr3; + asm_set_cr3(PD_ADDRESS); // 设置一个安全的页表 void *line_address = (void *)asm_get_cr2(); - if (!(page_get_attr(pde, (u32)line_address) & PAGE_P) || // 不存在 - (!(page_get_attr(pde, (u32)line_address) & PAGE_USER))) { // 用户不可写 + if (!(page_get_attr(pde, (u32)line_address) & PAGE_PRESENT) || // 不存在 + (!(page_get_attr(pde, (u32)line_address) & PAGE_USER))) { // 用户不可写 error("Attempt to read/write a non-existent/kernel memory %p at %p.", line_address, regs->eip); if (current_task->user_mode) { task_kill(current_task); diff --git a/src/kernel/syscall/mmap.c b/src/kernel/syscall/mmap.c index 4029e1a4..ffad8721 100755 --- a/src/kernel/syscall/mmap.c +++ b/src/kernel/syscall/mmap.c @@ -12,7 +12,7 @@ void *syscall_mmap(void *start, u32 length) { u32 page_count = PADDING_UP(length, PAGE_SIZE) / PAGE_SIZE; bool size_is_2M = page_count == 512; - u32 addr = current_task->pde; + u32 addr = current_task->cr3; void *line_addr_start = null; for (int i = DIDX(0x70000000), c = 0; i < 1024; i++) { u32 *pde_entry = (u32 *)addr + i; diff --git a/src/kernel/task/mtask.c b/src/kernel/task/mtask.c index 4b106041..9921c682 100755 --- a/src/kernel/task/mtask.c +++ b/src/kernel/task/mtask.c @@ -12,7 +12,7 @@ task_t task_current = null; static avltree_t tasks = null; static task_t next_set = null; -struct task empty_task = {.tid = -1, .pde = PDE_ADDRESS}; +struct task empty_task = {.tid = -1, .cr3 = PD_ADDRESS}; // -------------------------------------------------- //; 分配任务 @@ -53,7 +53,7 @@ static task_t task_alloc() { t->alloc_addr = 0; t->alloc_size = 0; t->alloced = 0; - t->pde = 0; + t->cr3 = 0; t->press_key_fifo = null; t->release_keyfifo = null; t->sigint_up = 0; @@ -85,8 +85,8 @@ static void task_free(task_t t) { klogi("task_free %d", t->tid); kassert(t->children == null); if (t->parent != null) avltree_delete(t->parent->children, t->tid); - if (t == current_task) asm_set_cr3(PDE_ADDRESS); - free_pde(t->pde); + if (t == current_task) asm_set_cr3(PD_ADDRESS); + free_pde(t->cr3); task_free_all_pages(t->tid); // 释放内存 if (t->press_key_fifo) { page_free(t->press_key_fifo->buf, 4096); @@ -276,7 +276,7 @@ task_t create_task(void *entry, u32 ticks, u32 floor) { avltree_insert(task_current->children, t->tid, t); } - t->pde = pde_clone(current_task->pde); + t->cr3 = pd_clone(current_task->cr3); t->stack_bottom = esp; t->floor = floor; t->running = 0; @@ -483,7 +483,7 @@ int task_fork() { m->mousefifo->buf = page_malloc_one(); memcpy(m->mousefifo->buf, current_task->mousefifo->buf, 4096); } - m->pde = pde_clone(current_task->pde); + m->cr3 = pd_clone(current_task->cr3); m->running = 0; m->jiffies = 0; m->timeout = 1;