Bladeren bron

将内核定位到高地址(存在bug,中断时会访问低地址)

fslongjin 2 jaren geleden
bovenliggende
commit
f5f36aafd8

+ 1 - 1
bochsrc

@@ -19,7 +19,7 @@ ata1-master: type=cdrom, path="DragonOS.iso", status=inserted
 ata2: enabled=0
 ata3: enabled=0
 pci: enabled=1, chipset=i440fx
-vga: extension=vbe, update_freq=5
+vga: extension=vbe, update_freq=30
 
 cpu: count=1:2:1, ips=4000000, quantum=16, model=corei7_haswell_4770, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0, msrs="msrs.def"
 

+ 18 - 8
kernel/driver/disk/ahci/ahci.c

@@ -6,8 +6,8 @@ struct pci_device_structure_header_t *ahci_devs[MAX_AHCI_DEVICES];
 
 uint32_t count_ahci_devices = 0;
 
-uint64_t ahci_port_base_vaddr; // 端口映射base addr
-uint64_t ahci_port_base_phys_addr;  // 端口映射的物理基地址(ahci控制器的参数的地址都是物理地址)
+uint64_t ahci_port_base_vaddr;     // 端口映射base addr
+uint64_t ahci_port_base_phys_addr; // 端口映射的物理基地址(ahci控制器的参数的地址都是物理地址)
 
 static void start_cmd(HBA_PORT *port);
 static void stop_cmd(HBA_PORT *port);
