From: AceVest Date: Thu, 1 May 2014 16:25:44 +0000 (+0800) Subject: return the result to userspace from syscall X-Git-Tag: 0.3.0~74 X-Git-Url: http://zhaoyanbai.com/repos/?a=commitdiff_plain;h=cdc504d67d3ab3454ee9bfbc04dd42f11ec7dff7;p=kernel.git return the result to userspace from syscall --- diff --git a/include/system.h b/include/system.h index 7a071dc..15ca050 100644 --- a/include/system.h +++ b/include/system.h @@ -102,12 +102,13 @@ enum GDTSelectorIndex // pushad push eax, ecx, edx, ebx, esp, ebp, esi, edi typedef struct { - u32 ebx; - u32 edx; - u32 ecx; u32 edi; u32 esi; u32 ebp; + u32 _esp; + u32 ebx; + u32 edx; + u32 ecx; u32 eax; // 因为在系统调用中用来带调用号,就无法传送参数 // 所以把eax放在这个位置 u16 ds, _ds; @@ -116,7 +117,6 @@ typedef struct u16 gs, _gs; union { - u32 sysc_nr; u32 irq; u32 errcode; }; @@ -176,22 +176,10 @@ extern System system; pushl %fs; \ pushl %es; \ pushl %ds; \ - pushl %eax; \ - pushl %ebp; \ - pushl %esi; \ - pushl %edi; \ - pushl %ecx; \ - pushl %edx; \ - pushl %ebx; + pushal; #define RESTORE_REGS \ - popl %ebx; \ - popl %edx; \ - popl %ecx; \ - popl %edi; \ - popl %esi; \ - popl %ebp; \ - popl %eax; \ + popal; \ popl %ds; \ popl %es; \ popl %fs; \ diff --git a/kernel/interrupts.S b/kernel/interrupts.S index bf3d0a7..13ddf46 100644 --- a/kernel/interrupts.S +++ b/kernel/interrupts.S @@ -66,11 +66,6 @@ DEF_IRQ(0,F) .extern irq_handler .extern schedule _irq_handler: -#if 1 - /* - * 这些寄存器以及上面的中断号和中断自动压栈的寄存器 - * 都存在中断栈中. - */ SAVE_REGS movw %ss,%ax @@ -82,7 +77,7 @@ _irq_handler: movl %esp, %eax call irq_handler - call schedule + # call schedule # movl current, %esp @@ -91,38 +86,3 @@ _irq_handler: addl $4,%esp /* 跳过中断号. */ iret -#endif - -#if 0 /* 2010.02.22 */ - /* - * 这些寄存器以及上面的中断号和中断自动压栈的寄存器 - * 都存在中断栈中. - */ - SAVE_REGS - - movw %ss,%ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - - movl %esp, %eax - call irq_handler - - - /* 向调度器传递栈帧的位置以便其保存现场. */ - pushl %esp - call schedule - - /* - * 利用task_struct 里的内容作为新进程的现场来恢复 - * 所以用不着针对pushl %esp 写 addl $4,%esp了. - */ - movl current, %esp - - RESTORE_REGS - - addl $4,%esp /* 跳过中断号. */ - - iret -#endif diff --git a/kernel/syscall.S b/kernel/syscall.S index da10d88..9e9bf74 100644 --- a/kernel/syscall.S +++ b/kernel/syscall.S @@ -7,10 +7,12 @@ * * Author: Zhao Yanbai [zhaoyanbai@126.com] * - * Version: 1.0 + * Version: 1.0 * Create Date: Tue Feb 10 13:20:33 2009 * Version: 2.0 * Last Update: Wed Feb 10 23:36:34 2010 + * Version: 3.0 + * Last Update: Fri May 2 00:21:37 2014 * *-------------------------------------------------------------------------- */ @@ -19,107 +21,51 @@ #include #include -#define TASK_SIZE 4096*2 .code32 -#if 0 -.extern sysc_handler_table -#endif .text .global syscall_entry .global ret_from_fork .global sysexit -#if 1 +#define EAX 32 + syscall_entry: movl (%esp),%esp SAVE_REGS - pushfl - pushl %ebp pushl %eax - movw %ss, %ax movw %ax, %ds movw %ax, %es movw %ax, %gs movw %ax, %fs - popl %eax cmpl $SYSC_NUM, %eax - jae bad_syscnr + jae bad_sysc_nr call *sysc_handler_table(,%eax,4) -ret_from_bad_syscnr: - popl %ebp - popfl +syscall_exit: + movl %eax, EAX(%esp) + RESTORE_REGS leal sysexit, %edx movl %ebp, %ecx - sti /* sysenter会自动清除IF.貌似sysexit不会自动置位 */ + sti /* sysenter have cleared IF, and sysexit will not set IF. */ sysexit -ret_from_fork: /* for compiler now */ -bad_syscnr: +bad_sysc_nr: call sysc_bad_syscnr - jmp ret_from_bad_syscnr - -#else -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 + jmp sysc_exit - cmpl $SYSC_NUM, %eax - jae bad_syscnr - - call *sysc_handler_table(,%eax,4) - -ret_from_bad_syscnr: - - - movl %eax, 0x18(%esp) /* return value */ - - /* - * fork 后的新进程的返回值已经在栈上被设定为0了. - * ret_from_fork 就是新进程被换入执行的入口地址. - */ -ret_from_fork: - - RESTORE_REGS +ret_from_fork: + xorl %eax, %eax + jmp sysc_exit - movl 0x04(%esp), %edx /* sysexit 参数 %eip */ - movl 0x10(%esp), %ecx /* sysexit 参数 %esp */ - - #xchg %bx, %bx - sti /* sysenter会自动清除IF.貌似sysexit不会自动置位 */ - sysexit - -bad_syscnr: - call sysc_bad_syscnr - jmp ret_from_bad_syscnr -#endif - # this routine should be load align by PAGE_SIZE # this page is shared by the kernel and userspace