diff --git a/include/kernel/page.h b/include/kernel/page.h index ab78ed71..511b7fc5 100755 --- a/include/kernel/page.h +++ b/include/kernel/page.h @@ -16,6 +16,10 @@ #define PAGE_END (PT_ADDRESS + 0x400000) #define PAGE_MANNAGER PAGE_END +#ifdef __x86_64__ + +#else + typedef struct PDE { u32 present : 1; // 存在位 u32 wrable : 1; // 读写位 @@ -48,9 +52,10 @@ typedef struct PTE { u32 addr : 20; // 一定要左移 12 位 } PTE; +#endif + typedef struct __PACKED__ PageInfo { - u8 task_id; - u8 count; + u16 count; } PageInfo; #ifdef __x86_64__ @@ -87,17 +92,22 @@ void tpo2page(int *page, int t, int p); void *page_malloc_one_count_from_4gb(); 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 pd_clone(u32 addr); -void pd_free(u32 addr); +usize pd_clone(usize addr); +void pd_free(usize addr); void *page_malloc_one(); -void *page_malloc_one_no_mark(); void page_link(u32 addr); void page_link_share(u32 addr); void page_unlink(u32 addr); u32 page_get_alloced(); -void page_link_addr_pde(u32 addr, u32 pde, u32 map_addr); + +/** + *\brief + * + *\param addr 目标(虚拟)地址 + *\param cr3 分页设置(cr3) + *\param map_addr 源(物理)地址 + */ +void page_link_addr_pde(usize addr, usize cr3, usize map_addr); // u8 PageType enum { diff --git a/include/kernel/task/kernel-part b/include/kernel/task/kernel-part index 76514a4c..27294d59 100644 --- a/include/kernel/task/kernel-part +++ b/include/kernel/task/kernel-part @@ -11,9 +11,9 @@ typedef struct _NAME _NAME; struct _NAME { stack_frame *esp; // - u32 cr3; // + usize cr3; // bool user_mode; // - u32 stack_bottom; // ring0 栈底 + usize stack_bottom; // ring0 栈底 u32 running; // 已经占用了多少时间片 u32 timeout; // 需要占用多少时间片 char *command_line; // 运行程序所使用的命令行 (在单独的页面) diff --git a/src/kernel/cpu/v86.c b/src/kernel/cpu/v86.c index bde12fcb..d10b5189 100644 --- a/src/kernel/cpu/v86.c +++ b/src/kernel/cpu/v86.c @@ -33,10 +33,10 @@ void v86_task() { vfs_read(p, code, 0, p->size); // 映射页面 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(0x2000, pde, (usize)code); + page_link_addr_pde(0x3000, pde, (usize)ptr); page_link_addr_pde(0x0, pde, 0x0); - for (int i = 0x7000; i < 0x100000; i += PAGE_SIZE) { + for (usize i = 0x7000; i < 0x100000; i += PAGE_SIZE) { page_link_addr_pde(i, pde, i); } // 设置状态 diff --git a/src/kernel/drivers/sound/hda.c b/src/kernel/drivers/sound/hda.c index 0ddf70f6..2a89f563 100755 --- a/src/kernel/drivers/sound/hda.c +++ b/src/kernel/drivers/sound/hda.c @@ -377,7 +377,7 @@ void hda_init() { info("input stream count: %d", input_stream_count); output_base = hda_base + 0x80 + (0x20 * input_stream_count); info("output base address: 0x%x", output_base); - output_buffer = page_malloc_one_no_mark(); + output_buffer = page_malloc_one(); int irq = pci_get_drive_irq(hda_bus, hda_slot, hda_func); irq_enable(irq); @@ -394,7 +394,7 @@ void hda_init() { mem_set8(hda_base + 0x4c, 0); mem_set8(hda_base + 0x5c, 0); - corb = page_malloc_one_no_mark(); + corb = page_malloc_one(); mem_set32(hda_base + 0x40, (u32)corb); mem_set32(hda_base + 0x44, 0); @@ -438,7 +438,7 @@ void hda_init() { corb_write_pointer = 1; info("corb has been reset already"); - rirb = page_malloc_one_no_mark(); + rirb = page_malloc_one(); mem_set32(hda_base + 0x50, (u32)rirb); mem_set32(hda_base + 0x54, 0); diff --git a/src/kernel/exec/exec.c b/src/kernel/exec/exec.c index c3927d0a..7f1600bf 100755 --- a/src/kernel/exec/exec.c +++ b/src/kernel/exec/exec.c @@ -35,10 +35,6 @@ void task_app() { u32 *pde_entry = (u32 *)(pde + i); if ((*pde_entry & PAGE_SHARED) || pages[IDX(*pde_entry)].count > 1) { - // if (pde_entry == 0x08e6b718) { - // while (true) - // ; - // } if (pages[IDX(*pde_entry)].count > 1) { u32 old = *pde_entry & 0xfffff000; u32 attr = *pde_entry & 0xfff; @@ -138,7 +134,6 @@ void task_to_user_mode_elf() { klogd("eip = %08x", iframe->eip); current_task->user_mode = 1; tss.esp0 = current_task->stack_bottom; - change_page_task_id(current_task->tid, elf_data, file->size); asm volatile("mov %0, %%esp\n\t" ::"r"(iframe)); asm volatile("jmp asm_inthandler_quit\n\t"); diff --git a/src/kernel/mm/vpage.c b/src/kernel/mm/vpage.c index 4eb315c3..80973554 100755 --- a/src/kernel/mm/vpage.c +++ b/src/kernel/mm/vpage.c @@ -12,10 +12,12 @@ static inthandler_f page_fault; // 刷新虚拟地址 vaddr 的 块表 TLB -finline void flush_tlb(size_t vaddr) { +finline void flush_tlb(usize vaddr) { asm volatile("invlpg (%0)" ::"r"(vaddr) : "memory"); } +#define flush_tlb(vaddr) flush_tlb((usize)(vaddr)) + PageInfo *pages = (PageInfo *)PAGE_MANNAGER; static void init_pdepte(size_t *pd, size_t *pt, size_t *page_end) { @@ -50,7 +52,7 @@ void page_set_alloced(PageInfo *pg, u32 start, u32 end) { // 为了防止应用程序和操作系统抢占前0x70000000的内存,所以page_link和copy_on_write是从后往前分配的 // OS应该是用不完0x70000000的,所以应用程序大概是可以用满2GB -u32 pd_clone(u32 addr) { +usize pd_clone(usize addr) { const var pd = (PDE *)addr; for (usize i = PDI(0x70000000); i < 1024; i++) { var pde = &pd[i]; @@ -63,12 +65,12 @@ u32 pd_clone(u32 addr) { pte->wrable = pte->shared ? true : false; } } - u32 result = (u32)page_malloc_one_no_mark(); - memcpy((void *)result, (void *)addr, PAGE_SIZE); + var result = page_malloc_one(); + memcpy(result, (void *)addr, PAGE_SIZE); flush_tlb(result); flush_tlb(addr); asm_set_cr3(addr); - return result; + return (usize)result; } static void pde_reset(u32 addr) { @@ -78,7 +80,7 @@ static void pde_reset(u32 addr) { } } -void pd_free(u32 addr) { +void pd_free(usize addr) { if (addr == PD_ADDRESS) return; for (int i = PDI(0x70000000) * 4; i < PDI(0xf1000000) * 4; i += 4) { u32 *pde_entry = (u32 *)(addr + i); @@ -126,7 +128,7 @@ static void page_link_pde(u32 addr, u32 pd) { asm_set_cr3(cr3_backup); } -void page_link_addr_pde(u32 addr, u32 pde, u32 map_addr) { +void page_link_addr_pde(usize addr, usize pde, usize map_addr) { u32 cr3_backup = current_task->cr3; current_task->cr3 = PD_ADDRESS; asm_set_cr3(PD_ADDRESS); @@ -245,8 +247,7 @@ void page_links_pde(u32 start, u32 numbers, u32 pde) { 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].task_id = current_task->tid; + u32 addr = PAGE(i); pages[i].count++; a[j++] = addr; } @@ -363,71 +364,29 @@ void tpo2page(int *page, int t, int p) { *page = (t * 1024) + p; } -void *page_malloc_one_no_mark() { - int i; - for (i = 0; i != 1024 * 1024; i++) { - if (pages[i].count == 0) { - int t, p; - page2tpo(i, &t, &p); - u32 addr = mk_linear_addr(t, p, 0); - pages[i].task_id = 0; - pages[i].count++; - return (void *)addr; - } - } - return NULL; -} - void *page_malloc_one() { for (int i = 0; i != 1024 * 1024; i++) { if (pages[i].count == 0) { int t, p; page2tpo(i, &t, &p); - u32 addr = mk_linear_addr(t, p, 0); - pages[i].task_id = current_task->tid; - pages[i].count++; - return (void *)addr; - } - } - return NULL; -} - -void *page_malloc_one_mark(u32 tid) { - int i; - for (i = 0; i != 1024 * 1024; i++) { - if (pages[i].count == 0) { - int t, p; - page2tpo(i, &t, &p); - u32 addr = mk_linear_addr(t, p, 0); - pages[i].task_id = tid; + u32 addr = mk_linear_addr(t, p, 0); pages[i].count++; return (void *)addr; } } - return NULL; } void *page_malloc_one_count_from_4gb() { for (int i = IDX(total_mem_size) - 1; i >= 0; i--) { if (pages[i].count == 0) { - u32 addr = PAGE(i); - pages[i].task_id = current_task->tid; + u32 addr = PAGE(i); pages[i].count++; return (void *)addr; } } return NULL; } -// TODO: 当实现线程时,这里需要修改 -void task_free_all_pages(u32 tid) { - for (int i = 0; i < 1024 * 1024; i++) { - if (pages[i].count && pages[i].task_id == tid) { - pages[i].count = 0; - pages[i].task_id = 0; - } - } -} int get_pageinpte_address(int t, int p) { int page; @@ -446,7 +405,6 @@ int find_kpage(int line, int n) { } if (free == n) { for (int j = line - n + 1; j != line + 1; j++) { - pages[j].task_id = 0; pages[j].count++; } line -= n - 1; @@ -472,8 +430,7 @@ void page_free(void *p, size_t size) { if (id >= 1024 * 1024) fatal("炸啦!"); // 超过最大页 // page_free只应用于free page_malloc分配的内存,因此count直接设置为0 // 如果是page_link出来的,那么task_free_all_pages会清理,free_pde也会清理 - pages[id].count = 0; - pages[id].task_id = 0; + pages[id].count = 0; } } @@ -504,13 +461,6 @@ void page_map(void *target, void *start, void *end) { } } -void change_page_task_id(int task_id, void *p, u32 size) { - int page = get_page_from_line_address((int)p); - for (int i = 0; i != ((size - 1) / (4 * 1024)) + 1; i++) { - pages[page + i].task_id = task_id; - } -} - u32 page_get_attr(u32 pde, u32 vaddr) { pde += (u32)(PDI(vaddr) * 4); void *pte = (void *)(*(u32 *)pde & 0xfffff000); diff --git a/src/kernel/task/mtask.c b/src/kernel/task/mtask.c index 19b36b4c..cab064f8 100755 --- a/src/kernel/task/mtask.c +++ b/src/kernel/task/mtask.c @@ -85,7 +85,7 @@ static void task_free(task_t t) { if (t->parent != null) avltree_delete(t->parent->children, t->tid); if (t == current_task) asm_set_cr3(PD_ADDRESS); pd_free(t->cr3); - task_free_all_pages(t->tid); // 释放内存 + // task_free_all_pages(t->tid); // 释放内存 if (t->press_key_fifo) { page_free(t->press_key_fifo->buf, 4096); free(t->press_key_fifo); @@ -266,7 +266,6 @@ task_t create_task(void *entry, u32 ticks, u32 floor) { if (t == null) return null; void *stack = page_alloc(STACK_SIZE); u32 esp = (u32)stack + STACK_SIZE; - change_page_task_id(t->tid, stack, STACK_SIZE); t->esp = (stack_frame *)esp - 1; // switch用到的栈帧 t->esp->eip = (size_t)entry; // 设置跳转地址 @@ -282,7 +281,7 @@ task_t create_task(void *entry, u32 ticks, u32 floor) { t->running = 0; t->timeout = ticks; t->jiffies = 0; - page_link_addr_pde(TASK_USER_PART_ADDR, t->cr3, (u32)t->_user_part); + page_link_addr_pde(TASK_USER_PART_ADDR, t->cr3, (usize)t->_user_part); with_no_interrupts(avltree_insert(tasks, t->tid, t)); return t; @@ -299,16 +298,17 @@ void task_to_user_mode(u32 eip, u32 esp) { iframe->ecx = 0; iframe->eax = 0; - iframe->gs = 0; - iframe->ds = GET_SEL(RING3_DS, SA_RPL3); - iframe->es = GET_SEL(RING3_DS, SA_RPL3); - iframe->fs = GET_SEL(RING3_DS, SA_RPL3); - iframe->ss = GET_SEL(RING3_DS, SA_RPL3); - iframe->cs = GET_SEL(RING3_CS, SA_RPL3); - iframe->eip = eip; - iframe->flags = (0 << 12 | 0b10 | 1 << 9); - iframe->esp = esp; // 设置用户态堆栈 - task_current->user_mode = 1; + iframe->gs = 0; + iframe->ds = GET_SEL(RING3_DS, SA_RPL3); + iframe->es = GET_SEL(RING3_DS, SA_RPL3); + iframe->fs = GET_SEL(RING3_DS, SA_RPL3); + iframe->ss = GET_SEL(RING3_DS, SA_RPL3); + iframe->cs = GET_SEL(RING3_CS, SA_RPL3); + iframe->eip = eip; + iframe->flags = (0 << 12 | 0b10 | 1 << 9); + iframe->esp = esp; // 设置用户态堆栈 + + task_current->user_mode = true; tss.esp0 = task_current->stack_bottom; asm volatile("mov %0, %%esp\n\t" ::"r"(iframe)); @@ -463,8 +463,6 @@ int task_fork() { with_no_interrupts({ memcpy(m, current_task, sizeof(struct task)); u32 stack = (u32)page_alloc(STACK_SIZE); - change_page_task_id(tid, (void *)stack, STACK_SIZE); - // u32 off = m->top - (u32)m->esp; memcpy((void *)stack, (void *)(m->stack_bottom - STACK_SIZE), STACK_SIZE); klogd("s = %08x \n", m->stack_bottom - STACK_SIZE); m->stack_bottom = stack += STACK_SIZE;