@@ -27,12 +27,20 @@ void ahci_init()
 {
     kinfo("Initializing AHCI...");
     pci_get_device_structure(0x1, 0x6, ahci_devs, &count_ahci_devices);
-
+    
+    if (count_ahci_devices == 0)
+    {
+        kwarn("There is no AHCI device found on this computer!");
+        return;
+    }
     // 映射ABAR
-    mm_map_phys_addr(AHCI_MAPPING_BASE, ((ul)(((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5)) & PAGE_2M_MASK, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
-    // kdebug("ABAR mapped!");
+    kdebug("phys_2_virt(ahci_devs[0])= %#018lx",(ahci_devs[0]));
+    kdebug("((struct pci_device_structure_general_device_t *)phys_2_virt(ahci_devs[0])))->BAR5= %#018lx",((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5);
+    uint32_t bar5 = ((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5;
 
-    for (int i = 0; i < count_ahci_devices; ++i)
+    mm_map_phys_addr(AHCI_MAPPING_BASE, (ul)(bar5) & PAGE_2M_MASK, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
+    kdebug("ABAR mapped!");
+     for (int i = 0; i < count_ahci_devices; ++i)
     {
         // kdebug("[%d]  class_code=%d, sub_class=%d, progIF=%d, ABAR=%#010lx", i, ahci_devs[i]->Class_code, ahci_devs[i]->SubClass, ahci_devs[i]->ProgIF, ((struct pci_device_structure_general_device_t *)(ahci_devs[i]))->BAR5);
         //  赋值HBA_MEM结构体
@@ -40,16 +48,18 @@ void ahci_init()
         ahci_devices[i].hba_mem = (HBA_MEM *)(cal_HBA_MEM_VIRT_ADDR(i));
         kdebug("ahci_devices[i].hba_mem = %#018lx", (ul)ahci_devices[i].hba_mem);
     }
+
     // todo: 支持多个ahci控制器。
     ahci_port_base_vaddr = (uint64_t)kmalloc(1048576, 0);
     kdebug("ahci_port_base_vaddr=%#018lx", ahci_port_base_vaddr);
     ahci_probe_port(0);
     port_rebase(&ahci_devices[0].hba_mem->ports[0], 0);
-
+    
     // 初始化请求队列
     ahci_req_queue.in_service = NULL;
     list_init(&(ahci_req_queue.queue_list));
     ahci_req_queue.request_count = 0;
+    kinfo("AHCI initialized.");
 }
 
 // Check device type
@@ -186,7 +196,7 @@ static void port_rebase(HBA_PORT *port, int portno)
 
         memset((void *)phys_2_virt(cmdheader[i].ctba), 0, 256);
     }
-    
+
     start_cmd(port); // Start command engine
 }
 

+ 13 - 0
kernel/driver/interrupt/apic/apic.c

@@ -425,6 +425,19 @@ void apic_init()
 
     apic_io_apic_init();
 
+    // get RCBA address
+    io_out32(0xcf8, 0x8000f8f0);
+    uint32_t RCBA_phys = io_in32(0xcfc);
+
+    // 获取RCBA寄存器的地址
+    if (RCBA_phys > 0xfec00000 && RCBA_phys < 0xfee00000)
+        RCBA_vaddr = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + RCBA_phys;
+    else
+    {
+        RCBA_vaddr = 0;
+        kwarn("Cannot get RCBA address. RCBA_phys=%#010lx", RCBA_phys);
+        
+    }
     sti();
 }
 /**

+ 2 - 0
kernel/driver/interrupt/apic/apic.h

@@ -73,6 +73,8 @@
 // 分频配置寄存器(定时器专用)
 #define LOCAL_APIC_OFFSET_Local_APIC_CLKDIV 0x3e0
 
+uint32_t RCBA_vaddr = 0;// RCBA寄存器的虚拟地址
+
 /*
 
 1:	LVT	CMCI

+ 3 - 3
kernel/driver/pci/pci.c

@@ -447,7 +447,7 @@ void pci_init()
         {
             if (ptr->Status & 0x10)
             {
-                kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\tcap_pointer=%#010lx", i, ptr->Class_code, ptr->SubClass, ptr->Status, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer);
+                kinfo("[ pci device %d ] class code = %d\tsubclass=%d\tstatus=%#010lx\tcap_pointer=%#010lx\tbar5=%#010lx", i, ptr->Class_code, ptr->SubClass, ptr->Status, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer, ((struct pci_device_structure_general_device_t *)ptr)->BAR5);
                 uint32_t tmp = pci_read_config(ptr->bus, ptr->device, ptr->func, ((struct pci_device_structure_general_device_t *)ptr)->Capabilities_Pointer);
             }
             else
@@ -592,8 +592,8 @@ void pci_get_device_structure(uint8_t class_code, uint8_t sub_class, struct pci_
     {
         if ((ptr->Class_code == 1) && (ptr->SubClass == 6))
         {
-            kdebug("[%d]  class_code=%d, sub_class=%d, progIF=%d", i, ptr->Class_code, ptr->SubClass, ptr->ProgIF);
-
+            kdebug("[%d]  class_code=%d, sub_class=%d, progIF=%d, bar5=%#010lx", i, ptr->Class_code, ptr->SubClass, ptr->ProgIF,((struct pci_device_structure_general_device_t *)ptr)->BAR5);
+            
             res[*count_res] = ptr;
             ++(*count_res);
         }

+ 56 - 13
kernel/driver/timers/HPET/HPET.c

@@ -57,7 +57,7 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
         // 若当前时间比定时任务的时间间隔大,则进入中断下半部
         if (container_of(list_next(&timer_func_head.list), struct timer_func_list_t, list)->expire_jiffies <= timer_jiffies)
             set_softirq_status(TIMER_SIRQ);
-/*
+
         switch (current_pcb->priority)
         {
         case 0:
@@ -74,7 +74,7 @@ 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;
-*/
+
         break;
 
     default:
@@ -85,32 +85,72 @@ void HPET_handler(uint64_t number, uint64_t param, struct pt_regs *regs)
 
 int HPET_init()
 {
+    kinfo("Initializing HPET...");
     // 从acpi获取hpet结构体
     ul hpet_table_addr = 0;
     acpi_iter_SDT(acpi_get_HPET, &hpet_table_addr);
+
+    // ACPI表没有HPET,尝试读HPTC
     if (hpet_table_addr == 0)
     {
-        kerror("HPET Not Found On This Computer!");
-        return E_HPET_INIT_FAILED;
+        kwarn("ACPI: HPET Table Not Found On This Computer!");
+
+        if (RCBA_vaddr != 0)
+        {
+            kerror("NO HPET found on this computer!");
+            uint32_t *hptc = (uint32_t *)(RCBA_vaddr + 0x3404UL);
+            // enable HPET
+            io_mfence();
+            // 读取HPET配置寄存器地址
+            switch ((*hptc) & 0x3)
+            {
+            case 0:
+                HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + 0xfed00000;
+                break;
+            case 1:
+                HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + 0xfed01000;
+                break;
+            case 2:
+                HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + 0xfed02000;
+                break;
+            case 3:
+                HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + 0xfed03000;
+                break;
+            default:
+                break;
+            }
+            // enable HPET
+            *hptc = 0x80;
+            io_mfence();
+        }
+        else
+        {
+            // 没有RCBA寄存器,采用默认值
+            HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + 0xfed00000;
+            kwarn("There is no RCBA register on this computer, and HPET regs base use default value.");
+        }
     }
-    hpet_table = (struct acpi_HPET_description_table_t *)hpet_table_addr;
-    // 由于这段内存与io/apic的映射在同一物理页内,因此不需要重复映射
-    HPET_REG_BASE = SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + hpet_table->address;
+    else // ACPI表中有HPET表
+    {
+        hpet_table = (struct acpi_HPET_description_table_t *)hpet_table_addr;
+        kdebug("hpet_table_addr=%#018lx", hpet_table_addr);
+
+        // 由于这段内存与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);
     HPET_COUNTER_CLK_PERIOD = (tmp >> 32) & 0xffffffff;
     HPET_freq = 1.0 * 1e15 / HPET_COUNTER_CLK_PERIOD;
     HPET_NUM_TIM_CAP = (tmp >> 8) & 0x1f; // 读取计时器数量
-    double x = 1*2;
-    x = 1.0*3.65;
-    //kinfo("HPET CLK_PERIOD=%#03lx Frequency=%f", HPET_COUNTER_CLK_PERIOD, (double)HPET_freq);
-    
+
+    // kinfo("HPET CLK_PERIOD=%#03lx Frequency=%f", HPET_COUNTER_CLK_PERIOD, (double)HPET_freq);
+
     struct apic_IO_APIC_RTE_entry entry;
     // 使用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);
-    // 注册中断
-    irq_register(34, &entry, &HPET_handler, 0, &HPET_intr_controller, "HPET0");
 
     *(uint64_t *)(HPET_REG_BASE + GEN_CONF) = 3; // 置位旧设备中断路由兼容标志位、定时器组使能标志位
     io_mfence();
@@ -123,4 +163,7 @@ int HPET_init()
     rtc_get_cmos_time(&rtc_now);
     *(uint64_t *)(HPET_REG_BASE + MAIN_CNT) = 0;
     io_mfence();
+    // 注册中断
+    irq_register(34, &entry, &HPET_handler, 0, &HPET_intr_controller, "HPET0");
+    kinfo("HPET Initialized.");
 }

+ 12 - 4
kernel/exception/entry.S

@@ -1,4 +1,6 @@
 #include"../common/asm.h"
+.code64
+.section .text
 
 R15 =   0x00
 R14 =   0x08
@@ -54,6 +56,7 @@ Restore_all:
 
 ret_from_exception:
     // === 从中断中返回 ===
+    .code64
 ENTRY(ret_from_intr)
     jmp Restore_all
 
@@ -85,18 +88,18 @@ Err_Code:
     pushq	%r15
 
     cld
-
+    
     movq ERRCODE(%rsp), %rsi    // 把错误码装进rsi,作为函数的第二个参数
     movq FUNC(%rsp), %rdx
-
+    
     movq $0x10, %rdi    // 加载内核段的地址
     movq %rdi, %ds
     movq %rdi, %es
 
     movq %rsp, %rdi // 把栈指针装入rdi,作为函数的第一个的参数
 
-    callq *%rdx //调用服务程序 带*号表示调用的是绝对地址
-
+    
+    callq %rdx //调用服务程序 带*号表示调用的是绝对地址
     jmp ret_from_exception
 
 // 系统调用入口
@@ -174,6 +177,7 @@ ENTRY(ret_from_system_call)
 
 // 0 #DE 除法错误
 ENTRY(divide_error)
+    
     pushq $0    //由于#DE不会产生错误码,但是为了保持弹出结构的一致性,故也压入一个错误码0
     pushq %rax  // 先将rax入栈
     leaq do_divide_error(%rip), %rax    // 获取中断服务程序的地址
@@ -333,3 +337,7 @@ ENTRY(virtualization_exception)
     leaq do_virtualization_exception(%rip), %rax    // 获取中断服务程序的地址
     xchgq %rax, (%rsp)  // 把FUNC的地址换入栈中
     jmp Err_Code
+
+
+ENTRY(_stack_start)
+    .quad initial_proc_union + 32768

+ 37 - 21
kernel/exception/gate.h

@@ -10,6 +10,7 @@
 #define __GATE_H__
 
 #include "../common/kprint.h"
+#include <mm/mm.h>
 
 //描述符表的结构体
 struct desc_struct
@@ -27,6 +28,18 @@ extern struct desc_struct GDT_Table[]; // GDT_Table是head.S中的GDT_Table
 extern struct gate_struct IDT_Table[]; // IDT_Table是head.S中的IDT_Table
 extern unsigned int TSS64_Table[26];
 
+struct gdtr
+{
+    uint16_t size;
+    uint64_t gdt_vaddr;
+}__attribute__((packed));
+
+struct idtr
+{
+    uint16_t size;
+    uint64_t idt_vaddr;
+}__attribute__((packed));
+
 /**
  * @brief 初始化中段描述符表内的门描述符(每个16B)
  * @param gate_selector_addr IDT表项的地址
@@ -86,8 +99,10 @@ void set_tss_descriptor(unsigned int n, void *addr)
 {
 
     unsigned long limit = 103;
-    *(unsigned long *)(&GDT_Table[n]) = (limit & 0xffff) | (((unsigned long)addr & 0xffff) << 16) | ((((unsigned long)addr >> 16) & 0xff) << 32) | ((unsigned long)0x89 << 40) | ((limit >> 16 & 0xf) << 48) | (((unsigned long)addr >> 24 & 0xff) << 56); /////89 is attribute
-    *(unsigned long *)(&GDT_Table[n + 1]) = (((unsigned long)addr >> 32) & 0xffffffff) | 0;
+    
+    *(unsigned long *)(phys_2_virt(GDT_Table) + n) = (limit & 0xffff) | (((unsigned long)addr & 0xffff) << 16) | ((((unsigned long)addr >> 16) & 0xff) << 32) | ((unsigned long)0x89 << 40) | ((limit >> 16 & 0xf) << 48) | (((unsigned long)addr >> 24 & 0xff) << 56); /////89 is attribute
+    kdebug("1212");
+    *(unsigned long *)(phys_2_virt(GDT_Table) + n + 1) = (((unsigned long)addr >> 32) & 0xffffffff) | 0;
 }
 
 /**
@@ -110,8 +125,9 @@ void set_tss_descriptor(unsigned int n, void *addr)
  */
 void set_intr_gate(unsigned int n, unsigned char ist, void *addr)
 {
-    _set_gate((IDT_Table + n), 0x8E, ist, addr); // p=1,DPL=0, type=E
-    // set_gate((ul *)(IDT_Table + n), 0x8E, ist, (ul *)(addr)); // p=1,DPL=0, type=E
+    _set_gate(phys_2_virt(IDT_Table + n), 0x8E, ist, addr); // p=1,DPL=0, type=E
+    
+    //set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8E, ist, (ul *)(addr)); // p=1,DPL=0, type=E
 }
 
 /**
@@ -125,8 +141,8 @@ void set_trap_gate(unsigned int n, unsigned char ist, void *addr)
 {
     // kdebug("addr=%#018lx", (ul)(addr));
 
-    // set_gate((ul *)(IDT_Table + n), 0x8F, ist, (ul *)(addr)); // p=1,DPL=0, type=F
-    _set_gate((IDT_Table + n), 0x8F, ist, addr); // p=1,DPL=0, type=F
+    //set_gate((ul *)phys_2_virt(IDT_Table + n), 0x8F, ist, (ul *)(addr)); // p=1,DPL=0, type=F
+    _set_gate(phys_2_virt(IDT_Table + n), 0x8F, ist, addr); // p=1,DPL=0, type=F
 }
 
 /**
@@ -140,8 +156,8 @@ void set_system_trap_gate(unsigned int n, unsigned char ist, void *addr)
 {
     // kdebug("addr=%#018lx", (ul)(addr));
 
-    // set_gate((ul *)(IDT_Table + n), 0xEF, ist, (ul *)(addr)); // p=1,DPL=3, type=F
-    _set_gate((IDT_Table + n), 0xEF, ist, addr); // p=1,DPL=3, type=F
+    //set_gate((ul *)phys_2_virt(IDT_Table + n), 0xEF, ist, (ul *)(addr)); // p=1,DPL=3, type=F
+    _set_gate(phys_2_virt(IDT_Table + n), 0xEF, ist, addr); // p=1,DPL=3, type=F
 }
 
 /**
@@ -149,19 +165,19 @@ void set_system_trap_gate(unsigned int n, unsigned char ist, void *addr)
  *
  */
 
-void set_tss64(unsigned int * Table,unsigned long rsp0,unsigned long rsp1,unsigned long rsp2,unsigned long ist1,unsigned long ist2,unsigned long ist3,
-unsigned long ist4,unsigned long ist5,unsigned long ist6,unsigned long ist7)
+void set_tss64(unsigned int *Table, unsigned long rsp0, unsigned long rsp1, unsigned long rsp2, unsigned long ist1, unsigned long ist2, unsigned long ist3,
+               unsigned long ist4, unsigned long ist5, unsigned long ist6, unsigned long ist7)
 {
-	*(unsigned long *)(Table+1) = rsp0;
-	*(unsigned long *)(Table+3) = rsp1;
-	*(unsigned long *)(Table+5) = rsp2;
-
-	*(unsigned long *)(Table+9) = ist1;
-	*(unsigned long *)(Table+11) = ist2;
-	*(unsigned long *)(Table+13) = ist3;
-	*(unsigned long *)(Table+15) = ist4;
-	*(unsigned long *)(Table+17) = ist5;
-	*(unsigned long *)(Table+19) = ist6;
-	*(unsigned long *)(Table+21) = ist7;	
+    *(unsigned long *)(Table + 1) = rsp0;
+    *(unsigned long *)(Table + 3) = rsp1;
+    *(unsigned long *)(Table + 5) = rsp2;
+
+    *(unsigned long *)(Table + 9) = ist1;
+    *(unsigned long *)(Table + 11) = ist2;
+    *(unsigned long *)(Table + 13) = ist3;
+    *(unsigned long *)(Table + 15) = ist4;
+    *(unsigned long *)(Table + 17) = ist5;
+    *(unsigned long *)(Table + 19) = ist6;
+    *(unsigned long *)(Table + 21) = ist7;
 }
 #endif

+ 5 - 1
kernel/exception/irq.c

@@ -203,6 +203,10 @@ void irq_init()
 #else
 
     apic_init();
-    memset(interrupt_desc, 0, sizeof(irq_desc_t) * IRQ_NUM);
+    kdebug("interrupt_desc=%#018lx",(void*)interrupt_desc);
+    kdebug("irq_init()=%#018lx",(void*)irq_init);
+    
+    memset((void*)interrupt_desc, 0, sizeof(irq_desc_t) * IRQ_NUM);
+    
 #endif
 }

+ 22 - 21
kernel/exception/trap.c

@@ -58,7 +58,6 @@ void sys_vector_init()
 // 0 #DE 除法错误
 void do_divide_error(struct pt_regs *regs, unsigned long error_code)
 {
-    
     kerror("do_divide_error(0)");
     //kerror("do_divide_error(0),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\n", error_code, regs->rsp, regs->rip);
 
@@ -243,33 +242,35 @@ 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;
-    // 先保存cr2寄存器的值,避免由于再次触发页故障而丢失值
-    // cr2存储着触发异常的线性地址
-    __asm__ __volatile__("movq %%cr2, %0"
-                         : "=r"(cr2)::"memory");
 
-    kerror("do_page_fault(14),\tError Code:%#18lx,\tRSP:%#18lx,\tRIP:%#18lx\tCR2:%#18lx\n", error_code, regs->rsp, regs->rip, cr2);
+	__asm__	__volatile__("movq	%%cr2,	%0":"=r"(cr2)::"memory");
+   
+	kerror("do_page_fault(14),Error code :%#018lx,RSP:%#018lx,RIP:%#018lx\n",error_code , regs->rsp , regs->rip);
 
-    printk_color(YELLOW, BLACK, "Information:\n");
-    if (!(error_code & 0x01))
-        printk("Page does not exist.\n");
+	if(!(error_code & 0x01))
+		printk_color(RED,BLACK,"Page Not-Present,\t");
 
-    if (error_code & 0x02)
-        printk("Fault occurred during operation: writing\n");
-    else
-        printk("Fault occurred during operation: reading\n");
+	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("Fault in user level(3).\n");
-    else
-        printk("Fault in supervisor level(0,1,2).\n");
+	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 & 0x10)
+		printk_color(RED,BLACK,",Instruction fetch Cause Fault");
 
-    if (error_code & 0x08)
-        printk("Reserved bit caused the fault.\n");
+	printk_color(RED,BLACK,"\n");
 
-    if (error_code & 0x10)
-        printk("Fault occurred during fetching instruction.\n");
+	printk_color(RED,BLACK,"CR2:%#018lx\n",cr2);
 
     while (1)
         ;

+ 87 - 14
kernel/head.S

@@ -269,8 +269,17 @@ enter_head_from_ap_boot:
     hlt
     ret
 .code64
+.global ready_to_start_64
 ready_to_start_64:
 
+    mov $0x10, %ax
+    mov %ax, %ds
+    mov %ax, %es
+    mov %ax, %fs
+    mov %ax, %ss
+    mov $0x7e00, %esp
+
+    
     //6. 跳转到start64
     movq switch_to_start64(%rip), %rax
     pushq $0x08 //段选择子
@@ -281,19 +290,23 @@ switch_to_start64:
     .quad _start64
 
 
-
 .code64
+is_from_ap:
+    
+    hlt
+
 .global _start64
 .type _start64, @function
 .extern Start_Kernel
 ENTRY(_start64)
+
+
     // 初始化寄存器
     mov $0x10, %ax
     mov %ax, %ds
     mov %ax, %es
     mov %ax, %fs
     mov %ax, %ss
-
     mov $0x7e00, %esp
 
 // === 加载GDTR ====
@@ -302,13 +315,7 @@ ENTRY(_start64)
 // === 加载IDTR ====
     lidt IDT_POINTER(%rip)
     //lidt $IDT_POINTER
-    mov $0x10, %ax
-    mov %ax, %ds
-    mov %ax, %es
-    mov %ax, %fs
-    mov %ax, %ss
-    mov %ax, %gs
-    
+    movq GDT_POINTER(%rip), %r12
     movq _stack_start(%rip), %rsp
 
     // 分支,判断是否为apu
@@ -333,10 +340,13 @@ ENTRY(_start64)
 
 
 // ==== 加载CR3寄存器
+
 load_cr3:
+ // 分支,判断是否为apu
     movq $__PML4E, %rax //设置页目录基地址
+    
     movq %rax, %cr3
-
+    
     movq switch_seg(%rip), %rax
     // 由于ljmp和lcall在GAS中不受支持,因此我们需要先伪造函数调用现场,通过lret的方式,给它跳转过去。才能更新cs寄存器
     // 实在是太妙了!Amazing!
@@ -360,6 +370,21 @@ entry64:
 
     movq _stack_start(%rip), %rsp //rsp的地址
     
+    // 重新加载GDT和IDT,加载到高地址
+    leaq GDT_Table(%rip), %r8
+    leaq GDT_END(%rip), %r9
+
+    subq %r8, %r9
+    movq %r9, %r13    // GDT size
+
+    leaq IDT_Table(%rip), %r8
+    leaq IDT_END(%rip), %r9
+
+    subq %r8, %r9
+    movq %r9, %r12    // IDT size
+
+    lgdt GDT_POINTER64(%rip)
+    lidt IDT_POINTER64(%rip)
 
     // 分支,判断是否为apu
     movq	$0x1b,	%rcx		// 根据IA32_APIC_BASE.BSP[8]标志位判断处理器是否为apu
@@ -399,6 +424,10 @@ SetUp_TSS64:
     // == 设置64位的任务状态段表 ===
     //rdx保存高8B, rax保存低8B
     leaq TSS64_Table(%rip), %rdx
+
+    movq $0xffff800000000000, %r8
+    addq %r8, %rdx
+
     xorq %rax, %rax
     xorq %rcx, %rcx
 
@@ -440,23 +469,57 @@ SetUp_TSS64:
     or $(3 << 9), %ax		//set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
     movq %rax, %cr4
 
-    //call Start_Kernel
+    
+
     movq	go_to_kernel(%rip),	%rax		/* movq address */
 	pushq	$0x08
 	pushq	%rax
 
-    movq mb2_info, %r15
+    
 
+    movq mb2_info, %r15
     movq mb2_magic, %r14
+
+    
 	lretq
 
 go_to_kernel:
     .quad Start_Kernel
 
 start_smp:
+
+
+    //now enable SSE and the like
+    movq %cr0, %rax
+    and $0xFFFB, %ax		//clear coprocessor emulation CR0.EM
+    or $0x2, %ax			//set coprocessor monitoring  CR0.MP
+    movq %rax, %cr0
+    movq %cr4, %rax
+    or $(3 << 9), %ax		//set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
+    movq %rax, %cr4
+
+
 	movq	go_to_smp_kernel(%rip),	%rax		/* movq address */
 	pushq	$0x08
 	pushq	%rax
+
+/*
+    // 重新加载GDT和IDT,加载到高地址
+    leaq GDT_Table(%rip), %r8
+    leaq GDT_END(%rip), %r9
+
+    subq %r8, %r9
+    movq %r9, %r13    // GDT size
+
+    leaq IDT_Table(%rip), %r8
+    leaq IDT_END(%rip), %r9
+
+    subq %r8, %r9
+    movq %r9, %r12    // IDT size
+
+    lgdt GDT_POINTER64(%rip)
+    lidt IDT_POINTER64(%rip)
+*/
 	lretq
 
 go_to_smp_kernel:
@@ -484,10 +547,10 @@ ENTRY(_stack_start)
 
 // 初始化页表
 .align 0x1000 //设置为4k对齐
-.org 0x1000 //设置页表位置为内核执行头程序的0x1000处
+//.org 0x1000 //设置页表位置为内核执行头程序的0x1000处
 
 __PML4E:
-    .quad 0x103003 // 用户访问,可读写,已存在, 地址在31~12位
+    .quad 0x103007 // 用户访问,可读写,已存在, 地址在31~12位
     .fill	255,8,0
 	.quad 0x103003
 	.fill	255,8,0
@@ -575,6 +638,11 @@ GDT_POINTER:
 GDT_LIMIT: .word GDT_END - GDT_Table - 1 // GDT的大小
 GDT_BASE: .quad GDT_Table
 
+.global GDT_POINTER64
+GDT_POINTER64:
+GDT_LIMIT64: .word GDT_END - GDT_Table - 1 // GDT的大小
+GDT_BASE64: .quad GDT_Table + 0xffff800000000000
+
 // IDT 表
 .global IDT_Table
 
@@ -587,6 +655,11 @@ IDT_POINTER:
 IDT_LIMIT: .word IDT_END - IDT_Table - 1
 IDT_BASE: .quad IDT_Table
 
+.global IDT_POINTER64
+IDT_POINTER64:
+IDT_LIMIT64: .word IDT_END - IDT_Table - 1
+IDT_BASE64: .quad IDT_Table + 0xffff800000000000
+
 // 64位的TSS表
 .global TSS64_Table
 

+ 12 - 5
kernel/link.lds

@@ -20,7 +20,8 @@ SECTIONS
 	}
 	
 	. += KERNEL_VMA;
-	.text : AT(ADDR(.text) - KERNEL_VMA)
+	text_start_pa = .;
+	.text (text_start_pa): AT(text_start_pa - KERNEL_VMA)
 	{
 		_text = .;
 		
@@ -28,14 +29,16 @@ SECTIONS
 		_etext = .;
 	}
 	. = ALIGN(8);
-	.data : AT(ADDR(.data) - KERNEL_VMA)
+	data_start_pa = .;
+	.data (data_start_pa): AT(data_start_pa - KERNEL_VMA)
 	{
 		_data = .;
 		*(.data)
 		
 		_edata = .;
 	}
-	.rodata : AT(ADDR(.rodata) - KERNEL_VMA)
+	rodata_start_pa = .;
+	.rodata (rodata_start_pa): AT(rodata_start_pa - KERNEL_VMA)
 	{
 		_rodata = .;	
 		*(.rodata)
@@ -43,9 +46,13 @@ SECTIONS
 	}
 
 	. = ALIGN(32768);
-	.data.init_proc_union : AT(ADDR(.data.init_proc_union) - KERNEL_VMA)
+
+	init_proc_union_start_pa = .;
+	.data.init_proc_union (init_proc_union_start_pa): AT(init_proc_union_start_pa - KERNEL_VMA)
 	 { *(.data.init_proc_union) }
-	.bss : AT(ADDR(.bss) - KERNEL_VMA)
+
+	 bss_start_pa = .;
+	.bss (bss_start_pa): AT(bss_start_pa - KERNEL_VMA)
 	{
 		_bss = .;
 		*(.bss)

+ 60 - 18
kernel/main.c

@@ -29,6 +29,7 @@
 #include <driver/timers/timer.h>
 
 unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址
+ul bsp_idt_size, bsp_gdt_size;
 
 struct memory_desc memory_management_struct = {{0}, 0};
 // struct Global_Memory_Descriptor memory_management_struct = {{0}, 0};
@@ -143,44 +144,77 @@ void test_slab()
 
     kinfo("SLAB test completed!");
 }
+struct gdtr gdtp;
+struct idtr idtp;
+void reload_gdt()
+{
+    
+    gdtp.size = bsp_gdt_size-1;
+    gdtp.gdt_vaddr = (ul)phys_2_virt((ul)&GDT_Table);
+    //kdebug("gdtvaddr=%#018lx", p.gdt_vaddr);
+    //kdebug("gdt size=%d", p.size);
+
+    asm volatile("lgdt (%0)   \n\t" ::"r"(&gdtp)
+                 : "memory");
+}
+
+void reload_idt()
+{
+    
+    idtp.size = bsp_idt_size-1;
+    idtp.idt_vaddr = (ul)phys_2_virt((ul)&IDT_Table);
+    //kdebug("gdtvaddr=%#018lx", p.gdt_vaddr);
+    //kdebug("gdt size=%d", p.size);
+
+    asm volatile("lidt (%0)   \n\t" ::"r"(&idtp)
+                 : "memory");
+}
+
 // 初始化系统各模块
 void system_initialize()
 {
 
     // 初始化printk
-    
+
     printk_init(8, 16);
     kinfo("Kernel Starting...");
+    // 重新加载gdt和idt
 
+    ul tss_item_addr = (ul)phys_2_virt(0x7c00);
+    kdebug("TSS64_Table=%#018lx", (void *)TSS64_Table);
+    kdebug("&TSS64_Table=%#018lx", (void *)&TSS64_Table);
+    kdebug("_stack_start=%#018lx", _stack_start);
     load_TR(10); // 加载TR寄存器
-    ul tss_item_addr = 0x7c00;
-
-    set_tss64(TSS64_Table, _stack_start, _stack_start, _stack_start, tss_item_addr,
+    set_tss64((uint *)phys_2_virt(TSS64_Table), _stack_start, _stack_start, _stack_start, tss_item_addr,
               tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr);
 
     cpu_core_info[0].stack_start = _stack_start;
-    cpu_core_info[0].tss_vaddr = &TSS64_Table;
-
+    cpu_core_info[0].tss_vaddr = (uint64_t)phys_2_virt((uint64_t)TSS64_Table);
+    kdebug("cpu_core_info[0].tss_vaddr=%#018lx", cpu_core_info[0].tss_vaddr);
+    kdebug("cpu_core_info[0].stack_start%#018lx", cpu_core_info[0].stack_start);
+    
+    
     // 初始化中断描述符表
     sys_vector_init();
 
     //  初始化内存管理单元
     mm_init();
-
+    
     acpi_init();
 
-    for (int i = 0; i < 1e7; ++i)
-        ;
     // 初始化中断模块
+    sched_init();
     irq_init();
+
     softirq_init();
-    timer_init();
-    HPET_init();
-    smp_init();
 
     // 先初始化系统调用模块
     syscall_init();
+    //  再初始化进程模块。顺序不能调转
+    sched_init();
+    timer_init();
 
+    smp_init();
     cpu_init();
     // ps2_keyboard_init();
     // ps2_mouse_init();
@@ -189,10 +223,10 @@ void system_initialize()
     ahci_init();
     // test_slab();
     // test_mm();
-
-    //  再初始化进程模块。顺序不能调转
-    // sched_init();
-    // process_init();
+    process_init();
+    cli();
+    HPET_init();
+    sti();
 }
 
 //操作系统内核从这里开始执行
@@ -203,12 +237,20 @@ void Start_Kernel(void)
     uint64_t mb2_info, mb2_magic;
     __asm__ __volatile__("movq %%r15, %0    \n\t"
                          "movq %%r14, %1  \n\t"
-                         : "=r"(mb2_info), "=r"(mb2_magic)::"memory");
+                         "movq %%r13, %2  \n\t"
+                         "movq %%r12, %3  \n\t"
+                         : "=r"(mb2_info), "=r"(mb2_magic), "=r"(bsp_gdt_size), "=r"(bsp_idt_size)::"memory");
+    reload_gdt();
+    reload_idt();
+    
+
     mb2_info &= 0xffffffff;
     mb2_magic &= 0xffffffff;
 
     multiboot2_magic = mb2_magic;
-    multiboot2_boot_info_addr = mb2_info+PAGE_OFFSET;
+    multiboot2_boot_info_addr = mb2_info + PAGE_OFFSET;
+
+    
     system_initialize();
 
     /*

+ 67 - 17
kernel/mm/mm.c

@@ -6,7 +6,7 @@
 
 ul Total_Memory = 0;
 ul total_2M_pages = 0;
-static ul root_page_table_phys_addr=0;  // 内核层根页表的物理地址
+static ul root_page_table_phys_addr = 0; // 内核层根页表的物理地址
 void mm_init()
 {
     kinfo("Initializing memory management unit...");
@@ -190,22 +190,16 @@ void mm_init()
     }
 
     global_CR3 = get_CR3();
-    //root_page_table_phys_addr = global_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("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!");
 
-    /*
-    kinfo("Cleaning page table remapping at 0x0000");
-    for (int i = 0; i < 10; ++i)
-        *(phys_2_virt(global_CR3) + i) = 0UL;
-    kinfo("Successfully cleaned page table remapping!\n");
-    */
-
     flush_tlb();
     // 初始化slab内存池
     slab_init();
@@ -424,8 +418,9 @@ void free_pages(struct Page *page, int number)
  */
 void page_table_init()
 {
-    kinfo("Initializing page table...");
+    kinfo("Re-Initializing page table...");
     global_CR3 = get_CR3();
+    /*
     // 由于CR3寄存器的[11..0]位是PCID标志位,因此将低12位置0后,就是PML4页表的基地址
     ul *pml4_addr = (ul *)((ul)phys_2_virt((ul)global_CR3 & (~0xfffUL)));
     kdebug("PML4 addr=%#018lx *pml4=%#018lx", pml4_addr, *pml4_addr);
@@ -435,7 +430,7 @@ void page_table_init()
 
     ul *pd_addr = phys_2_virt(*pdpt_addr & (~0xfffUL));
     kdebug("pd addr=%#018lx *pd=%#018lx", pd_addr, *pd_addr);
-
+*/
     ul *tmp_addr;
     for (int i = 0; i < memory_management_struct.count_zones; ++i)
     {
@@ -447,6 +442,8 @@ 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);
+            /*
             // 计算出PML4页表中的页表项的地址
             tmp_addr = (ul *)((ul)pml4_addr + ((((ul)phys_2_virt(p->addr_phys)) >> PAGE_GDT_SHIFT) & 0x1ff) * 8);
 
@@ -472,7 +469,7 @@ void page_table_init()
 
             // 填入pd页表的页表项,映射2MB物理页
             set_pdt(tmp_addr, mk_pdt(virt_2_phys(p->addr_phys), PAGE_KERNEL_PAGE));
-
+            */
             // 测试
             if (j % 50 == 0)
                 kdebug("pd_addr=%#018lx, *pd_addr=%#018lx", tmp_addr, *tmp_addr);
@@ -569,27 +566,77 @@ void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flag
     flush_tlb();
 }
 
+void mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul flags)
+{
+    global_CR3 = get_CR3();
+
+    // 计算线性地址对应的pml4页表项的地址
+    ul *tmp = phys_2_virt((ul *)((ul)global_CR3 & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff));
+    if (*tmp == 0)
+    {
+        ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
+        set_pml4t(tmp, mk_pml4t(virt_2_phys(virt_addr), PAGE_USER_PGT));
+    }
+    else
+        kdebug("*tmp != 0!!!    \t tmp = %#018lx\t *tmp = %#018lx",tmp, *tmp);
+
+    tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff));
+
+    if (*tmp == 0)
+    {
+        ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
+        set_pdpt(tmp, mk_pdpt(virt_2_phys(virt_addr), PAGE_USER_DIR));
+    }
+    else
+        kdebug("*tmp != 0!!!    \t tmp = %#018lx\t *tmp = %#018lx",tmp, *tmp);
+
+    ul *tmp1;
+    // 初始化2M物理页
+    for (ul i = 0; i < (length); i += PAGE_2M_SIZE)
+    {
+        // 计算当前2M物理页对应的pdt的页表项的物理地址
+        tmp1 = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff));
+
+        // 页面写穿,禁止缓存
+        set_pdt(tmp1, mk_pdt((ul)phys_addr_start + i, flags | PAGE_USER_PAGE));
+        kdebug("mk_pdt((ul)phys_addr_start + i, flags | PAGE_USER_PAGE) = %#018lx",mk_pdt((ul)phys_addr_start + i, flags | PAGE_USER_PAGE));
+    }
+
+    flush_tlb();
+}
+
 /**
  * @brief 将将物理地址填写到进程的页表的函数
  *
- * @param proc_page_table_addr 进程的页表的虚拟基地址
+ * @param proc_page_table_addr 页表的基地址
+ * @param is_phys 页表的基地址是否为物理地址
  * @param virt_addr_start 要映射到的虚拟地址的起始位置
  * @param phys_addr_start 物理地址的起始位置
  * @param length 要映射的区域的长度(字节)
  * @param user 用户态是否可访问
  */
