Procházet zdrojové kódy

改用int250作为系统调用

fslongjin před 2 roky
rodič
revize
2d7b2b7048

+ 15 - 9
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,加锁

+ 41 - 32
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();
+    }
 }
 
 /**

+ 13 - 5
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.");
 }

+ 2 - 2
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;
 }

+ 14 - 5
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

+ 2 - 0
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) =
     {

+ 2 - 0
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

+ 1 - 1
kernel/exception/softirq.c

@@ -52,7 +52,7 @@ void do_softirq()
         }
     }
 
-    cli();
+    
 }
 
 void softirq_init()

+ 3 - 3
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为用户自定义中断内部
 

+ 1 - 0
kernel/exception/trap.h

@@ -48,4 +48,5 @@ void machine_check();
 void SIMD_exception();
 void virtualization_exception();
 
+void syscall_int(); // 系统调用门
 void sys_vector_init();

+ 7 - 2
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);
 }
 
 //操作系统内核从这里开始执行

+ 36 - 19
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(&regs, 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(&current_pcb->list), struct process_control_block, list);
+    struct process_control_block *p = container_of(list_next(&current_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))

+ 14 - 10
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;
 }

+ 78 - 10
kernel/syscall/syscall.c

@@ -1,11 +1,14 @@
 #include "syscall.h"
 #include "../process/process.h"
+#include <exception/gate.h>
+#include <exception/irq.h>
 
 // 导出系统调用入口函数,定义在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 &&regs->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 &&regs->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");
 }

+ 8 - 7
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};