diff --git a/kernel/common/printk.c b/kernel/common/printk.c index c06dc95a..6e36f011 100644 --- a/kernel/common/printk.c +++ b/kernel/common/printk.c @@ -28,8 +28,7 @@ int printk_init(const int char_size_x, const int char_size_y) struct multiboot_tag_framebuffer_info_t info; int reserved; multiboot2_iter(multiboot2_get_Framebuffer_info, &info, &reserved); - - + pos.width = info.framebuffer_width; pos.height = info.framebuffer_height; @@ -37,7 +36,7 @@ int printk_init(const int char_size_x, const int char_size_y) pos.char_size_y = char_size_y; pos.max_x = calculate_max_charNum(pos.width, char_size_x); pos.max_y = calculate_max_charNum(pos.height, char_size_y); - + VBE_FB_phys_addr = (ul)info.framebuffer_addr; pos.FB_address = (uint *)0xffff800003000000; @@ -72,11 +71,11 @@ int printk_init(const int char_size_x, const int char_size_y) pos.x = 0; pos.y = 0; - + cls(); kdebug("width=%d\theight=%d", pos.width, pos.height); - + return 0; } @@ -440,10 +439,17 @@ static char *write_num(char *str, ul num, int base, int field_width, int precisi pad = (flags & PAD_ZERO) ? '0' : ' '; sign = 0; - if (flags & SIGN && num < 0) + + if (flags & SIGN) { - sign = '-'; - num = -num; + int64_t signed_num = (int64_t)num; + if (signed_num < 0) + { + sign = '-'; + num = -signed_num; + } + else + num = signed_num; } else { @@ -653,7 +659,7 @@ int printk_color(unsigned int FRcolor, unsigned int BKcolor, const char *fmt, .. * @param BKcolor 背景色 * @param ... 格式化字符串 */ - + /* if (get_rflags() & 0x200UL) spin_lock(&printk_lock); // 不是中断处理程序调用printk,加锁 diff --git a/kernel/driver/interrupt/apic/apic.c b/kernel/driver/interrupt/apic/apic.c index 7397a338..17868868 100644 --- a/kernel/driver/interrupt/apic/apic.c +++ b/kernel/driver/interrupt/apic/apic.c @@ -436,7 +436,6 @@ void apic_init() { RCBA_vaddr = 0; kwarn("Cannot get RCBA address. RCBA_phys=%#010lx", RCBA_phys); - } sti(); } @@ -448,50 +447,60 @@ void apic_init() */ void do_IRQ(struct pt_regs *rsp, ul number) { - switch (number & 0x80) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC + + if (number < 0x80) // 以0x80为界限,低于0x80的是外部中断控制器,高于0x80的是Local APIC + + // 外部中断控制器 { - case 0x00: // 外部中断控制器 - /* code */ + irq_desc_t *irq = &interrupt_desc[number - 32]; + + // 执行中断上半部处理程序 + if (irq->handler != NULL) + irq->handler(number, irq->parameter, rsp); + else + kwarn("Intr vector [%d] does not have a handler!"); + + // 向中断控制器发送应答消息 + if (irq->controller != NULL && irq->controller->ack != NULL) + irq->controller->ack(number); + else { - irq_desc_t *irq = &interrupt_desc[number - 32]; - // 执行中断上半部处理程序 - if (irq->handler != NULL) - irq->handler(number, irq->parameter, rsp); - else - kwarn("Intr vector [%d] does not have a handler!"); - - // 向中断控制器发送应答消息 - if (irq->controller != NULL && irq->controller->ack != NULL) - irq->controller->ack(number); - else - { - - // 向EOI寄存器写入0x00表示结束中断 - __asm__ __volatile__("movq $0x00, %%rdx \n\t" - "movq $0x00, %%rax \n\t" - "movq $0x80b, %%rcx \n\t" - "wrmsr \n\t" :: - : "memory"); - } + // 向EOI寄存器写入0x00表示结束中断 + __asm__ __volatile__("movq $0x00, %%rdx \n\t" + "movq $0x00, %%rax \n\t" + "movq $0x80b, %%rcx \n\t" + "wrmsr \n\t" :: + : "memory"); } - break; - case 0x80: + } + + else if (number >= 0x80 && number != 250) + + { printk_color(RED, BLACK, "SMP IPI [ %d ]\n", number); apic_local_apic_edge_ack(number); - default: + } + else if (number == 250) // 系统调用 + { + kdebug("receive syscall"); + kdebug("rflags=%#010lx", rsp->rflags); + } + + else + { + kwarn("do IRQ receive: %d", number); - break; } // 检测是否有未处理的软中断 if (softirq_status != 0) do_softirq(); - // 检测当前进程是否可被调度 - struct process_control_block *current_proc = get_current_pcb(); - if (current_proc->flags & PROC_NEED_SCHED) + if (current_pcb->flags & PROC_NEED_SCHED) + { sched_cfs(); + } } /** diff --git a/kernel/driver/timers/HPET/HPET.c b/kernel/driver/timers/HPET/HPET.c index 719e3f85..7e1811ad 100644 --- a/kernel/driver/timers/HPET/HPET.c +++ b/kernel/driver/timers/HPET/HPET.c @@ -50,6 +50,7 @@ hardware_intr_controller HPET_intr_controller = void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs) { + printk("(HPET)"); switch (param) { case 0: // 定时器0中断 @@ -73,7 +74,10 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs) } if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0) + { current_pcb->flags |= PROC_NEED_SCHED; + kdebug("need_sched. proc_jiffies=%ld", sched_cfs_ready_queue.cpu_exec_proc_jiffies); + } break; @@ -138,7 +142,7 @@ int HPET_init() // 由于这段内存与io/apic的映射在同一物理页内,因此不需要重复映射 HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + hpet_table->address; } - + // 读取计时精度并计算频率 uint64_t tmp; tmp = *(uint64_t *)(HPET_REG_BASE + GCAP_ID); @@ -152,18 +156,22 @@ int HPET_init() // 使用I/O APIC 的IRQ2接收hpet定时器0的中断 apic_make_rte_entry(&entry, 34, IO_APIC_FIXED, DEST_PHYSICAL, IDLE, POLARITY_HIGH, IRR_RESET, EDGE_TRIGGER, MASKED, 0); - *(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位 - io_mfence(); + + *(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0; + io_mfence(); *(uint64_t *)(HPET_REG_BASE + TIM0_CONF) = 0x004c; // 设置定时器0为周期定时,边沿触发,投递到IO APIC的2号引脚(这里有点绕,写的是8259的引脚号,但是因为禁用了8259,因此会被路由到IO APIC的2号引脚) io_mfence(); *(uint64_t *)(HPET_REG_BASE + TIM0_COMP) = HPET_freq; // 1s触发一次中断 io_mfence(); rtc_get_cmos_time(&rtc_now); - *(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0; + + + + kinfo("HPET Initialized."); + *(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位 io_mfence(); // 注册中断 irq_register(34, &entry, &HPET_handler, 0, &HPET_intr_controller, "HPET0"); - kinfo("HPET Initialized."); } \ No newline at end of file diff --git a/kernel/driver/timers/rtc/rtc.c b/kernel/driver/timers/rtc/rtc.c index 4ea048d6..219b0a5a 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 04ecbef5..c9fb489f 100644 --- a/kernel/exception/entry.S +++ b/kernel/exception/entry.S @@ -52,6 +52,7 @@ Restore_all: popq %rax addq $0x10, %rsp // 弹出变量FUNC和errcode + iretq ret_from_exception: @@ -106,9 +107,6 @@ Err_Code: ENTRY(system_call) // 由于sysenter指令会禁用中断,因此要在这里手动开启中断 - sti; - - subq $0x38, %rsp cld; @@ -146,6 +144,7 @@ ENTRY(system_call) // 从系统调用中返回 ENTRY(ret_from_system_call) + movq %rax, 0x80(%rsp) // 将当前rax的值先存到栈中rax的位置 @@ -168,9 +167,10 @@ ENTRY(ret_from_system_call) popq %rax movq %rax, %es popq %rax - addq $0x38, %rsp - .byte 0x48 + addq $0x38, %rsp + .byte 0x48 sysexit + // 0 #DE 除法错误 @@ -337,6 +337,15 @@ ENTRY(virtualization_exception) xchgq %rax, (%rsp) // 把FUNC的地址换入栈中 jmp Err_Code +/* +// 0x80 系统调用门 +ENTRY(syscall_int) + pushq $0 + pushq %rax + leaq do_syscall_int(%rip), %rax // 获取系统调用服务程序的地址 + xchgq %rax, (%rsp) // 把FUNC的地址换入栈中 + jmp Err_Code +*/ ENTRY(_stack_start) .quad initial_proc_union + 32768 \ No newline at end of file diff --git a/kernel/exception/irq.c b/kernel/exception/irq.c index 90a291e4..de24b43a 100644 --- a/kernel/exception/irq.c +++ b/kernel/exception/irq.c @@ -129,6 +129,8 @@ Build_IRQ(0xcf); Build_IRQ(0xd0); Build_IRQ(0xd1); +Build_IRQ(0xfa); // 系统调用入口 +void (*syscall_intr_table[1])(void) = {IRQ0xfainterrupt}; // 初始化IPI中断服务程序数组 void (*SMP_interrupt_table[SMP_IRQ_NUM])(void) = { diff --git a/kernel/exception/irq.h b/kernel/exception/irq.h index 89ffda40..33cab2f4 100644 --- a/kernel/exception/irq.h +++ b/kernel/exception/irq.h @@ -22,6 +22,8 @@ extern void do_IRQ(struct pt_regs *regs, ul number); extern void (*SMP_interrupt_table[SMP_IRQ_NUM])(void); +extern void (*syscall_intr_table[1])(void); + /* ========= 中断向量分配表 ========== 0~255 IDT diff --git a/kernel/exception/softirq.c b/kernel/exception/softirq.c index 6679b932..c60ba195 100644 --- a/kernel/exception/softirq.c +++ b/kernel/exception/softirq.c @@ -52,7 +52,7 @@ void do_softirq() } } - cli(); + } void softirq_init() diff --git a/kernel/exception/trap.c b/kernel/exception/trap.c index b3b1a374..890236a8 100644 --- a/kernel/exception/trap.c +++ b/kernel/exception/trap.c @@ -196,7 +196,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code) unsigned long cr2 = 0; __asm__ __volatile__("movq %%cr2, %0":"=r"(cr2)::"memory"); - + hlt(); kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx,RIP:%#018lx\n",error_code , regs->rsp , regs->rip); if(!(error_code & 0x01)) @@ -284,8 +284,6 @@ void do_virtualization_exception(struct pt_regs *regs, unsigned long error_code) void sys_vector_init() { - kdebug("do_divide_error=%#018lx", do_divide_error); - kdebug("&do_divide_error=%#018lx", &do_divide_error); set_trap_gate(0, 1, divide_error); set_trap_gate(1, 1, debug); set_intr_gate(2, 1, nmi); @@ -308,6 +306,8 @@ void sys_vector_init() set_trap_gate(19, 1, SIMD_exception); set_trap_gate(20, 1, virtualization_exception); // 中断号21-31由Intel保留,不能使用 + + // 32-255为用户自定义中断内部 diff --git a/kernel/exception/trap.h b/kernel/exception/trap.h index 00abac92..d4f98720 100644 --- a/kernel/exception/trap.h +++ b/kernel/exception/trap.h @@ -48,4 +48,5 @@ void machine_check(); void SIMD_exception(); void virtualization_exception(); +void syscall_int(); // 系统调用门 void sys_vector_init(); \ No newline at end of file diff --git a/kernel/main.c b/kernel/main.c index 51464a28..47bfc690 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -212,6 +212,7 @@ void system_initialize() syscall_init(); // 再初始化进程模块。顺序不能调转 sched_init(); + kdebug("sched_cfs_ready_queue.cpu_exec_proc_jiffies=%ld", sched_cfs_ready_queue.cpu_exec_proc_jiffies); timer_init(); smp_init(); @@ -223,10 +224,14 @@ void system_initialize() ahci_init(); // test_slab(); // test_mm(); + + process_init(); - cli(); + HPET_init(); - sti(); + + + while(1); } //操作系统内核从这里开始执行 diff --git a/kernel/process/process.c b/kernel/process/process.c index 4c4f90f2..59296e1d 100644 --- a/kernel/process/process.c +++ b/kernel/process/process.c @@ -32,12 +32,12 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc __asm__ __volatile__("movq %0, %%fs \n\t" ::"a"(next->thread->fs)); __asm__ __volatile__("movq %0, %%gs \n\t" ::"a"(next->thread->gs)); wrmsr(0x175, next->thread->rbp); - - kdebug("next=%#018lx", next); - kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1); - kdebug("prev->thread->rsp0:%#018lx\n", prev->thread->rbp); - kdebug("next->thread->rsp0:%#018lx\n", next->thread->rbp); - kdebug("next->thread->rip:%#018lx\n", next->thread->rip); + + // kdebug("next=%#018lx", next); + // kdebug("initial_tss[0].rsp1=%#018lx", initial_tss[0].rsp1); + // kdebug("prev->thread->rsp0:%#018lx\n", prev->thread->rbp); + // kdebug("next->thread->rsp0:%#018lx\n", next->thread->rbp); + // kdebug("next->thread->rip:%#018lx\n", next->thread->rip); } /** @@ -51,20 +51,35 @@ void user_level_function() // 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; // color_printk(RED,BLACK,"user_level_function task is running\n"); - while(1); + 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..."); + : "memory"); + */ + + for (int i = 0; i < 10; ++i) + { + long err_code; + ul addr = (ul)string; + __asm__ __volatile__( + "movq %2, %%r8 \n\t" + "int $250 \n\t" + : "=a"(err_code) + : "a"(SYS_PRINTF), "m"(addr) + : "memory", "r8"); + } + // enter_syscall_int(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0); + // kinfo("Return from syscall id 15..."); while (1) ; @@ -85,7 +100,7 @@ ul do_execve(struct pt_regs *regs) regs->ds = 0; regs->es = 0; - kdebug("do_execve is running..."); + // kdebug("do_execve is running..."); // 映射起始页面 // 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); @@ -114,7 +129,9 @@ ul do_execve(struct pt_regs *regs) current_pcb->addr_limit = KERNEL_BASE_LINEAR_ADDR; // 将程序代码拷贝到对应的内存中 memcpy((void *)0x800000, user_level_function, 1024); - kdebug("program copied!"); + + + // kdebug("program copied!"); return 0; } @@ -126,7 +143,7 @@ ul do_execve(struct pt_regs *regs) */ ul initial_kernel_thread(ul arg) { - kinfo("initial proc running...\targ:%#018lx", arg); + // kinfo("initial proc running...\targ:%#018lx", arg); struct pt_regs *regs; @@ -136,7 +153,7 @@ ul initial_kernel_thread(ul arg) // memset((void*)current_pcb->mm->pgd, 0, PAGE_4K_SIZE); regs = (struct pt_regs *)current_pcb->thread->rsp; - kdebug("current_pcb->thread->rsp=%#018lx", current_pcb->thread->rsp); + // kdebug("current_pcb->thread->rsp=%#018lx", current_pcb->thread->rsp); current_pcb->flags = 0; // 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数 这里的设计思路和switch_proc类似 __asm__ __volatile__("movq %1, %%rsp \n\t" @@ -226,8 +243,8 @@ int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigne // rip寄存器指向内核线程的引导程序 regs.rip = (ul)kernel_thread_func; - kdebug("kernel_thread_func=%#018lx", kernel_thread_func); - kdebug("&kernel_thread_func=%#018lx", &kernel_thread_func); + // kdebug("kernel_thread_func=%#018lx", kernel_thread_func); + // kdebug("&kernel_thread_func=%#018lx", &kernel_thread_func); return do_fork(®s, flags, 0, 0); } @@ -277,7 +294,7 @@ void process_init() 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..."); // 切换到新的内核线程 @@ -317,12 +334,13 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned tsk->priority = 2; ++(tsk->pid); tsk->state = PROC_UNINTERRUPTIBLE; + list_init(&tsk->list); + list_add(&initial_proc_union.pcb.list, &tsk->list); // 将线程结构体放置在pcb的后面 struct thread_struct *thd = (struct thread_struct *)(tsk + 1); memset(thd, 0, sizeof(struct thread_struct)); tsk->thread = thd; - // 将寄存器信息存储到进程的内核栈空间的顶部 memcpy((void *)((ul)tsk + STACK_SIZE - sizeof(struct pt_regs)), regs, sizeof(struct pt_regs)); @@ -333,7 +351,6 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned thd->fs = KERNEL_DS; thd->gs = KERNEL_DS; - kdebug("do_fork() thd->rsp=%#018lx", thd->rsp); // 若进程不是内核层的进程,则跳转到ret from system call if (!(tsk->flags & PF_KTHREAD)) diff --git a/kernel/sched/sched.c b/kernel/sched/sched.c index 4ffc88cb..837cdfcd 100644 --- a/kernel/sched/sched.c +++ b/kernel/sched/sched.c @@ -10,6 +10,7 @@ struct process_control_block *sched_cfs_dequeue() { if (list_empty(&sched_cfs_ready_queue.proc_queue.list)) { + kdebug("list empty"); return &initial_proc_union.pcb; } @@ -17,6 +18,7 @@ struct process_control_block *sched_cfs_dequeue() list_del(&proc->list); --sched_cfs_ready_queue.count; + kdebug("dequeued"); return proc; } @@ -30,7 +32,7 @@ void sched_cfs_enqueue(struct process_control_block *pcb) struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue.proc_queue.list), struct process_control_block, list); if (proc == &initial_proc_union.pcb) return; - if (!(list_empty(&sched_cfs_ready_queue.proc_queue.list))) + if ((list_empty(&sched_cfs_ready_queue.proc_queue.list)) == 0) { while (proc->virtual_runtime < pcb->virtual_runtime) { @@ -39,6 +41,7 @@ void sched_cfs_enqueue(struct process_control_block *pcb) } list_append(&proc->list, &pcb->list); ++sched_cfs_ready_queue.count; + kdebug("enqueued"); } /** @@ -57,7 +60,7 @@ void sched_cfs() if (current_pcb->state = PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理 sched_cfs_enqueue(current_pcb); - if (!sched_cfs_ready_queue.cpu_exec_proc_jiffies) + if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0) { switch (proc->priority) { @@ -67,7 +70,6 @@ void sched_cfs() break; case 2: default: - sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.count) << 2; break; } @@ -77,24 +79,26 @@ void sched_cfs() } else // 不进行切换 { - kdebug("not switch."); - sched_cfs_enqueue(current_pcb); + // kdebug("not switch."); + sched_cfs_enqueue(proc); - if (!sched_cfs_ready_queue.cpu_exec_proc_jiffies) + if (sched_cfs_ready_queue.cpu_exec_proc_jiffies <= 0) { switch (proc->priority) { case 0: case 1: - sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.cpu_exec_proc_jiffies; + sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.count; + //sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5; break; case 2: default: - sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.cpu_exec_proc_jiffies) << 2; + //sched_cfs_ready_queue.cpu_exec_proc_jiffies = 5; + + sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.count) << 2; break; } } - kdebug("hhhh"); } } @@ -107,6 +111,6 @@ void sched_init() memset(&sched_cfs_ready_queue, 0, sizeof(struct sched_queue_t)); list_init(&sched_cfs_ready_queue.proc_queue.list); sched_cfs_ready_queue.count = 1; // 因为存在IDLE进程,因此为1 - sched_cfs_ready_queue.cpu_exec_proc_jiffies = 10; + sched_cfs_ready_queue.cpu_exec_proc_jiffies = 15; sched_cfs_ready_queue.proc_queue.virtual_runtime = 0x7fffffffffffffff; } \ No newline at end of file diff --git a/kernel/syscall/syscall.c b/kernel/syscall/syscall.c index 89082cf0..b428d569 100644 --- a/kernel/syscall/syscall.c +++ b/kernel/syscall/syscall.c @@ -1,11 +1,14 @@ #include "syscall.h" #include "../process/process.h" +#include +#include // 导出系统调用入口函数,定义在entry.S中 extern void system_call(void); +extern void syscall_int(void); /** - * @brief 系统调用函数,从entry.S中跳转到这里 + * @brief sysenter的系统调用函数,从entry.S中跳转到这里 * * @param regs 3特权级下的寄存器值,rax存储系统调用号 * @return ul 对应的系统调用函数的地址 @@ -22,17 +25,19 @@ ul system_call_function(struct pt_regs *regs) void syscall_init() { kinfo("Initializing syscall..."); + /* // 向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); - +*/ + set_system_trap_gate(250, 0, syscall_intr_table[0]); // 系统调用门 } +/* long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7) { long err_code; @@ -53,12 +58,66 @@ long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, u : "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx"); return err_code; } +*/ + +ul enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7) +{ + long err_code; + __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"(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"); + return err_code; +} +/** + * @brief 通过中断进入系统调用 + * + * @param syscall_id + * @param arg0 + * @param arg1 + * @param arg2 + * @param arg3 + * @param arg4 + * @param arg5 + * @param arg6 + * @param arg7 + * @return long + */ +/* +long enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7) +{ + long err_code; + __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"(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"); + return err_code; +} +*/ /** * @brief 打印字符串的系统调用 - * + * * 当arg1和arg2均为0时,打印黑底白字,否则按照指定的前景色和背景色来打印 - * + * * @param regs 寄存器 * @param arg0 要打印的字符串 * @param arg1 前景色 @@ -67,11 +126,20 @@ long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, u */ ul sys_printf(struct pt_regs *regs) { - - //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); + + // 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->r8); return 0; +} + +// 系统调用的内核入口程序 +void do_syscall_int(struct pt_regs *regs, unsigned long error_code) +{ + + ul ret = system_call_table[regs->rax](regs); + __asm__ __volatile__("movq %0, %%rax \n\t" ::"r"(ret) + : "memory"); } \ No newline at end of file diff --git a/kernel/syscall/syscall.h b/kernel/syscall/syscall.h index 6164a2d4..8e9d68e7 100644 --- a/kernel/syscall/syscall.h +++ b/kernel/syscall/syscall.h @@ -9,8 +9,6 @@ #define ESYSCALL_NOT_EXISTS 1 - - typedef unsigned long (*system_call_t)(struct pt_regs *regs); extern void ret_from_system_call(void); // 导出从系统调用返回的函数(定义在entry.S) @@ -27,7 +25,8 @@ void syscall_init(); * @param syscall_id 系统调用id * @return long 错误码 */ -long enter_syscall(ul syscall_id,ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7); +long enter_syscall(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7); +ul enter_syscall_int(ul syscall_id, ul arg0, ul arg1, ul arg2, ul arg3, ul arg4, ul arg5, ul arg6, ul arg7); /** * @brief 系统调用不存在时的处理函数 @@ -43,9 +42,9 @@ ul system_call_not_exists(struct pt_regs *regs) /** * @brief 打印字符串的系统调用 - * + * * 当arg1和arg2均为0时,打印黑底白字,否则按照指定的前景色和背景色来打印 - * + * * @param regs 寄存器 * @param arg0 要打印的字符串 * @param arg1 前景色 @@ -54,9 +53,11 @@ ul system_call_not_exists(struct pt_regs *regs) */ ul sys_printf(struct pt_regs *regs); +// 系统调用的内核入口程序 +void do_syscall_int(struct pt_regs *regs, unsigned long error_code); + system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = { [0] = system_call_not_exists, [1] = sys_printf, - [2 ... MAX_SYSTEM_CALL_NUM - 1] = system_call_not_exists - }; + [2 ... MAX_SYSTEM_CALL_NUM - 1] = system_call_not_exists};