-void mm_map_proc_page_table(ul *proc_page_table_addr, 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)
 {
 
     // 计算线性地址对应的pml4页表项的地址
-    ul *tmp = (ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff);
+    ul *tmp;
+    if (is_phys)
+        tmp = phys_2_virt((ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff));
+    else
+        tmp = (ul *)((ul)proc_page_table_addr & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff);
+
+    kdebug("tmp = %#018lx", tmp);
     if (*tmp == 0)
     {
         ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
         set_pml4t(tmp, mk_pml4t(virt_2_phys(virt_addr), (user ? PAGE_USER_PGT : PAGE_KERNEL_PGT)));
     }
+    kdebug("*tmp = %#018lx", *tmp);
 
-    tmp = (ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff);
+    if (is_phys)
+        tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff));
+    else
+        tmp = (ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff);
 
     if (*tmp == 0)
     {
@@ -602,7 +649,10 @@ void mm_map_proc_page_table(ul *proc_page_table_addr, ul virt_addr_start, ul phy
     for (ul i = 0; i < (length); i += PAGE_2M_SIZE)
     {
         // 计算当前2M物理页对应的pdt的页表项的物理地址
-        tmp1 = ((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff));
+        if (is_phys)
+            tmp1 = phys_2_virt(((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff)));
+        else
+            tmp1 = ((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff));
 
         // 页面写穿,禁止缓存
         set_pdt(tmp1, mk_pdt((ul)phys_addr_start + i, flags | (user ? PAGE_USER_PAGE : PAGE_KERNEL_PAGE)));

+ 7 - 3
kernel/mm/mm.h

@@ -8,7 +8,7 @@
 
 // 内核层的起始地址
 #define PAGE_OFFSET ((unsigned long)0xffff800000000000)
-#define KERNEL_BASE_PHYS_ADDR ((unsigned long)0xffff800000000000)
+#define KERNEL_BASE_LINEAR_ADDR ((unsigned long)0xffff800000000000)
 
 #define PAGE_4K_SHIFT 12
 #define PAGE_2M_SHIFT 21
@@ -365,10 +365,14 @@ void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flag
 /**
  * @brief 将将物理地址填写到进程的页表的函数
  *
- * @param proc_page_table_addr 进程的页表的虚拟基地址
+ * @param proc_page_table_addr 页表的基地址
+ * @param is_phys 页表的基地址是否为物理地址
  * @param virt_addr_start 要映射到的虚拟地址的起始位置
  * @param phys_addr_start 物理地址的起始位置
  * @param length 要映射的区域的长度(字节)
  * @param user 用户态是否可访问
  */
-void mm_map_proc_page_table(ul *proc_page_table_addr, 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);
+
+
+void mm_map_phys_addr_user(ul virt_addr_start, ul phys_addr_start, ul length, ul flags);

+ 65 - 17
kernel/process/process.c

@@ -5,6 +5,8 @@
 #include "../common/kprint.h"
 #include "../syscall/syscall.h"
 #include "../syscall/syscall_num.h"
+#include <mm/slab.h>
+#include <sched/sched.h>
 
 /**
  * @brief 切换进程
@@ -18,16 +20,26 @@
 void __switch_to(struct process_control_block *prev, struct process_control_block *next)
 {
     initial_tss[0].rsp0 = next->thread->rbp;
-    set_tss64(TSS64_Table, initial_tss[0].rsp0, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1,
+    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));
+                         : "=a"(prev->thread->fs)::"memory");
     __asm__ __volatile__("movq	%%gs,	%0 \n\t"
-                         : "=a"(prev->thread->gs));
+                         : "=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,	%%fs \n\t" ::"a"(next->thread->fs));
-    __asm__ __volatile__("movq	%0,	%%gs \n\t" ::"a"(next->thread->gs));
+    __asm__ __volatile__("movq	%0,	%%gs \n\t" ::"a"(next->thread->gs)
+                         : "memory");
+    kdebug("prev->thread->rsp0:%#018lx\n", prev->thread->rbp);
+    kdebug("next->thread->rsp0:%#018lx\n", next->thread->rbp);
 }
 
 /**
@@ -36,9 +48,10 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
  */
 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);
+    // 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);
+    hlt();
     enter_syscall(SYS_PRINTF, (ul) "test_sys_printf\n", 0, 0, 0, 0, 0, 0, 0);
 
     kinfo("Return from syscall id 15...");
@@ -63,8 +76,34 @@ ul do_execve(struct pt_regs *regs)
     regs->es = 0;
 
     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);
+
+    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);
+    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));
+    virtual = kmalloc(PAGE_4K_SIZE, 0);
+    set_pdpt(tmp, mk_pdpt(virt_2_phys(virtual), PAGE_USER_DIR));
+
+    tmp = phys_2_virt((unsigned long *)(*tmp & (~0xfffUL)) + ((addr >> PAGE_2M_SHIFT) & 0x1ff));
+    struct Page *p = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED);
+    set_pdt(tmp, mk_pdt(p->addr_phys, PAGE_USER_PAGE));
+
+    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))
+        current_pcb->addr_limit = KERNEL_BASE_LINEAR_ADDR;
     // 将程序代码拷贝到对应的内存中
     memcpy((void *)0x800000, user_level_function, 1024);
