From eddd38aec8a167e79accec0f0bfffc01fe3763e3 Mon Sep 17 00:00:00 2001 From: AceVest Date: Tue, 29 Apr 2014 23:00:00 +0800 Subject: [PATCH] fix privilege bug when init_paging; add sysexit for user program --- boot/multiboot.S | 6 ++--- include/page.h | 8 +++---- kernel/syscall.S | 57 ++++++++++-------------------------------------- mm/mm.c | 20 +++++++++++++++-- scripts/link.ld | 1 + setup/setup.c | 1 - 6 files changed, 37 insertions(+), 56 deletions(-) diff --git a/boot/multiboot.S b/boot/multiboot.S index 36675ab..de5acf1 100644 --- a/boot/multiboot.S +++ b/boot/multiboot.S @@ -74,7 +74,7 @@ kernel_entry: # Init Page Directory movl %ebx,%edi movl $init_pgt-KRNLADDR,%eax - addl $7,%eax + addl $3,%eax movl $BOOT_INIT_PAGETBL_CNT,%ecx 1: stosl @@ -87,7 +87,7 @@ kernel_entry: movl %eax,%edi movl $init_pgt-KRNLADDR,%eax - addl $7,%eax + addl $3,%eax movl $BOOT_INIT_PAGETBL_CNT,%ecx 2: stosl @@ -98,7 +98,7 @@ kernel_entry: movl $init_pgt-KRNLADDR,%ebx movl %ebx,%edi movl $(BOOT_INIT_PAGETBL_CNT*1024),%ecx - movl $0x07,%eax + movl $3,%eax cld 3: stosl diff --git a/include/page.h b/include/page.h index 7fc67f1..308da1a 100644 --- a/include/page.h +++ b/include/page.h @@ -23,10 +23,10 @@ #define PAGE_WR 0x2 #define PAGE_US 0x4 -#define PAGE_SHIFT (12) -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~((1UL << PAGE_SHIFT)-1)) -#define PAGE_OFFSET (0xC0000000) +#define PAGE_SHIFT (12) +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~((1UL << PAGE_SHIFT)-1)) +#define PAGE_OFFSET (0xC0000000) #define PAGE_PDE_CNT 1024 #define PAGE_PTE_CNT 1024 diff --git a/kernel/syscall.S b/kernel/syscall.S index 62bced0..780e76f 100644 --- a/kernel/syscall.S +++ b/kernel/syscall.S @@ -99,50 +99,15 @@ bad_syscnr: jmp ret_from_bad_syscnr #endif -#if 0 -syscall_entry: - /* 此时%esp存的是current的地址(¤t) */ - movl (%esp),%esp /* 获得current的值 */ - addl $TASK_SIZE, %esp /* 指向PCB的顶部 */ - - pushl %ds /* %ss */ - pushl %ebp /* %esp */ - pushfl /* %eflags */ - pushl $SELECTOR_USER_CS /* %cs */ - pushl %gs:(,%ebp) /* %eip */ - pushl %eax /* sysc_nr */ - SAVE_REGS - - pushl %eax - movw %ss,%ax - movw %ax, %ds - movw %ax, %es - movw %ax, %gs - movw %ax, %fs - popl %eax - - call *sysc_handler_table(,%eax,4) - - movl %eax, 0x18(%esp) /* return value */ - - RESTORE_REGS - - movl 0x04(%esp), %edx /* sysexit 参数 %eip */ - movl 0x10(%esp), %ecx /* sysexit 参数 %esp */ - sti /* sysenter会自动清除IF.貌似sysexit不会自动置位 */ - sysexit -#endif - -#if 0 -.global sysc_handler_table -.extern sysc_write -.extern sysc_read_kbd -.extern sysc_reboot -.extern sysc_fork -sysc_handler_table: -.long sysc_write -.long sysc_read_kbd -.long sysc_reboot -.long sysc_fork -#endif +# this routine should be load align by PAGE_SIZE +# 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 +.section .sysexit +.align 0x1000 +.global sysexit +sysexit: + nop + nop + ret diff --git a/mm/mm.c b/mm/mm.c index a853839..6ba689c 100644 --- a/mm/mm.c +++ b/mm/mm.c @@ -294,6 +294,19 @@ find_block: pde_t __initdata init_pgd[PDECNT_PER_PAGE] __attribute__((__aligned__(PAGE_SIZE))); pte_t __initdata init_pgt[PTECNT_PER_PAGE*BOOT_INIT_PAGETBL_CNT] __attribute__((__aligned__(PAGE_SIZE))); +extern void sysexit(); + +void set_page_shared(void *x) +{ + unsigned long addr = (unsigned long) x; + addr = PAGE_ALIGN(addr); + unsigned int npd = get_npd(addr); + init_pgd[npd] |= PAGE_US; + + pte_t *pte = pa2va(init_pgd[npd] & PAGE_MASK); + pte[get_npt(addr)] |= PAGE_US; +} + void init_paging() { unsigned int i; @@ -312,11 +325,11 @@ void init_paging() memset((void *)pgtb_addr, 0, PAGE_SIZE); - init_pgd[get_npd(page_addr)] = (pde_t)(pgtb_addr | PAGE_P | PAGE_WR | PAGE_US); + init_pgd[get_npd(page_addr)] = (pde_t)(pgtb_addr | PAGE_P | PAGE_WR); } pte = ((pte_t *) pa2va(pgtb_addr)) + ti; - *pte = (pte_t) (page_addr | PAGE_P | PAGE_WR | PAGE_US); + *pte = (pte_t) (page_addr | PAGE_P | PAGE_WR); } @@ -327,6 +340,9 @@ void init_paging() init_pgd[i] = init_pgd[i-delta]; } + // paging for user space + set_page_shared(sysexit); + LOAD_CR3(init_pgd); } diff --git a/scripts/link.ld b/scripts/link.ld index 4095c8a..c1a3955 100644 --- a/scripts/link.ld +++ b/scripts/link.ld @@ -28,6 +28,7 @@ SECTIONS phys_addr = . - kernel_virtual_addr_start; *(.multiboot_header) *(.text) + *(.sysexit) } etext = .; .data : AT(phys_addr) ALIGN(0x1000) diff --git a/setup/setup.c b/setup/setup.c index fff210a..479507b 100644 --- a/setup/setup.c +++ b/setup/setup.c @@ -60,7 +60,6 @@ void setup_kernel() setup_irqs(); - while(1); // TODO MODIFY CODE BELOW setup_tasks(); -- 2.44.0