diff --git a/kernel/common/glib.h b/kernel/common/glib.h index d64aecb2..f278f791 100644 --- a/kernel/common/glib.h +++ b/kernel/common/glib.h @@ -202,6 +202,16 @@ void *memset(void *dst, unsigned char C, ul size) return dst; } +void *memset_c(void* dst, uint8_t c, size_t count) +{ + uint8_t* xs = (uint8_t*)dst; + + while (count--) + *xs++ = c; + + return dst; +} + /** * @brief 内存拷贝函数 * @@ -210,7 +220,7 @@ void *memset(void *dst, unsigned char C, ul size) * @param Num 字节数 * @return void* */ -static inline void *memcpy(void *dst, void *src, long Num) +static void *memcpy(void *dst, void *src, long Num) { int d0, d1, d2; __asm__ __volatile__("cld \n\t" @@ -262,13 +272,13 @@ int strcmp(char *FirstPart, char *SecondPart) return __res; } -void *memset_c(void *dst, unsigned char c, ul n) -{ - unsigned char *s = (unsigned char *)dst; - for (int i = 0; i < n; ++i) - s[i] = c; - return dst; -} +// void *memset_c(void *dst, unsigned char c, ul n) +// { +// unsigned char *s = (unsigned char *)dst; +// for (int i = 0; i < n; ++i) +// s[i] = c; +// return dst; +// } // 从io口读入8个bit unsigned char io_in8(unsigned short port) diff --git a/kernel/driver/video/video.c b/kernel/driver/video/video.c index c93a174e..c6e47fae 100644 --- a/kernel/driver/video/video.c +++ b/kernel/driver/video/video.c @@ -20,7 +20,7 @@ struct screen_info_t /** * @brief VBE帧缓存区的地址重新映射 - * 将帧缓存区映射到地址0xffff800003000000处 + * 将帧缓存区映射到地址SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE处 */ void init_frame_buffer(bool level) { @@ -42,7 +42,7 @@ void init_frame_buffer(bool level) sc_info.height = info.framebuffer_height; sc_info.length = 1UL * sc_info.width * sc_info.height; - mm_map_proc_page_table(global_CR3, true, sc_info.fb_vaddr, sc_info.fb_paddr, get_VBE_FB_length() << 2, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false); + mm_map_proc_page_table(global_CR3, true, sc_info.fb_vaddr, sc_info.fb_paddr, get_VBE_FB_length() << 2, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD, false, true); set_pos_VBE_FB_addr((uint *)sc_info.fb_vaddr); } else // 高级初始化,增加双缓冲区的支持 @@ -50,7 +50,7 @@ void init_frame_buffer(bool level) // 申请双重缓冲区 struct Page *p = alloc_pages(ZONE_NORMAL, PAGE_2M_ALIGN(sc_info.length << 2) / PAGE_2M_SIZE, 0); sc_info.double_fb_vaddr = (uint64_t)phys_2_virt(p->addr_phys); - mm_map_proc_page_table(global_CR3, true, sc_info.double_fb_vaddr, p->addr_phys, PAGE_2M_ALIGN(sc_info.length << 2), PAGE_KERNEL_PAGE, false); + mm_map_proc_page_table(global_CR3, true, sc_info.double_fb_vaddr, p->addr_phys, PAGE_2M_ALIGN(sc_info.length << 2), PAGE_KERNEL_PAGE, false, true); // 将原有的数据拷贝到double buffer里面 memcpy((void *)sc_info.double_fb_vaddr, (void *)sc_info.fb_vaddr, sc_info.length << 2); diff --git a/kernel/exception/trap.c b/kernel/exception/trap.c index 3485d385..cd18367f 100644 --- a/kernel/exception/trap.c +++ b/kernel/exception/trap.c @@ -4,11 +4,10 @@ #include "../common/kprint.h" #include - // 0 #DE 除法错误 void do_divide_error(struct pt_regs *regs, unsigned long error_code) { - //kerror("do_divide_error(0)"); + // kerror("do_divide_error(0)"); kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\t pid=%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id, current_pcb->pid); current_pcb->state = PROC_STOPPED; while (1) @@ -168,8 +167,7 @@ void do_stack_segment_fault(struct pt_regs *regs, unsigned long error_code) // 13 #GP 通用保护性异常 void do_general_protection(struct pt_regs *regs, unsigned long error_code) { - - + kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\t CPU:%d\n", error_code, regs->rsp, regs->rip, proc_current_cpu_id); if (error_code & 0x01) printk_color(RED, BLACK, "The exception occurred during delivery of an event external to the program,such as an interrupt or an earlier exception.\n"); @@ -193,36 +191,38 @@ void do_general_protection(struct pt_regs *regs, unsigned long error_code) // 14 #PF 页故障 void do_page_fault(struct pt_regs *regs, unsigned long error_code) { - + unsigned long cr2 = 0; - __asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory"); - - kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx,RIP:%#018lx CPU:%d, pid=%d\n",error_code , regs->rsp , regs->rip, proc_current_cpu_id, current_pcb->pid); + __asm__ __volatile__("movq %%cr2, %0" + : "=r"(cr2)::"memory"); - if(!(error_code & 0x01)) - printk_color(RED,BLACK,"Page Not-Present,\t"); + kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx, RBP=%#018lx, RIP:%#018lx CPU:%d, pid=%d\n", error_code, regs->rsp, regs->rbp, regs->rip, proc_current_cpu_id, current_pcb->pid); + kerror("regs->rax = %#018lx\n", regs->rax); + if (!(error_code & 0x01)) + printk_color(RED, BLACK, "Page Not-Present,\t"); - if(error_code & 0x02) - printk_color(RED,BLACK,"Write Cause Fault,\t"); - else - printk_color(RED,BLACK,"Read Cause Fault,\t"); + if (error_code & 0x02) + printk_color(RED, BLACK, "Write Cause Fault,\t"); + else + printk_color(RED, BLACK, "Read Cause Fault,\t"); - if(error_code & 0x04) - printk_color(RED,BLACK,"Fault in user(3)\t"); - else - printk_color(RED,BLACK,"Fault in supervisor(0,1,2)\t"); + if (error_code & 0x04) + printk_color(RED, BLACK, "Fault in user(3)\t"); + else + printk_color(RED, BLACK, "Fault in supervisor(0,1,2)\t"); - if(error_code & 0x08) - printk_color(RED,BLACK,",Reserved Bit Cause Fault\t"); + if (error_code & 0x08) + printk_color(RED, BLACK, ",Reserved Bit Cause Fault\t"); - if(error_code & 0x10) - printk_color(RED,BLACK,",Instruction fetch Cause Fault"); + if (error_code & 0x10) + printk_color(RED, BLACK, ",Instruction fetch Cause Fault"); - printk_color(RED,BLACK,"\n"); + printk_color(RED, BLACK, "\n"); - printk_color(RED,BLACK,"CR2:%#018lx\n",cr2); + printk_color(RED, BLACK, "CR2:%#018lx\n", cr2); + current_pcb->state = PROC_STOPPED; while (1) hlt(); } @@ -281,8 +281,6 @@ void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code) // 21-21 Intel保留,请勿使用 - - void sys_vector_init() { set_trap_gate(0, 0, divide_error); @@ -307,9 +305,6 @@ void sys_vector_init() set_trap_gate(19, 0, SIMD_exception); set_trap_gate(20, 0, virtualization_exception); // 中断号21-31由Intel保留,不能使用 - - // 32-255为用户自定义中断内部 - } \ No newline at end of file diff --git a/kernel/mm/mm.c b/kernel/mm/mm.c index fd6f77eb..6d4d1f0f 100644 --- a/kernel/mm/mm.c +++ b/kernel/mm/mm.c @@ -177,7 +177,6 @@ void mm_init() } } - // 初始化0~2MB的物理页 // 由于这个区间的内存由多个内存段组成,因此不会被以上代码初始化,需要我们手动配置page[0]。 @@ -340,19 +339,20 @@ struct Page *alloc_pages(unsigned int zone_select, int num, ul flags) // 分配页面,手动配置属性及计数器 // 置位bmp *(memory_management_struct.bmp + ((x->addr_phys >> PAGE_2M_SHIFT) >> 6)) |= (1UL << (x->addr_phys >> PAGE_2M_SHIFT) % 64); - ++z->count_pages_using; - --z->count_pages_free; + ++(z->count_pages_using); + --(z->count_pages_free); x->attr = attr; } // 成功分配了页面,返回第一个页面的指针 - // printk("start page num=%d\n",start_page_num); + kwarn("start page num=%d\n", start_page_num); return (struct Page *)(memory_management_struct.pages_struct + start_page_num); } } } } kBUG("Cannot alloc page, ZONE=%d\tnums=%d, total_2M_pages=%d", zone_select, num, total_2M_pages); - while(1); + while (1) + ; return NULL; } @@ -467,6 +467,7 @@ void page_table_init() ul *pd_addr = phys_2_virt(*pdpt_addr & (~0xfffUL)); kdebug("pd addr=%#018lx *pd=%#018lx", pd_addr, *pd_addr); */ + int js = 0; ul *tmp_addr; for (int i = 0; i < memory_management_struct.count_zones; ++i) { @@ -478,13 +479,26 @@ void page_table_init() for (int j = 0; j < z->count_pages; ++j) { - mm_map_phys_addr((ul)phys_2_virt(p->addr_phys), p->addr_phys, PAGE_2M_SIZE, PAGE_KERNEL_PAGE); + if (j == 0) + kdebug("(ul)phys_2_virt(p->addr_phys)=%#018lx",(ul)phys_2_virt(p->addr_phys)); + //mm_map_phys_addr((ul)phys_2_virt(p->addr_phys), p->addr_phys, PAGE_2M_SIZE, PAGE_KERNEL_PAGE); + mm_map_proc_page_table((uint64_t)get_CR3(), true, (ul)phys_2_virt(p->addr_phys), p->addr_phys, PAGE_2M_SIZE, PAGE_KERNEL_PAGE, false, true); + ++js; } } flush_tlb(); - kinfo("Page table Initialized."); + kinfo("Page table Initialized. Affects:%d", js); + // for(int i=0;i<100;++i) + // { + // struct Page * p=alloc_pages(ZONE_NORMAL, 1, 0); + // kdebug("Testing [%d]: addr_phys=%#018lx", i,p->addr_phys); + // memset((void*)(phys_2_virt(p->addr_phys)), 0, PAGE_2M_SIZE); + + // } + // while(1) + // pause(); } /** @@ -498,13 +512,13 @@ void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flag { uint64_t global_CR3 = (uint64_t)get_CR3(); - mm_map_proc_page_table(global_CR3, true, virt_addr_start, phys_addr_start, length, flags, false); + mm_map_proc_page_table(global_CR3, true, virt_addr_start, phys_addr_start, length, flags, false, true); } void mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul flags) { 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); + mm_map_proc_page_table(global_CR3, true, virt_addr_start, phys_addr_start, length, flags, true, true); } /** @@ -516,8 +530,9 @@ void mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul * @param phys_addr_start 物理地址的起始位置 * @param length 要映射的区域的长度(字节) * @param user 用户态是否可访问 + * @param flush 是否刷新tlb */ -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, bool flush) { // 计算线性地址对应的pml4页表项的地址 @@ -580,14 +595,19 @@ void mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_ --pgt_num.num_PDE; // 计算当前2M物理页对应的pdt的页表项的物理地址 ul *pde_ptr = pd_ptr + pde_id; - + if (*pde_ptr != 0 && user) + { + kwarn("page already mapped!"); + continue; + } // 页面写穿,禁止缓存 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(); + if (flush) + flush_tlb(); } /** @@ -786,8 +806,8 @@ 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) { - // 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); + 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, true); } current_pcb->mm->brk_end = end_addr; } diff --git a/kernel/mm/mm.h b/kernel/mm/mm.h index a7435477..5c3920b6 100644 --- a/kernel/mm/mm.h +++ b/kernel/mm/mm.h @@ -366,8 +366,9 @@ void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flag * @param phys_addr_start 物理地址的起始位置 * @param length 要映射的区域的长度(字节) * @param user 用户态是否可访问 + * @param flush 是否刷新tlb */ -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, bool flush); void mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul flags); diff --git a/kernel/process/process.c b/kernel/process/process.c index dda49383..487d240e 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -15,6 +15,9 @@ spinlock_t process_global_pid_write_lock; // 增加pid的写锁 long process_global_pid = 1; // 系统中最大的pid +uint64_t pid_one_map_offset = 0x0000020000000000; +int pid_one_map_count = 0; + extern void system_call(void); extern void kernel_thread_func(void); @@ -125,206 +128,6 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc // wrmsr(0x175, next->thread->rbp); } -/** - * @brief 这是一个用户态的程序 - * - */ -void user_level_function() -{ - // kinfo("Program (user_level_function) is runing..."); - // kinfo("Try to enter syscall id 15..."); - // enter_syscall(15, 0, 0, 0, 0, 0, 0, 0, 0); - - // enter_syscall(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0); - // while(1); - long ret = 0; - // printk_color(RED,BLACK,"user_level_function task is running\n"); - - /* - // 测试sys put string - char string[] = "User level process.\n"; - long err_code = 1; - ul addr = (ul)string; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_PUT_STRING), "m"(addr) - : "memory", "r8"); - */ - while (1) - { - // 测试sys_open - char string[] = "333.txt"; - long err_code = 1; - int zero = 0; - - uint64_t addr = (ul)string; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "movq %3, %%r9 \n\t" - "movq %4, %%r10 \n\t" - "movq %5, %%r11 \n\t" - "movq %6, %%r12 \n\t" - "movq %7, %%r13 \n\t" - "movq %8, %%r14 \n\t" - "movq %9, %%r15 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_OPEN), "m"(addr), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) - : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); - - int fd_num = err_code; - - int count = 128; - // while (count) - //{ - uchar buf[128] = {0}; - // Test sys_read - addr = (uint64_t)&buf; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "movq %3, %%r9 \n\t" - "movq %4, %%r10 \n\t" - "movq %5, %%r11 \n\t" - "movq %6, %%r12 \n\t" - "movq %7, %%r13 \n\t" - "movq %8, %%r14 \n\t" - "movq %9, %%r15 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_READ), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) - : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); - count = err_code; - // 将读取到的数据打印出来 - addr = (ul)buf; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_PUT_STRING), "m"(addr) - : "memory", "r8"); - // SYS_WRITE - char test1[] = "GGGGHHHHHHHHh112343"; - - addr = (uint64_t)&test1; - count = 19; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "movq %3, %%r9 \n\t" - "movq %4, %%r10 \n\t" - "movq %5, %%r11 \n\t" - "movq %6, %%r12 \n\t" - "movq %7, %%r13 \n\t" - "movq %8, %%r14 \n\t" - "movq %9, %%r15 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_WRITE), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) - : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); - - addr = 1; - count = SEEK_SET; - fd_num = 0; - // Test lseek - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "movq %3, %%r9 \n\t" - "movq %4, %%r10 \n\t" - "movq %5, %%r11 \n\t" - "movq %6, %%r12 \n\t" - "movq %7, %%r13 \n\t" - "movq %8, %%r14 \n\t" - "movq %9, %%r15 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_LSEEK), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) - : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); - - // SYS_WRITE - char test2[] = "K123456789K"; - - addr = (uint64_t)&test2; - count = 11; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "movq %3, %%r9 \n\t" - "movq %4, %%r10 \n\t" - "movq %5, %%r11 \n\t" - "movq %6, %%r12 \n\t" - "movq %7, %%r13 \n\t" - "movq %8, %%r14 \n\t" - "movq %9, %%r15 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_WRITE), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) - : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); - // Test sys_close - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "movq %3, %%r9 \n\t" - "movq %4, %%r10 \n\t" - "movq %5, %%r11 \n\t" - "movq %6, %%r12 \n\t" - "movq %7, %%r13 \n\t" - "movq %8, %%r14 \n\t" - "movq %9, %%r15 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_CLOSE), "m"(fd_num), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) - : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); - - addr = (ul)string; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "movq %3, %%r9 \n\t" - "movq %4, %%r10 \n\t" - "movq %5, %%r11 \n\t" - "movq %6, %%r12 \n\t" - "movq %7, %%r13 \n\t" - "movq %8, %%r14 \n\t" - "movq %9, %%r15 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_OPEN), "m"(addr), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) - : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); - fd_num = err_code; - count = 128; - // Test sys_read - addr = (uint64_t)&buf; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "movq %3, %%r9 \n\t" - "movq %4, %%r10 \n\t" - "movq %5, %%r11 \n\t" - "movq %6, %%r12 \n\t" - "movq %7, %%r13 \n\t" - "movq %8, %%r14 \n\t" - "movq %9, %%r15 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_READ), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero) - : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); - count = err_code; - // 将读取到的数据打印出来 - addr = (ul)buf; - __asm__ __volatile__( - "movq %2, %%r8 \n\t" - "int $0x80 \n\t" - : "=a"(err_code) - : "a"(SYS_PUT_STRING), "m"(addr) - : "memory", "r8"); - - // Test Sys - //} - - while (1) - pause(); - } - while (1) - pause(); -} - /** * @brief 打开要执行的程序文件 * @@ -443,13 +246,16 @@ static int process_load_elf_file(struct pt_regs *regs, char *path) pos = phdr->p_offset; uint64_t virt_base = phdr->p_vaddr; + kdebug("virt_base = %#018lx, &memory_management_struct=%#018lx", virt_base, &memory_management_struct); + while (remain_mem_size > 0) { // todo: 改用slab分配4K大小内存块并映射到4K页 if (!mm_check_mapped((uint64_t)current_pcb->mm->pgd, virt_base)) // 未映射,则新增物理页 { - mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, virt_base, 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, virt_base, alloc_pages(ZONE_NORMAL, 10, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true, true); + memset((void *)virt_base, 0, PAGE_2M_SIZE); } pos = filp->file_ops->lseek(filp, pos, SEEK_SET); @@ -472,10 +278,35 @@ static int process_load_elf_file(struct pt_regs *regs, char *path) // 分配2MB的栈内存空间 regs->rsp = current_pcb->mm->stack_start; regs->rbp = current_pcb->mm->stack_start; - mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true); + + uint64_t pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys; + // pa+= PAGE_2M_SIZE; + kdebug("pa1=%#018lx", pa); + // mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true, false); + // mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE, pa, PAGE_2M_SIZE, PAGE_USER_PAGE, true, true); + // pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys; + // kdebug("pa2=%#018lx", pa); + // // mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE, pa, PAGE_2M_SIZE, PAGE_USER_PAGE, true, true); + + // pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys; + // kdebug("pa3=%#018lx", pa); + mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE, pa, PAGE_2M_SIZE, PAGE_USER_PAGE, true, true); + // mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, 1 * PAGE_2M_SIZE, PAGE_USER_PAGE, true); // 清空栈空间 memset((void *)(current_pcb->mm->stack_start - PAGE_2M_SIZE), 0, PAGE_2M_SIZE); + // mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE * 2, alloc_pages(ZONE_NORMAL, 2, PAGE_PGT_MAPPED)->addr_phys, 2 * PAGE_2M_SIZE, PAGE_USER_PAGE, true); + // // 清空栈空间 + // memset((void *)(current_pcb->mm->stack_start - 2 * PAGE_2M_SIZE), 0, 2 * PAGE_2M_SIZE); + + // if (current_pcb->pid == 1 && pid_one_map_count < 2) + // { + // mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, pid_one_map_offset, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true); + // memset(pid_one_map_offset, 0, PAGE_2M_SIZE); + // pid_one_map_count++; + // pid_one_map_offset += PAGE_2M_SIZE; + // } + load_elf_failed:; if (buf != NULL) kfree(buf); @@ -516,8 +347,8 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[]) } // 设置用户栈和用户堆的基地址 - unsigned long stack_start_addr = 0x6fffffc00000; - const uint64_t brk_start_addr = 0x6fffffc00000; + unsigned long stack_start_addr = 0x6ffff0a00000UL; + const uint64_t brk_start_addr = 0x700000000000UL; process_switch_mm(current_pcb); @@ -655,7 +486,7 @@ ul process_do_exit(ul code) // todo: 可否在这里释放内存结构体?(在判断共享页引用问题之后) pcb->state = PROC_ZOMBIE; - pcb->exit_code = pcb; + pcb->exit_code = code; sti(); process_exit_notify(); @@ -841,6 +672,10 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned retval = tsk->pid; kdebug("fork done: tsk->pid=%d", tsk->pid); + + // kdebug("current_pcb->mm->brk_end=%#018lx", current_pcb->mm->brk_end); + // mm_map_proc_page_table((uint64_t)current_pcb->mm->pgd, true, 0x0000500000000000, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true); + // 唤醒进程 process_wakeup(tsk); @@ -1003,52 +838,121 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb // 当前页表项为空 if ((*(uint64_t *)(current_pgd + i)) == 0) continue; - + kdebug("user page [%d]", i); // 分配新的二级页表 - pdpt_t *new_pdpt = (pdpt_t *)kmalloc(PAGE_4K_SIZE, 0); + uint64_t *new_pdpt = (uint64_t *)kmalloc(PAGE_4K_SIZE, 0); memset(new_pdpt, 0, PAGE_4K_SIZE); // 在新的一级页表中设置新的二级页表表项 set_pml4t(new_pml4t + i, mk_pml4t(virt_2_phys(new_pdpt), (*(current_pgd + i)) & 0xfffUL)); - pdpt_t *current_pdpt = (pdpt_t *)phys_2_virt(*(uint64_t *)(current_pgd + i) & (~0xfffUL)); - - kdebug("i=%d, current pdpt=%#018lx \t (current_pgd + i)->pml4t=%#018lx", i, current_pdpt, *(uint64_t *)(current_pgd + i)); - // 设置二级页表 + uint64_t *current_pdpt = (uint64_t *)phys_2_virt((*(uint64_t *)(current_pgd + i)) & (~0xfffUL)); + kdebug("current_pdpt=%#018lx, current_pid=%d", current_pdpt, current_pcb->pid); for (int j = 0; j < 512; ++j) { - if (*(uint64_t *)(current_pdpt + j) == 0) + if (*(current_pdpt + j) == 0) continue; - kdebug("j=%d *(uint64_t *)(current_pdpt + j)=%#018lx", j, *(uint64_t *)(current_pdpt + j)); - // 分配新的三级页表 - pdt_t *new_pdt = (pdt_t *)kmalloc(PAGE_4K_SIZE, 0); + uint64_t *new_pdt = (uint64_t *)kmalloc(PAGE_4K_SIZE, 0); memset(new_pdt, 0, PAGE_4K_SIZE); - + // 在二级页表中填写新的三级页表 // 在新的二级页表中设置三级页表的表项 - set_pdpt((uint64_t *)(new_pdpt + j), mk_pdpt(virt_2_phys(new_pdt), (*(uint64_t *)(current_pdpt + j)) & 0xfffUL)); + set_pdpt((uint64_t *)(new_pdpt + j), mk_pdpt(virt_2_phys(new_pdt), (*(current_pdpt + j)) & 0xfffUL)); - pdt_t *current_pdt = (pdt_t *)phys_2_virt((*(uint64_t *)(current_pdpt + j)) & (~0xfffUL)); - - // 拷贝内存页 + uint64_t *current_pdt = (uint64_t *)phys_2_virt((*(current_pdpt + j)) & (~0xfffUL)); + kdebug("current_pdt=%#018lx", current_pdt); + // 循环拷贝三级页表 for (int k = 0; k < 512; ++k) { - if ((current_pdt + k)->pdt == 0) - continue; - - kdebug("k=%d, (current_pdt + k)->pdt=%#018lx", k, (current_pdt + k)->pdt); - // 获取一个新页 - struct Page *pg = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED); - set_pdt((uint64_t *)(new_pdt + k), mk_pdt(pg->addr_phys, (current_pdt + k)->pdt & 0x1ffUL)); - kdebug("k=%d, cpy dest=%#018lx, src=%#018lx", k, phys_2_virt(pg->addr_phys), phys_2_virt((current_pdt + k)->pdt & (~0x1ffUL))); - // 拷贝数据 - memcpy(phys_2_virt(pg->addr_phys), phys_2_virt((current_pdt + k)->pdt & (~0x1ffUL)), PAGE_2M_SIZE); + // 获取新的物理页 + if (*(current_pdt + k) == 0) + continue; + + // 跳过栈空间 + if (i == 223 && j == 511 && k == 388) + continue; + // if (i > 10) + // continue; + uint64_t pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys; + kdebug("before memset phys_2_virt(pa)=%#018lx", phys_2_virt(pa)); + + memset((void*)phys_2_virt(pa), 0, PAGE_2M_SIZE); + + kdebug("[i=%d][j=%d][k=%d] pg->addr_phys=%#018lx", i, j, k, pa); + + // 计算当前虚拟地址 + uint64_t current_vaddr = 0; + current_vaddr = ((1UL * i) << PAGE_GDT_SHIFT) | ((1UL * j) << PAGE_1G_SHIFT) | ((1UL * k) << PAGE_2M_SHIFT); + kdebug("current_vaddr = %#018lx, pa=%#018lx", current_vaddr, pa); + + mm_map_proc_page_table((uint64_t)pcb->mm->pgd, true, current_vaddr, pa, PAGE_2M_SIZE, PAGE_USER_PAGE, true, false); + kdebug("before memcpy"); + memcpy((void*)phys_2_virt(pa), (void *)current_vaddr, PAGE_2M_SIZE); + + kdebug("current_pcb->mm->stack_start=%#018lx", current_pcb->mm->stack_start); + // kdebug("*(current_pdt+k)=%#018lx", *(current_pdt + k)); + // set_pdt((new_pdt + k), mk_pdt(pa, PAGE_USER_PAGE)); + // // set_pdt((new_pdt + k), mk_pdt(pg->addr_phys, (*(current_pdt + k)) & 0xfffUL)); + + // // memcpy((void *)phys_2_virt(pg->addr_phys), (void *)phys_2_virt((*(current_pdt + k)) & (~0xfffUL)), PAGE_2M_SIZE); + + // kdebug("phys_2_virt((*(current_pdt + k)) & (~0x1ffUL))=%#018lx",phys_2_virt((*(current_pdt + k)) & (~0x1ffUL))); + // memcpy((void *)phys_2_virt(pa), (void *)phys_2_virt((*(current_pdt + k)) & (~0x1ffUL)), PAGE_2M_SIZE); + // set_pdt((new_pdt + k), mk_pdt(pg->addr_phys, PAGE_USER_PAGE)); + + // *(new_pdt + k) = (pg->addr_phys | (*(current_pdt + k)) & (0xfffUL)); } } + // kdebug("current_pcb->mm->stack_start - PAGE_2M_SIZE * 2=%#018lx",current_pcb->mm->stack_start - PAGE_2M_SIZE * 2); + + // kdebug("i=%d, current pdpt=%#018lx \t (current_pgd + i)->pml4t=%#018lx", i, current_pdpt, *(uint64_t *)(current_pgd + i)); + // // 设置二级页表 + // for (int j = 0; j < 512; ++j) + // { + // if (*(uint64_t *)(current_pdpt + j) == 0) + // continue; + + // kdebug("j=%d *(uint64_t *)(current_pdpt + j)=%#018lx", j, *(uint64_t *)(current_pdpt + j)); + + // // 分配新的三级页表 + // uint64_t *new_pdt = (uint64_t *)kmalloc(PAGE_4K_SIZE, 0); + // memset(new_pdt, 0, PAGE_4K_SIZE); + + // // 在新的二级页表中设置三级页表的表项 + // set_pdpt((uint64_t *)(new_pdpt + j), mk_pdpt(virt_2_phys(new_pdt), (*(uint64_t *)(current_pdpt + j)) & 0xfffUL)); + + // uint64_t *current_pdt = (uint64_t *)phys_2_virt((*(uint64_t *)(current_pdpt + j)) & (~0xfffUL)); + + // // 拷贝内存页 + // for (int k = 0; k < 512; ++k) + // { + // if (*(current_pdt + k) == 0) + // continue; + + // kdebug("k=%d, *(current_pdt + k)=%#018lx", k, *(current_pdt + k)); + // // 获取一个新页 + // struct Page *pg = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED); + // set_pdt((uint64_t *)(new_pdt + k), mk_pdt(pg->addr_phys, *(current_pdt + k) & 0x1ffUL)); + + // kdebug("k=%d, cpy dest=%#018lx, src=%#018lx", k, phys_2_virt(pg->addr_phys), phys_2_virt((*(current_pdt + k)) & (~0x1ffUL))); + // // 拷贝数据 + // memcpy(phys_2_virt(pg->addr_phys), phys_2_virt((*(current_pdt + k)) & (~0x1ffUL)), PAGE_2M_SIZE); + // } + // } } + kdebug("mapppping stack mem!!!, pid=%d", pcb->pid); + uint64_t pha = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys; + mm_map_proc_page_table((uint64_t)pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE * 1, pha, 1 * PAGE_2M_SIZE, PAGE_USER_PAGE, true, false); + // mm_map_proc_page_table((uint64_t)pcb->mm->pgd, true, current_pcb->mm->stack_start - PAGE_2M_SIZE * 1, pha, 1 * PAGE_2M_SIZE, PAGE_USER_PAGE, true, false); + // 清空栈空间 + memset(phys_2_virt(pha), 0, PAGE_2M_SIZE); + kdebug("(current_pcb->mm->stack_start - PAGE_2M_SIZE)=%#018lx", (current_pcb->mm->stack_start - PAGE_2M_SIZE)); + memcpy(phys_2_virt(pha), (void *)(current_pcb->mm->stack_start - PAGE_2M_SIZE), PAGE_2M_SIZE); + kdebug("mapppped stack mem!!!"); + return retval; } @@ -1148,7 +1052,7 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block thd->rip = (uint64_t)kernel_thread_func; else thd->rip = (uint64_t)ret_from_system_call; - kdebug("new proc's ret addr = %#018lx\tthd->rip=%#018lx stack_start=%#018lx child_regs->rsp = %#018lx, new_rip=%#018lx)", child_regs->rbx, thd->rip,stack_start,child_regs->rsp, child_regs->rip); + kdebug("new proc's ret addr = %#018lx\tthd->rip=%#018lx stack_start=%#018lx child_regs->rsp = %#018lx, new_rip=%#018lx)", child_regs->rbx, thd->rip, stack_start, child_regs->rsp, child_regs->rip); return 0; } diff --git a/kernel/process/process.h b/kernel/process/process.h index e13f8196..eac49794 100644 --- a/kernel/process/process.h +++ b/kernel/process/process.h @@ -330,8 +330,8 @@ void process_exit_notify(); { \ asm volatile("movq %0, %%cr3 \n\t" ::"r"(next_pcb->mm->pgd) \ : "memory"); \ - flush_tlb(); \ } while (0) +// flush_tlb(); \ // 获取当前cpu id #define proc_current_cpu_id (current_pcb->cpu_id) diff --git a/kernel/sched/sched.c b/kernel/sched/sched.c index 1a73ecfa..ae4b7d68 100644 --- a/kernel/sched/sched.c +++ b/kernel/sched/sched.c @@ -76,7 +76,15 @@ void sched_cfs() } // kdebug("before switch, next.rip = %#018lx\tnext->gs=%#018lx", proc->thread->rip, proc->thread->gs); // kdebug("currentpcb=%#018lx", (uint64_t)current_pcb); + + // if(proc->pid == 1 && pid_one_map_count < 2) + // { + // mm_map_proc_page_table(proc->mm->pgd, true, pid_one_map_offset, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true); + // pid_one_map_count++; + // pid_one_map_offset += PAGE_2M_SIZE; + // } process_switch_mm(proc); + switch_proc(current_pcb, proc); } else // 不进行切换 diff --git a/kernel/smp/smp.c b/kernel/smp/smp.c index 031d070a..75583887 100644 --- a/kernel/smp/smp.c +++ b/kernel/smp/smp.c @@ -91,9 +91,8 @@ void smp_init() // 由于ap处理器初始化过程需要用到0x00处的地址,因此初始化完毕后才取消内存地址的重映射 uint64_t *global_CR3 = get_CR3(); - for (int i = 0; i < 128; ++i) + for (int i = 0; i < 256; ++i) { - *(ul *)(phys_2_virt(global_CR3) + i) = 0UL; } diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index f2615c4c..8bd2db32 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -270,7 +270,7 @@ uint64_t sys_read(struct pt_regs *regs) void *buf = (void *)regs->r9; int64_t count = (int64_t)regs->r10; - // kdebug("sys read: fd=%d", fd_num); + // kdebug("sys read: fd=%d", fd_num); // 校验文件描述符范围 if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM) @@ -605,7 +605,7 @@ uint64_t sys_wait4(struct pt_regs *regs) uint64_t pid = regs->r8; int *status = (int *)regs->r9; int options = regs->r10; - void *rusage = regs->r11; + void *rusage = (void*)regs->r11; struct process_control_block *proc = NULL; struct process_control_block *child_proc = NULL; @@ -634,7 +634,7 @@ uint64_t sys_wait4(struct pt_regs *regs) wait_queue_sleep_on_interriptible(¤t_pcb->wait_child_proc_exit); // 拷贝子进程的返回码 - copy_to_user(status, child_proc->exit_code, sizeof(int)); + copy_to_user(status, (void*)child_proc->exit_code, sizeof(int)); proc->next_pcb = child_proc->next_pcb; // 释放子进程的页表 diff --git a/user/apps/shell/shell.c b/user/apps/shell/shell.c index 4a4d5c9a..f6e135ca 100644 --- a/user/apps/shell/shell.c +++ b/user/apps/shell/shell.c @@ -42,13 +42,19 @@ void main_loop(int kb_fd) unsigned char input_buffer[INPUT_BUFFER_SIZE] = {0}; - sbrk(24); + // sbrk(24); + // brk(0x700000000000 + (1<<21)); pid_t pid = fork(); int retval = 0; - while (1) + for(int i=0;i<10;++i) printf(" @pid=%d ", pid); + + if(pid == 0) + { + int a = 1/0; + } // 初始化当前工作目录的路径 shell_current_path = (char *)malloc(3); diff --git a/user/libs/libsystem/syscall.c b/user/libs/libsystem/syscall.c index fc76d1cd..89d3929e 100644 --- a/user/libs/libsystem/syscall.c +++ b/user/libs/libsystem/syscall.c @@ -3,7 +3,7 @@ #include long syscall_invoke(uint64_t syscall_id, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7) { - uint64_t err_code; + uint64_t __err_code; __asm__ __volatile__( "movq %2, %%r8 \n\t" "movq %3, %%r9 \n\t" @@ -14,11 +14,12 @@ long syscall_invoke(uint64_t syscall_id, uint64_t arg0, uint64_t arg1, uint64_t "movq %8, %%r14 \n\t" "movq %9, %%r15 \n\t" "int $0x80 \n\t" - // "movq %%rax, %0 \n\t" - : "=a"(err_code) + "movq %%rax, %0 \n\t" + :"=a"(__err_code) : "a"(syscall_id), "m"(arg0), "m"(arg1), "m"(arg2), "m"(arg3), "m"(arg4), "m"(arg5), "m"(arg6), "m"(arg7) : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); - errno = err_code; + // printf("errcode = %#018lx\n", __err_code); + errno = __err_code; - return err_code; + return __err_code; }