+    kdebug("program copied!");
     return 0;
 }
 
@@ -82,9 +121,11 @@ ul initial_kernel_thread(ul arg)
 
     current_pcb->thread->rip = (ul)ret_from_system_call;
     current_pcb->thread->rsp = (ul)current_pcb + STACK_SIZE - sizeof(struct pt_regs);
+    // current_pcb->mm->pgd = kmalloc(PAGE_4K_SIZE, 0);
+    // memset((void*)current_pcb->mm->pgd, 0, PAGE_4K_SIZE);
 
     regs = (struct pt_regs *)current_pcb->thread->rsp;
-
+    current_pcb->flags = 0;
     // 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数  这里的设计思路和switch_proc类似
     __asm__ __volatile__("movq %1, %%rsp   \n\t"
                          "pushq %2    \n\t"
@@ -101,7 +142,7 @@ ul initial_kernel_thread(ul arg)
  * @param code 返回码
  * @return ul
  */
-ul do_exit(ul code)
+ul process_thread_do_exit(ul code)
 {
     kinfo("thread_exiting..., code is %#018lx.", code);
     while (1)
@@ -142,7 +183,7 @@ __asm__(
     "	movq	%rdx,	%rdi	\n\t"
     "	callq	*%rbx		\n\t"
     "	movq	%rax,	%rdi	\n\t"
-    "	callq	do_exit		\n\t");
+    "	callq	process_thread_do_exit		\n\t");
 
 /**
  * @brief 初始化内核进程
@@ -183,7 +224,7 @@ int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigne
  */
 void process_init()
 {
-
+    kinfo("Initializing process...");
     initial_mm.pgd = (pml4t_t *)global_CR3;
 
     initial_mm.code_addr_start = memory_management_struct.kernel_code_start;
@@ -198,12 +239,16 @@ void process_init()
     initial_mm.brk_start = 0;
     initial_mm.brk_end = memory_management_struct.kernel_end;
 
-    initial_mm.stack_start = _stack_start;
+
+    initial_mm.stack_start = *(ul *)phys_2_virt(&_stack_start);
 
     // 初始化进程和tss
-    set_tss64(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);
+    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);
@@ -214,6 +259,7 @@ void process_init()
     // 获取新的进程的pcb
     struct process_control_block *p = container_of(list_next(&current_pcb->list), struct process_control_block, list);
 
+    kdebug("Ready to switch...");
     // 切换到新的内核线程
     switch_proc(current_pcb, p);
 }
