]> Zhao Yanbai Git Server - kernel.git/commitdiff
用新的方式跳转到用户态
authoracevest <zhaoyanbai@126.com>
Fri, 5 Nov 2021 06:51:10 +0000 (14:51 +0800)
committeracevest <zhaoyanbai@126.com>
Fri, 5 Nov 2021 06:51:10 +0000 (14:51 +0800)
.bochsrc
include/printk.h
kernel/init.c
kernel/sched.c
kernel/syscall.S
mm/bootmem.c
mm/mm.c
scripts/link.ld

index a2e7855be52c1c454ac6f419929cb31aa8be27cf..dd163524c64505191efa92ac2c46f5850c6e383d 100644 (file)
--- a/.bochsrc
+++ b/.bochsrc
@@ -1308,4 +1308,4 @@ magic_break: enabled=1
 #megs: 32
 #megs: 16
 #megs: 8
-megs: 32
+megs: 8
index a1acab07b934c4faa2d6f287afc156c55aaa07db..30e0108f929a88ae4d8e83b172977ce370bf9a0b 100644 (file)
@@ -37,6 +37,7 @@ enum {
     MPL_TEST,
     MPL_DEBUG,
     MPL_ROOT,
+    MPL_TASK_0,
     MPL_TASK_1,
     MPL_TASK_2,
     MPL_TASK_3,
index b4434d77ce442eb88aee7eea8e969fbaf925ef52..8b36e128876647860b32dda63c9a011ab1099f3b 100644 (file)
@@ -25,59 +25,62 @@ char idtr[6] __attribute__((__aligned__(4)));
 // int debug_wait_queue_get();
 
 #define __ring3text__ __attribute__((__section__(".ring3.text")))
-#define __ring3data__ __attribute__((__section__(".ring3.data"), __aligned__(PAGE_SIZE)))
-#define __ring3bss__ __attribute__((__section__(".ring3.bss"), __aligned__(PAGE_SIZE)))
 
-char __ring3data__ ring3_stack[PAGE_SIZE] = {0};
-char __ring3bss__ ring3_bss[PAGE_SIZE + 1234];
 int ring3_sysctest();
 void __ring3text__ __attribute__((__aligned__(PAGE_SIZE))) ring3_entry() {
     while (1) {
-        ring3_sysctest();
+        int __sysc_ret__ = 0;
+
+        // 下面这段汇编中的 ring3_entry 和 sysexit_return_address的地址都是内核地址
+        // 然而在用户态用的代码地址是从0x08000000开始的
+        // 因此为了算了systexit返回的正确地址
+        // 需要借助ring3_entry算出sysexit_return_address相对ring3_entry的偏移量
+        // 再把这个偏移量加上0x08000000就是正确的sysexit的地址
+
+        // 必需注意这里的sysexit_return_address并不是sysexit指令返回的地址
+        // sysexit指令返回的是编译在内核中的一段代码地址,这个地址已经被设成内核和用户态共享
+        // 在内核中的那段代码里会利用存在栈上的sysexit_return_address返回到
+        // sysexit_return_address处
+        asm volatile(
+            "leal sysexit_return_address, %%ebx;"
+            "subl %%ecx, %%ebx;"
+            "addl $0x08000000, %%ebx;"  // 算出sysexit_return_address在用户态的实际地址
+            "pushl %%ebx;"  // 把这个地址保存在栈上,内核sysexit会返回到一段共享代码上
+                            // 共享代码会利用保存在栈上的地址返回到sysexit_return_address处
+            "pushl $0;"
+            "pushl $0;"
+            "pushl %%ebp;"
+            "movl  %%esp, %%ebp;"
+            "sysenter;"
+            "sysexit_return_address:"
+            : "=a"(__sysc_ret__)
+            : "a"(SYSC_TEST), "c"(ring3_entry));
     }
 }
 
-static int __ring3text__ __volatile__ __ring3_syscall0(int nr) {
-    int __sysc_ret__ = 0;
-    extern void sysenter;
-    asm volatile("leal sysenter, %%ebx;call *%%ebx;" : "=a"(__sysc_ret__) : "a"(nr));
-    return __sysc_ret__;
-}
-int __ring3text__ _ring3_syscall0(int nr) { return __ring3_syscall0(nr); }
-int __ring3text__ ring3_sysctest() { return _ring3_syscall0(SYSC_TEST); }
-
-void user_task_entry() {
-    // printk("user_task_entry: %08x\n", ring3_entry);
-
-    // unsigned long ring3_text_page = va2pa(alloc_one_page(0));
-    // unsigned long ring3_data_page = va2pa(alloc_one_page(0));
-    // unsigned long ring3_bss_page = va2pa(alloc_one_page(0));
+void user_task_entry(char *name) {
+    strcpy(current->name, name);
 
     unsigned long ring3_text_page = va2pa(ring3_entry);
-    unsigned long ring3_data_page = va2pa(ring3_stack);
     unsigned long ring3_bss_page = va2pa(alloc_one_page(0));
 
     unsigned long *pt_text_page = (unsigned long *)(alloc_one_page(0));
-    unsigned long *pt_data_page = (unsigned long *)(alloc_one_page(0));
     unsigned long *pt_bss_page = (unsigned long *)(alloc_one_page(0));
+
     unsigned long *p = (unsigned long *)(pa2va(current->cr3));
 
     printk("page dir : %x %x %x %x\n", p, pt_text_page, ring3_text_page);
     printk("pt bss page %x %x", pt_bss_page, ring3_bss_page);
 
     // text: 0x0800_0000
-    // data: 0x2000_0000
     //  bss: 0x3000_0000
     unsigned long text_at = 0x08000000;
-    unsigned long data_at = 0x20000000;
     unsigned long bbs_at = 0x30000000;
 
-    p[text_at >> 22] = (unsigned long)va2pa(pt_text_page) | PAGE_P | PAGE_WR | PAGE_US;
-    pt_text_page[0] = ring3_text_page | 7;
-    p[data_at >> 22] = (unsigned long)va2pa(pt_data_page) | PAGE_P | PAGE_WR | PAGE_US;
-    pt_data_page[0] = ring3_data_page | 7;
+    p[text_at >> 22] = (unsigned long)va2pa(pt_text_page) | PAGE_P | PAGE_US;
+    pt_text_page[0] = ring3_text_page | PAGE_P | PAGE_US;
     p[bbs_at >> 22] = (unsigned long)va2pa(pt_bss_page) | PAGE_P | PAGE_WR | PAGE_US;
-    pt_bss_page[0] = ring3_bss_page | 7;
+    pt_bss_page[0] = ring3_bss_page | PAGE_P | PAGE_WR | PAGE_US;
 
     //
     LoadCR3(current->cr3);
@@ -88,10 +91,12 @@ void user_task_entry() {
     asm volatile("sysexit;" ::"d"(0x08000000), "c"(0x30000000 + PAGE_SIZE - 100));
 }
 
-void init_task_entry() {
+void init_task_entry(char *name) {
     int cnt = 0;
     pid_t id = sysc_getpid();
 
+    strcpy(current->name, name);
+
     // 赋予不同的优先级
     current->priority = id * 30;
     if (current->priority <= 0) {
@@ -103,7 +108,7 @@ void init_task_entry() {
 
     while (1) {
         // sysc_test();
-        printl(MPL_TASK_1 + id - 1, "task:%d [%08x] weight %d cnt %d", id, current, current->weight, cnt++);
+        // printl(MPL_TASK_0 + id, "task:%d [%08x] weight %d cnt %d", id, current, current->weight, cnt++);
         // printl(MPL_TASK_1, "task:%d [%08x] weight %d cnt %d", id, current, current->weight, cnt++);
         int v = 0;  // debug_wait_queue_get();
         // printk("task:%d wait queue get %d\n", id, v);
@@ -130,6 +135,8 @@ void kernel_task(char *name, void *entry) {
     regs.fs = SELECTOR_KRNL_DS;
     regs.gs = SELECTOR_KRNL_DS;
 
+    regs.ebx = (unsigned long)name;  // 用ebx传递参数
+
     int pid = do_fork(&regs, FORK_KRNL);
 
     printk("kernel[%s] task pid is %d\n", name, pid);
@@ -145,7 +152,7 @@ void root_task_entry() {
     int cnt = 0;
     while (1) {
         // sysc_test();
-        printl(MPL_ROOT, "root:0 [%08x] weight %d cnt %d", current, root_task.weight, cnt++);
+        // printl(MPL_TASK_0, "root:0 [%08x] weight %d cnt %d", current, root_task.weight, cnt++);
         // printk("root:0 [%08x] weight %d cnt %d", current, current->weight, cnt++);
         asm("sti;hlt;");
         // asm("nop;nop;nop;");
index 535d4644d5996289e5b7ba11a751b2fd8ed5eef0..d458525c05d576d67b9e08ba2f6cdc42c978ecef 100644 (file)
@@ -143,7 +143,7 @@ unsigned long schedule() {
 
     unsigned long iflags;
     irq_save(iflags);
-    printl(MPL_ROOT, "root:%d [%08x] cnt %u", root_task.pid, &root_task, root_task.cnt);
+    // printl(MPL_ROOT, "root:%d [%08x] cnt %u", root_task.pid, &root_task, root_task.cnt);
 
     float min_ratio = 1.0;
 
@@ -172,8 +172,6 @@ unsigned long schedule() {
     list_for_each_safe(pos, t, &all_tasks) {
         p = list_entry(pos, task_union, list);
 
-        printl(MPL_ROOT + p->pid, "task:%d [%08x] state %s cnt %u", p->pid, p, task_state(p->state), p->cnt);
-
         if (p->state != TASK_RUNNING) {
             continue;
         }
@@ -196,6 +194,12 @@ unsigned long schedule() {
 
     if (prev != next) {
         // printk("switch to: %s:%d\n", next->name, next->pid);
+
+        list_for_each_safe(pos, t, &all_tasks) {
+            p = list_entry(pos, task_union, list);
+            printl(MPL_TASK_0 + p->pid, "%s%4s:%d [%08x] state %s weight %03d cnt %u", sel == p ? ">" : " ", p->name,
+                   p->pid, p, task_state(p->state), p->weight, p->cnt);
+        }
         context_switch(prev, next);
     }
 }
index 906d65c3e65e94e3749088f15ea849f0a32d8a7b..76b3ad14c80a5a6666ca4e49792339e0235d7926 100644 (file)
@@ -89,7 +89,11 @@ ret_from_fork_krnl:
     addl    $12, %esp
     popfl
     addl    $8, %esp
+
+    # 用ebx传递参数
+    pushl   %ebx
     call    *%edx
+    addl    $4, %esp
 
     # 还没有实现do_exit
     #call    do_exit
@@ -101,18 +105,6 @@ ret_from_fork_krnl:
 # this page is shared by the kernel and userspace
 # the reason why i use this method is because of that the user program
 # no need to pay attention on the return address
-.global sysenter
-.section .sysenter
-.align 0x1000
-sysenter:
-    pushl   %ecx;
-    pushl   %edx;
-    pushl   %ebp;
-    movl    %esp, %ebp;
-    sysenter;
-
-
-
 .global sysexit
 .section .sysexit
 .align 0x1000
index 597a593769f4d44dd4016e9d0fd02bae107ec319..bd8a30bb7f5969d81d09eae48b7d902df536ac6d 100644 (file)
@@ -44,7 +44,7 @@ void fast_init_bootmem_bitmap(unsigned long bgn_pfn, unsigned long end_pfn, int
     u8 data = op == 0 ? 0x00 : 0xFF;
 
     // 先设置头部不是从单个字节开始的比特
-    unsigned int i = 0;  // 这个变不能放到for循环里定义
+    unsigned int i = 0;  // 这个变不能放到for循环里定义
     for (i = bgn_pfn; i < end_pfn && (i % 8 != 0); i++) {
         bit_func(i, bootmem_data.bitmap);
     }
@@ -52,7 +52,7 @@ void fast_init_bootmem_bitmap(unsigned long bgn_pfn, unsigned long end_pfn, int
     // 算出中间的整字节数
     unsigned int bytes = (end_pfn - i) / 8;
 
-    // 直接清零
+    // 直接清零或设置
     memset((char *)(bootmem_data.bitmap) + (i / 8), data, bytes);
 
     // 最后设置尾部不是整字节的比特
diff --git a/mm/mm.c b/mm/mm.c
index c3907b0bb6eda2b52a7f5bd52ff77a7004b0928f..02ca95e69b4623fba27869ce4231a8e8d0e461e9 100644 (file)
--- a/mm/mm.c
+++ b/mm/mm.c
@@ -75,9 +75,7 @@ void init_paging() {
     }
 
     // paging for user space
-    extern void sysenter();
     extern void sysexit();
-    set_page_shared(sysenter);
     set_page_shared(sysexit);
 
     LoadCR3(va2pa(init_pgd));
index df9ce8067949796fd665bbb7454bfbe2ba3b8411..8d8efff528508a4df4151340fdabf01d73a8a932 100644 (file)
@@ -29,8 +29,7 @@ SECTIONS
         boot/multiboot.S.o(.text)
         *(.multiboot_header)
         *(.text)
-
-        *(.sysenter) /* last */
+       *(.ring3.text);
         *(.sysexit) /* last */
     }
     etext = .;
@@ -50,24 +49,6 @@ SECTIONS
 
     ebss = .;
 
-    .ring3.text : AT(phys_addr) ALIGN(0x1000)
-    {
-        phys_addr = . - kernel_virtual_addr_start;
-           *(.ring3.text);
-    }
-
-    .ring3.data : AT(phys_addr) ALIGN(0x1000)
-    {
-        phys_addr = . - kernel_virtual_addr_start;
-           *(.ring3.data);
-    }
-
-    .ring3.bss : AT(phys_addr) ALIGN(0x1000)
-    {
-        phys_addr = . - kernel_virtual_addr_start;
-           *(.ring3.bss);
-    }
-
     end = .;
     _end = .;
     kernel_end = .;