From: acevest Date: Wed, 3 Nov 2021 14:03:47 +0000 (+0800) Subject: 进入ring3 X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=4ebfe2ef702b36cc0ce8ba74ac3fc7e552a285da;p=kernel.git 进入ring3 --- diff --git a/kernel/init.c b/kernel/init.c index 9ce0257..1d852dc 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -24,62 +24,71 @@ char idtr[6] __attribute__((__aligned__(4))); // int debug_wait_queue_get(); -#define __ring3text__ __attribute__((__section__(".ring3.text"), __aligned__(PAGE_SIZE))) +#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_stack[PAGE_SIZE]; -void __ring3text__ ring3_entry() { +int ring3_sysctest(); +void __ring3text__ __attribute__((__aligned__(PAGE_SIZE))) ring3_entry() { while (1) { - systest(); + ring3_sysctest(); } } + +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); + // 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)); - // unsigned long *pt_text_page = (unsigned long *)va2pa(alloc_one_page(0)); - // unsigned long *pt_data_page = (unsigned long *)va2pa(alloc_one_page(0)); - // unsigned long *pt_bss_page = (unsigned long *)va2pa(alloc_one_page(0)); - // unsigned long *p = (unsigned long *)((current->cr3 - 0xC0000000)); - // asm volatile("xchg %%bx, %%bx;mov %%eax, %%ebx;xchg %%bx, %%bx;"::"a"(p)); + 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)); - // // text: 0x0800_0000 - // // data: 0x2000_0000 - // // bss: 0x3000_0000 - // unsigned long text_at = 0x08000000; - // unsigned long data_at = 0x20000000; - // unsigned long bbs_at = 0x30000000; + 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)); - // unsigned long flag = 0; + //asm volatile("xchg %%bx, %%bx;mov %%eax, %%ebx;xchg %%bx, %%bx;"::"a"(p)); + 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); - // flag |= PAGE_P; - // flag |= PAGE_US; + // 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)pt_text_page | PAGE_P | PAGE_US; - // pt_text_page[0] = ring3_text_page; - // p[data_at >> 22] = (unsigned long)pt_data_page | PAGE_P | PAGE_WR | PAGE_US; - // pt_data_page[0] = ring3_data_page; - // p[bbs_at >> 22] = (unsigned long)pt_bss_page | PAGE_P | PAGE_WR | PAGE_US; - // pt_bss_page[0] = ring3_bss_page; + 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[bbs_at >> 22] = (unsigned long)va2pa(pt_bss_page) | PAGE_P | PAGE_WR | PAGE_US; + pt_bss_page[0] = ring3_bss_page | 7 ; - // // - // asm("xchg %bx, %bx"); - // LOAD_CR3((unsigned long)p); + // + LoadCR3(current->cr3); // 现在要准备返回用户态 // eip --> edx // esp --> ecx - asm("xchg %bx, %bx"); - // asm("sysexit;" ::"d"(0x08000000), "c"(0x30000000 + PAGE_SIZE)); - while (1) { - asm("hlt;"); - } + asm volatile("xchg %bx, %bx"); + asm volatile("sysexit;" ::"d"(0x08000000), "c"(0x30000000 + PAGE_SIZE - 100)); } void init_task_entry() { @@ -96,7 +105,7 @@ void init_task_entry() { } while (1) { - sysc_test(); + //sysc_test(); printl(MPL_TASK_1 + id - 1, "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(); @@ -138,12 +147,12 @@ void root_task_entry() { int cnt = 0; while (1) { - sysc_test(); + //sysc_test(); printl(MPL_ROOT, "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;"); - sysc_test(); + //sysc_test(); // syscall0(SYSC_TEST); } } diff --git a/kernel/syscall.S b/kernel/syscall.S index 0a6f290..906d65c 100644 --- a/kernel/syscall.S +++ b/kernel/syscall.S @@ -27,7 +27,6 @@ .global syscall_entry .global ret_from_fork_user .global ret_from_fork_krnl -.global sysexit //.global syscall_exit syscall_entry: @@ -78,7 +77,7 @@ ret_from_fork_user: // 在系统调用前,用户态的esp保存在ebp中 // sysexit指令从ecx中恢复用户态esp - movl %ebp, %ecx + xchgl %ebp, %ecx sti /* sysenter have cleared IF, and sysexit will not set IF. */ sysexit @@ -102,8 +101,21 @@ 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 +.align 0x1000 sysexit: popl %ebp; popl %edx; diff --git a/kernel/syscall.c b/kernel/syscall.c index 3c11103..59edd80 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -52,9 +52,9 @@ int sysc_test() { static unsigned int cnt = 0; current->cnt++; - printl(MPL_TEST, "systest cnt %u current %08x cnt %u ", - cnt++, current, cnt); - + // printl(MPL_TEST, "systest cnt %u current %08x cnt %u ", + // cnt++, current, cnt); + printk("systest cnt %u current %08x cnt %u\n",cnt++, current, cnt); return 0; } diff --git a/mm/mm.c b/mm/mm.c index 06bdad7..a9d8c49 100644 --- a/mm/mm.c +++ b/mm/mm.c @@ -39,8 +39,6 @@ void set_page_shared(void *x) { pte[get_npt(addr)] |= PAGE_US; } -extern void sysexit(); - void init_paging() { unsigned int i; unsigned long pfn = 0; @@ -74,6 +72,9 @@ 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)); diff --git a/scripts/link.ld b/scripts/link.ld index ce2afbd..1f9d6f0 100644 --- a/scripts/link.ld +++ b/scripts/link.ld @@ -30,6 +30,7 @@ SECTIONS *(.multiboot_header) *(.text) + *(.sysenter) /* last */ *(.sysexit) /* last */ } etext = .;