@@ -237,7 +283,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
 
     tsk = (struct process_control_block *)phys_2_virt(pp->addr_phys);
 
-    memset(tsk, 0, sizeof(*tsk));
+    memset(tsk, 0, sizeof(struct process_control_block));
 
     // 将当前进程的pcb复制到新的pcb内
     *tsk = *current_pcb;
@@ -245,8 +291,8 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
     // 将进程加入循环链表
     list_init(&tsk->list);
 
-    list_add(&initial_proc_union.pcb.list, &tsk->list);
-
+    // list_add(&initial_proc_union.pcb.list, &tsk->list);
+    tsk->priority = 2;
     ++(tsk->pid);
     tsk->state = PROC_UNINTERRUPTIBLE;
 
@@ -270,5 +316,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
 
     tsk->state = PROC_RUNNING;
 
+    sched_cfs_enqueue(tsk);
+
     return 0;
 }

+ 18 - 27
kernel/process/process.h

@@ -17,8 +17,7 @@
 #include "ptrace.h"
 
 extern unsigned long _stack_start; // 导出内核层栈基地址(定义在head.S)
-extern void ret_from_intr(void);	   // 导出从中断返回的函数(定义在entry.S)
-
+extern void ret_from_intr(void);   // 导出从中断返回的函数(定义在entry.S)
 
 // 进程的内核栈大小 32K
 #define STACK_SIZE 32768
