diff --git a/kernel/driver/timers/rtc/rtc.c b/kernel/driver/timers/rtc/rtc.c index 219b0a5a..4ea048d6 100644 --- a/kernel/driver/timers/rtc/rtc.c +++ b/kernel/driver/timers/rtc/rtc.c @@ -22,7 +22,7 @@ enum CMOSTimeSelector int rtc_get_cmos_time(struct rtc_time_t *t) { // 为防止中断请求打断该过程,需要先关中断 - cli(); + //cli(); uint8_t status_register_B = read_cmos(0x0B); // 读取状态寄存器B bool is_24h = ((status_register_B & 0x02) ? true : false); // 判断是否启用24小时模式 @@ -53,6 +53,6 @@ int rtc_get_cmos_time(struct rtc_time_t *t) if ((!is_24h) && t->hour & 0x80) // 将十二小时制转为24小时 t->hour = ((t->hour & 0x7f) + 12) % 24; - sti(); + //sti(); return 0; } diff --git a/kernel/exception/entry.S b/kernel/exception/entry.S index 851b2881..04ecbef5 100644 --- a/kernel/exception/entry.S +++ b/kernel/exception/entry.S @@ -104,13 +104,15 @@ Err_Code: // 系统调用入口 // 保存寄存器 ENTRY(system_call) + // 由于sysenter指令会禁用中断,因此要在这里手动开启中断 sti; - hlt + + subq $0x38, %rsp cld; - + pushq %rax movq %es, %rax pushq %rax @@ -137,6 +139,7 @@ ENTRY(system_call) // 将rsp作为参数传递给system_call_function movq %rsp, %rdi + callq system_call_function @@ -145,33 +148,29 @@ ENTRY(system_call) ENTRY(ret_from_system_call) movq %rax, 0x80(%rsp) // 将当前rax的值先存到栈中rax的位置 - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %r11 - popq %r10 - popq %r9 - popq %r8 - popq %rbx - popq %rcx - popq %rdx - popq %rsi - popq %rdi - popq %rbp - - popq %rax // 不允许直接pop到ds - movq %rax, %ds - - popq %rax - movq %rax, %es - - popq %rax - - addq $0x38, %rsp - - .byte 0x48 - sysexit + + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %r11 + popq %r10 + popq %r9 + popq %r8 + popq %rbx + popq %rcx + popq %rdx + popq %rsi + popq %rdi + popq %rbp + popq %rax + movq %rax, %ds + popq %rax + movq %rax, %es + popq %rax + addq $0x38, %rsp + .byte 0x48 + sysexit // 0 #DE 除法错误 diff --git a/kernel/exception/trap.c b/kernel/exception/trap.c index 50bbbfa2..b3b1a374 100644 --- a/kernel/exception/trap.c +++ b/kernel/exception/trap.c @@ -168,7 +168,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) { - hlt(); + kerror("do_general_protection(13),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\n", error_code, regs->rsp, regs->rip); 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"); @@ -192,7 +192,7 @@ 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) { - hlt(); + unsigned long cr2 = 0; __asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory"); diff --git a/kernel/mm/mm.c b/kernel/mm/mm.c index a45af772..37c2d92a 100644 --- a/kernel/mm/mm.c +++ b/kernel/mm/mm.c @@ -164,7 +164,7 @@ void mm_init() if (z->zone_addr_start >= 0x100000000 && (!ZONE_UNMAPPED_INDEX)) ZONE_UNMAPPED_INDEX = i; } - kdebug("ZONE_DMA_INDEX=%d\tZONE_NORMAL_INDEX=%d\tZONE_UNMAPPED_INDEX=%d", ZONE_DMA_INDEX, ZONE_NORMAL_INDEX, ZONE_UNMAPPED_INDEX); + //kdebug("ZONE_DMA_INDEX=%d\tZONE_NORMAL_INDEX=%d\tZONE_UNMAPPED_INDEX=%d", ZONE_DMA_INDEX, ZONE_NORMAL_INDEX, ZONE_UNMAPPED_INDEX); // 设置内存页管理结构的地址,预留了一段空间,防止内存越界。 memory_management_struct.end_of_struct = (ul)((ul)memory_management_struct.zones_struct + memory_management_struct.zones_struct_len + sizeof(long) * 32) & (~(sizeof(long) - 1)); @@ -174,7 +174,7 @@ void mm_init() // 初始化内存管理单元结构所占的物理页的结构体 ul mms_max_page = (virt_2_phys(memory_management_struct.end_of_struct) >> PAGE_2M_SHIFT); // 内存管理单元所占据的序号最大的物理页 - kdebug("mms_max_page=%ld", mms_max_page); + //kdebug("mms_max_page=%ld", mms_max_page); struct Page *tmp_page = NULL; ul page_num; @@ -191,11 +191,11 @@ void mm_init() global_CR3 = get_CR3(); // root_page_table_phys_addr = 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(*phys_2_virt(global_CR3) & (~0xff)) & (~0xff)); + //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(*phys_2_virt(global_CR3) & (~0xff)) & (~0xff)); - kdebug("1.memory_management_struct.bmp:%#018lx\tzone->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free); + //kdebug("1.memory_management_struct.bmp:%#018lx\tzone->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free); //kinfo("Cleaning page table remapping at 0x0000"); kinfo("Memory management unit initialize complete!"); diff --git a/kernel/mm/slab.c b/kernel/mm/slab.c index d6f7252e..a6023097 100644 --- a/kernel/mm/slab.c +++ b/kernel/mm/slab.c @@ -374,7 +374,7 @@ ul slab_init() page_init(page, PAGE_KERNEL_INIT | PAGE_KERNEL | PAGE_PGT_MAPPED); } - kdebug("2.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free); + //kdebug("2.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free); // 为slab内存池对象分配内存空间 ul *virt = NULL; @@ -395,7 +395,7 @@ ul slab_init() kmalloc_cache_group[i].cache_pool_entry->vaddr = virt; } - kdebug("3.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free); + //kdebug("3.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free); kinfo("SLAB initialized successfully!"); diff --git a/kernel/process/process.c b/kernel/process/process.c index 8cc986d4..df841a48 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -8,6 +8,7 @@ #include #include +extern void system_call(void); /** * @brief 切换进程 * @@ -20,24 +21,20 @@ void __switch_to(struct process_control_block *prev, struct process_control_block *next) { initial_tss[0].rsp0 = next->thread->rbp; - kdebug("phys_2_virt(TSS64_Table)=%#018lx", phys_2_virt(TSS64_Table)); set_tss64((uint *)phys_2_virt(TSS64_Table), initial_tss[0].rsp0, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1, initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7); - kdebug("prev->thread=%#018lx", prev->thread); - kdebug("next->thread=%#018lx", next->thread); - __asm__ __volatile__("movq %%fs, %0 \n\t" : "=a"(prev->thread->fs)::"memory"); __asm__ __volatile__("movq %%gs, %0 \n\t" : "=a"(prev->thread->gs)::"memory"); - kdebug("&next->thread->fs=%#018lx", &(next->thread->fs)); __asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs) : "memory"); __asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs) : "memory"); + wrmsr(0x175, next->thread->rbp); kdebug("prev->thread->rsp0:%#018lx\n", prev->thread->rbp); kdebug("next->thread->rsp0:%#018lx\n", next->thread->rbp); } @@ -51,18 +48,21 @@ 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); -long ret = 0; -// color_printk(RED,BLACK,"user_level_function task is running\n"); - char string[]="Hello World!\n"; - __asm__ __volatile__ ( "leaq sysexit_return_address(%%rip), %%rdx \n\t" - "movq %%rsp, %%rcx \n\t" - "sysenter \n\t" - "sysexit_return_address: \n\t" - :"=a"(ret):"0"(1),"D"(string):"memory"); - //kinfo("Return from syscall id 15..."); + // enter_syscall(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0); + long ret = 0; + // color_printk(RED,BLACK,"user_level_function task is running\n"); + + char string[] = "Hello World!\n"; + + __asm__ __volatile__("leaq sysexit_return_address(%%rip), %%rdx \n\t" + "movq %%rsp, %%rcx \n\t" + "sysenter \n\t" + "sysexit_return_address: \n\t" + : "=a"(ret) + : "0"(1), "D"(string) + : "memory", "rcx", "rdx", "r14"); + // kinfo("Return from syscall id 15..."); while (1) ; @@ -89,10 +89,10 @@ ul do_execve(struct pt_regs *regs) // mm_map_proc_page_table(get_CR3(), true, 0x800000, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE, true); uint64_t addr = 0x800000UL; - - unsigned long * tmp = phys_2_virt((unsigned long *)((unsigned long)get_CR3() & (~0xfffUL)) + (( addr>> PAGE_GDT_SHIFT) & 0x1ff)); - - unsigned long * virtual = kmalloc(PAGE_4K_SIZE, 0); + + unsigned long *tmp = phys_2_virt((unsigned long *)((unsigned long)get_CR3() & (~0xfffUL)) + ((addr >> PAGE_GDT_SHIFT) & 0x1ff)); + + unsigned long *virtual = kmalloc(PAGE_4K_SIZE, 0); set_pml4t(tmp, mk_pml4t(virt_2_phys(virtual), PAGE_USER_PGT)); tmp = phys_2_virt((unsigned long *)(*tmp & (~0xfffUL)) + ((addr >> PAGE_1G_SHIFT) & 0x1ff)); @@ -105,9 +105,10 @@ ul do_execve(struct pt_regs *regs) flush_tlb(); -/* - mm_map_phys_addr_user(addr, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE); - */ if (!(current_pcb->flags & PF_KTHREAD)) + /* + mm_map_phys_addr_user(addr, alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys, PAGE_2M_SIZE, PAGE_USER_PAGE); + */ + if (!(current_pcb->flags & PF_KTHREAD)) current_pcb->addr_limit = KERNEL_BASE_LINEAR_ADDR; // 将程序代码拷贝到对应的内存中 memcpy((void *)0x800000, user_level_function, 1024); @@ -247,29 +248,36 @@ void process_init() initial_mm.brk_start = 0; initial_mm.brk_end = memory_management_struct.kernel_end; - initial_mm.stack_start = *(ul *)phys_2_virt(&_stack_start); + // 向MSR寄存器组中的 IA32_SYSENTER_CS寄存器写入内核的代码段的地址 + wrmsr(0x174, KERNEL_CS); + // 向MSR寄存器组中的 IA32_SYSENTER_ESP寄存器写入内核进程的rbp(在syscall入口中会将rsp减去相应的数值) + wrmsr(0x175, current_pcb->thread->rbp); + + // 向MSR寄存器组中的 IA32_SYSENTER_EIP寄存器写入系统调用入口的地址。 + wrmsr(0x176, (ul)system_call); // 初始化进程和tss set_tss64((uint *)phys_2_virt(TSS64_Table), initial_thread.rbp, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1, initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7); initial_tss[0].rsp0 = initial_thread.rbp; + /* kdebug("initial_thread.rbp=%#018lx", initial_thread.rbp); kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1); kdebug("initial_tss[0].ist1=%#018lx", initial_tss[0].ist1); - +*/ // 初始化进程的循环链表 list_init(&initial_proc_union.pcb.list); - + current_pcb->flags=0; kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_FILES | CLONE_SIGNAL); // 初始化内核进程 initial_proc_union.pcb.state = PROC_RUNNING; // 获取新的进程的pcb - struct process_control_block *p = container_of(list_next(¤t_pcb->list), struct process_control_block, list); + // struct process_control_block *p = container_of(list_next(¤t_pcb->list), struct process_control_block, list); kdebug("Ready to switch..."); // 切换到新的内核线程 - switch_proc(current_pcb, p); + // switch_proc(current_pcb, p); } /** @@ -296,6 +304,8 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned // 将当前进程的pcb复制到新的pcb内 *tsk = *current_pcb; + kdebug("current_pcb->flags=%#010lx", current_pcb->flags); + // 将进程加入循环链表 list_init(&tsk->list); @@ -306,6 +316,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned // 将线程结构体放置在pcb的后面 struct thread_struct *thd = (struct thread_struct *)(tsk + 1); + memset(thd, 0, sizeof(struct thread_struct)); tsk->thread = thd; // 将寄存器信息存储到进程的内核栈空间的顶部 @@ -321,6 +332,10 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned // 若进程不是内核层的进程,则跳转到ret from system call if (!(tsk->flags & PF_KTHREAD)) thd->rip = regs->rip = (ul)ret_from_system_call; + else + kdebug("is kernel proc."); + + kdebug("ret_from_system_call=%#018lx", (ul)ret_from_system_call); tsk->state = PROC_RUNNING; diff --git a/kernel/smp/smp.c b/kernel/smp/smp.c index 856e0d2b..89246840 100644 --- a/kernel/smp/smp.c +++ b/kernel/smp/smp.c @@ -24,7 +24,7 @@ void smp_init() apic_get_ics(ACPI_ICS_TYPE_PROCESSOR_LOCAL_APIC, tmp_vaddr, &total_processor_num); - kdebug("processor num=%d", total_processor_num); + //kdebug("processor num=%d", total_processor_num); for (int i = 0; i < total_processor_num; ++i) proc_local_apic_structs[i] = (struct acpi_Processor_Local_APIC_Structure_t *)(tmp_vaddr[i]); @@ -56,10 +56,10 @@ void smp_init() set_tss_descriptor(10 + (i * 2), (void *)virt_2_phys(cpu_core_info[i].tss_vaddr)); set_tss64((uint *)cpu_core_info[i].tss_vaddr, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start); - kdebug("phys_2_virt(GDT_Table)=%#018lx",phys_2_virt(GDT_Table)); - kdebug("GDT Table %#018lx, \t %#018lx", *(ul *)(phys_2_virt(GDT_Table) + 10 + i * 2), *(ul *)(phys_2_virt(GDT_Table) + 10 + i * 2 + 1)); + //kdebug("phys_2_virt(GDT_Table)=%#018lx",phys_2_virt(GDT_Table)); + //kdebug("GDT Table %#018lx, \t %#018lx", *(ul *)(phys_2_virt(GDT_Table) + 10 + i * 2), *(ul *)(phys_2_virt(GDT_Table) + 10 + i * 2 + 1)); // kdebug("(cpu_core_info[i].tss_vaddr)=%#018lx", (cpu_core_info[i].tss_vaddr)); - kdebug("(cpu_core_info[i].stack_start)=%#018lx", (cpu_core_info[i].stack_start)); + //kdebug("(cpu_core_info[i].stack_start)=%#018lx", (cpu_core_info[i].stack_start)); // 连续发送两次start-up IPI ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->ACPI_ID); ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand, true, proc_local_apic_structs[i]->ACPI_ID); @@ -111,7 +111,7 @@ void smp_ap_start() load_TR(10 + current_starting_cpu * 2); sti(); - kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table)); + //kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table)); memset(current_pcb, 0, sizeof(struct process_control_block)); spin_unlock(&multi_core_starting_lock); while (1) // 这里要循环hlt,原因是当收到中断后,核心会被唤醒,处理完中断之后不会自动hlt diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 44ef911d..89082cf0 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -26,9 +26,11 @@ void syscall_init() wrmsr(0x174, KERNEL_CS); // 向MSR寄存器组中的 IA32_SYSENTER_ESP寄存器写入内核进程的rbp(在syscall入口中会将rsp减去相应的数值) wrmsr(0x175, current_pcb->thread->rbp); + // 向MSR寄存器组中的 IA32_SYSENTER_EIP寄存器写入系统调用入口的地址。 wrmsr(0x176, (ul)system_call); + } long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7) @@ -65,10 +67,11 @@ long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, u */ ul sys_printf(struct pt_regs *regs) { - while(1); - if(regs->r9 == 0 &®s->r10 == 0) - printk((char*)regs->r8); - else printk_color(regs->r9, regs->r10, (char*)regs->r8); + + //if(regs->r9 == 0 &®s->r10 == 0) + // printk((char*)regs->r8); + //else printk_color(regs->r9, regs->r10, (char*)regs->r8); + printk_color(BLACK,WHITE,(char *)regs->rdi); return 0; } \ No newline at end of file diff --git a/run.sh b/run.sh index db61c57f..4274c7c1 100644 --- a/run.sh +++ b/run.sh @@ -12,7 +12,7 @@ if [ ! "$1" == "--nobuild" ]; then make clean fi -IA32_USE_QEMU=0 +IA32_USE_QEMU=1 bochsrc="./bochsrc" ARCH="x86_64"