@@ -86,45 +85,38 @@ struct thread_struct
 	ul err_code;
 };
 
+// ========= pcb->flags =========
 // 进程标志位
-#define PF_KTHREAD (1 << 0)
-
+#define PF_KTHREAD (1UL << 0)
+#define PROC_NEED_SCHED (1UL << 1) // 进程需要被调度
 /**
  * @brief 进程控制块
  *
  */
 struct process_control_block
 {
-	// 连接各个pcb的双向链表
-	struct List list;
-
 	// 进程的状态
 	volatile long state;
 	// 进程标志:进程、线程、内核线程
 	unsigned long flags;
-
+	long signal;
 	// 内存空间分布结构体, 记录内存页表和程序段信息
 	struct mm_struct *mm;
 
 	// 进程切换时保存的状态信息
 	struct thread_struct *thread;
 
+	// 连接各个pcb的双向链表
+	struct List list;
+
 	// 地址空间范围
 	// 用户空间: 0x0000 0000 0000 0000 ~ 0x0000 7fff ffff ffff
 	// 内核空间: 0xffff 8000 0000 0000 ~ 0xffff ffff ffff ffff
-	ul addr_limit;
+	uint64_t addr_limit;
 
-	// 进程id
 	long pid;
-
-	// 可用时间片
-	long counter;
-
-	// 信号
-	long signal;
-
-	// 优先级
-	long priority;
+	long priority;		  // 优先级
+	long virtual_runtime; // 虚拟运行时间
 };
 
 // 将进程的pcb和内核栈融合到一起,8字节对齐
@@ -146,9 +138,9 @@ struct thread_struct initial_thread;
 		.thread = &initial_thread,        \
 		.addr_limit = 0xffff800000000000, \
 		.pid = 0,                         \
-		.counter = 1,                     \
+		.virtual_runtime = 0,             \
 		.signal = 0,                      \
-		.priority = 0                     \
+		.priority = 2                     \
 	}
 
 // 初始化 初始进程的union ,并将其链接到.data.init_proc段内
@@ -224,18 +216,17 @@ struct process_control_block *get_current_pcb()
 	return current;
 };
 
-
 #define current_pcb get_current_pcb()
 
 #define GET_CURRENT_PCB    \
 	"movq %rsp, %rbx \n\t" \
 	"andq $-32768, %rbx\n\t"
 
-/**
- * @brief 切换进程上下文
- * 先把rbp和rax保存到栈中,然后将rsp和rip保存到prev的thread结构体中
- * 然后调用__switch_to切换栈,配置其他信息,最后恢复下一个进程的rax rbp。
- */
+	/**
+	 * @brief 切换进程上下文
+	 * 先把rbp和rax保存到栈中,然后将rsp和rip保存到prev的thread结构体中
+	 * 然后调用__switch_to切换栈,配置其他信息,最后恢复下一个进程的rax rbp。
+	 */
 
 #define switch_proc(prev, next)                                                                     \
 	do                                                                                              \

+ 112 - 0
kernel/sched/sched.c

@@ -0,0 +1,112 @@
+#include "sched.h"
+#include <common/kprint.h>
+
+/**
+ * @brief 从就绪队列中取出PCB
+ *
+ * @return struct process_control_block*
+ */
+struct process_control_block *sched_cfs_dequeue()
+{
+    if (list_empty(&sched_cfs_ready_queue.proc_queue.list))
+    {
+        return &initial_proc_union.pcb;
+    }
+
+    struct process_control_block *proc = container_of(list_next(&sched_cfs_ready_queue.proc_queue.list), struct process_control_block, list);
+
+    list_del(&proc->list);
+    --sched_cfs_ready_queue.count;
+    return proc;
+}
+
+/**
+ * @brief 将PCB加入就绪队列
+ *
+ * @param pcb
+ */
+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)))
+    {
+        while (proc->virtual_runtime < pcb->virtual_runtime)
+        {
+            proc = container_of(list_next(&proc->list), struct process_control_block, list);
+        }
+    }
+    list_append(&proc->list, &pcb->list);
+    ++sched_cfs_ready_queue.count;
+}
+
+/**
+ * @brief 调度函数
+ *
+ */
+void sched_cfs()
+{
+
+    current_pcb->flags &= ~PROC_NEED_SCHED;
+    struct process_control_block *proc = sched_cfs_dequeue();
+
+    if (current_pcb->virtual_runtime >= proc->virtual_runtime) // 当前进程运行时间大于了下一进程的运行时间,进行切换
+    {
+
+        if (current_pcb->state = PROC_RUNNING) // 本次切换由于时间片到期引发,则再次加入就绪队列,否则交由其它功能模块进行管理
+            sched_cfs_enqueue(current_pcb);
+
+        if (!sched_cfs_ready_queue.cpu_exec_proc_jiffies)
+        {
+            switch (proc->priority)
+            {
+            case 0:
+            case 1:
+                sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.count;
+                break;
+            case 2:
+            default:
+
+                sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.count) << 2;
+                break;
+            }
+        }
+
+        switch_proc(current_pcb, proc);
+    }
+    else // 不进行切换
+    {
+        kdebug("not switch.");
+        sched_cfs_enqueue(current_pcb);
+
+        if (!sched_cfs_ready_queue.cpu_exec_proc_jiffies)
+        {
+            switch (proc->priority)
+            {
+            case 0:
+            case 1:
+                sched_cfs_ready_queue.cpu_exec_proc_jiffies = 4 / sched_cfs_ready_queue.cpu_exec_proc_jiffies;
+                break;
+            case 2:
+            default:
+                sched_cfs_ready_queue.cpu_exec_proc_jiffies = (4 / sched_cfs_ready_queue.cpu_exec_proc_jiffies) << 2;
+                break;
+            }
+        }
+        kdebug("hhhh");
+    }
+}
+
+/**
+ * @brief 初始化进程调度器
+ *
+ */
+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 = 4;
+    sched_cfs_ready_queue.proc_queue.virtual_runtime = 0x7fffffffffffffff;
+}

+ 41 - 0
kernel/sched/sched.h

@@ -0,0 +1,41 @@
+#pragma once
+
+#include <common/glib.h>
+#include <process/process.h>
+
+struct sched_queue_t
+{
+    long count; // 当前队列中的数量
+    long cpu_exec_proc_jiffies; // 进程可执行的时间片数量
+    struct process_control_block proc_queue;
+};
+
+// @todo: 用红黑树重写cfs的队列
+struct sched_queue_t sched_cfs_ready_queue; // 就绪队列
+
+/**
+ * @brief 调度函数
+ * 
+ */
+void sched_cfs();
+
+/**
+ * @brief 将PCB加入就绪队列
+ *
+ * @param pcb
+ */
+void sched_cfs_enqueue(struct process_control_block *pcb);
+
+
+/**
+ * @brief 从就绪队列中取出PCB
+ *
+ * @return struct process_control_block*
+ */
+struct process_control_block *sched_cfs_dequeue();
+
+/**
+ * @brief 初始化进程调度器
+ * 
+ */
+void sched_init();

+ 2 - 44
kernel/smp/apu_boot.S

@@ -3,7 +3,7 @@
 
 .align 0x1000  // 按照4k对齐
 
-.text
+.section .text
 .code16
 
 ENTRY(_apu_boot_start)
@@ -72,58 +72,16 @@ _apu_code32:
     mov %cr4, %eax
     or $(1<<5), %eax
     mov %eax, %cr4
-/*
+
     movl $enter_head_from_ap_boot, %eax
     jmpl	*%eax
     hlt
-*/
-    
 
-    // 设置页表
-
-    movl $pml4, %eax    // 复用bsp处理器初始化时的32位页表
-    movl %eax, %cr3
     
-    // enable long mode
-    movl	$0xC0000080,	%ecx
-	rdmsr
-
-	bts	$8,	%eax
-	wrmsr
-
-    // enable PE and paging
-    mov %cr0, %eax
-    bts	$0,	%eax
-	bts	$31,	%eax
-    mov %eax, %cr0
-
-    // 跳转到64位代码
-    ljmp *(_apu_code64_vector - _apu_boot_base)(%esi)
-
 
 .code64
 .align 0x1000 
 _apu_code64:
-    movq $0x20, %rax
-    movq %rax, %ds
-    movq %rax, %es
-    movq %rax, %ss
-    movq %rax, %fs
-    movq %rax, %gs
-
-
-    //now enable SSE and the like
-    movq %cr0, %rax
-    and $0xFFFB, %ax		//clear coprocessor emulation CR0.EM
-    or $0x2, %ax			//set coprocessor monitoring  CR0.MP
-    movq %rax, %cr0
-    movq %cr4, %rax
-    or $(3 << 9), %ax		//set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time
-    movq %rax, %cr4
-
-    // 跳转到地址1MB处执行
-    movq	$_start64,	%rax
-	jmpq	*%rax
 
     hlt
 

+ 42 - 15
kernel/smp/smp.c

@@ -15,10 +15,11 @@ static struct acpi_Processor_Local_APIC_Structure_t *proc_local_apic_structs[MAX
 static uint32_t total_processor_num = 0;
 int current_starting_cpu = 0;
 
+int num_cpu_started = 1;
+
 void smp_init()
 {
     spin_init(&multi_core_starting_lock); // 初始化多核启动锁
-
     ul tmp_vaddr[MAX_SUPPORTED_PROCESSOR_NUM] = {0};
 
     apic_get_ics(ACPI_ICS_TYPE_PROCESSOR_LOCAL_APIC, tmp_vaddr, &total_processor_num);
@@ -29,17 +30,20 @@ void smp_init()
 
     //*(uchar *)0x20000 = 0xf4; // 在内存的0x20000处写入HLT指令(AP处理器会执行物理地址0x20000的代码)
     // 将引导程序复制到物理地址0x20000处
-    memcpy((unsigned char *)0x20000, _apu_boot_start, (unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
-
+    memcpy((unsigned char *)phys_2_virt(0x20000), _apu_boot_start, (unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
+    
     // 设置多核IPI中断门
     for (int i = 200; i < 210; ++i)
         set_intr_gate(i, 2, SMP_interrupt_table[i - 200]);
-    memset(SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM);
+
+    memset((void *)SMP_IPI_desc, 0, sizeof(irq_desc_t) * SMP_IRQ_NUM);
 
     ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x00, ICR_INIT, ICR_ALL_EXCLUDE_Self, true, 0x00);
 
     for (int i = 1; i < total_processor_num; ++i) // i从1开始,不初始化bsp
     {
+        if (proc_local_apic_structs[i]->ACPI_Processor_UID == 0)
+            --total_processor_num;
         spin_lock(&multi_core_starting_lock);
         current_starting_cpu = i;
 
@@ -49,15 +53,34 @@ void smp_init()
 
         cpu_core_info[i].tss_vaddr = (uint64_t)kmalloc(128, 0);
 
-        set_tss_descriptor(10 + (i * 2), (void *)(cpu_core_info[i].tss_vaddr));
+        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("GDT Table %#018lx, \t %#018lx", GDT_Table[10 + i * 2], 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);
     }
+
+    while (num_cpu_started != total_processor_num)
+        __asm__ __volatile__("pause" ::
+                                 : "memory");
+
+    kinfo("Cleaning page table remapping...\n");
+    
+    // 由于ap处理器初始化过程需要用到0x00处的地址,因此初始化完毕后才取消内存地址的重映射
+    //todo: 取消低0-2M的地址映射
+    for (int i = 1; i < 128; ++i)
+    {
+
+        *(ul *)(phys_2_virt(global_CR3) + i) = 0UL;
+    }
+
+    kinfo("Successfully cleaned page table remapping!\n");
+   
 }
 
 /**
@@ -66,8 +89,9 @@ void smp_init()
  */
 void smp_ap_start()
 {
-    // 切换栈基地址
-    // uint64_t stack_start = (uint64_t)kmalloc(STACK_SIZE, 0) + STACK_SIZE;
+
+    //  切换栈基地址
+    //  uint64_t stack_start = (uint64_t)kmalloc(STACK_SIZE, 0) + STACK_SIZE;
     __asm__ __volatile__("movq %0, %%rbp \n\t" ::"m"(cpu_core_info[current_starting_cpu].stack_start)
                          : "memory");
     __asm__ __volatile__("movq %0, %%rsp \n\t" ::"m"(cpu_core_info[current_starting_cpu].stack_start)
@@ -78,15 +102,18 @@ void smp_ap_start()
         __asm__ __volatile__("movq %0, %%rsp \n\t" ::"m"(stack_start)
                              : "memory");*/
     ksuccess("AP core successfully started!");
+
+    ++num_cpu_started;
+
     kdebug("current cpu = %d", current_starting_cpu);
-    apic_init_ap_core_local_apic();
 
+    apic_init_ap_core_local_apic();
     load_TR(10 + current_starting_cpu * 2);
-    spin_unlock(&multi_core_starting_lock);
+
     sti();
-    kdebug("IDT_addr = %#018lx", &IDT_Table);
-    
-    
-    while (1)   // 这里要循环hlt,原因是当收到中断后,核心会被唤醒,处理完中断之后不会自动hlt
+    kdebug("IDT_addr = %#018lx", phys_2_virt(IDT_Table));
+
+    spin_unlock(&multi_core_starting_lock);
+    while (1) // 这里要循环hlt,原因是当收到中断后,核心会被唤醒,处理完中断之后不会自动hlt
         hlt();
 }

+ 1 - 0
kernel/syscall/syscall.c

@@ -21,6 +21,7 @@ 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减去相应的数值)

+ 1 - 1
run.sh

@@ -12,7 +12,7 @@ if [ ! "$1" == "--nobuild" ]; then
     make clean
 fi
 
-IA32_USE_QEMU=1
+IA32_USE_QEMU=0
 bochsrc="./bochsrc"
 ARCH="x86_64"