您的位置:首页 > 运维架构 > Linux

linux内核分析——扒开系统调用的三层皮(上)

2016-03-20 17:59 411 查看
20135125陈智威原创作品转载请注明出处《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000系统调用:库函数封装了系统调用,通过库函数和系统调用打交道用户态:低级别执行状态,代码的掌控范围会受到限制。内核态:高执行级别,代码可移植性特权指令,访问任意物理地址为什么划分级别:如果全部特权,系统容易崩溃系统调用的三层皮:xyz,system_call,sys_xyz。即:API,中断向量,服务程序。xyz()函数是系统调用对应的API,这个应用程序编程接口里面封装了一个系统调用,这个系统调用会触发一个int0x80的中断,产生向量为128的编译异常,0x80这个中断向量对应着system_call这个内核代码的起点,这个内核代码里面会有SAVE_ALL,然后执行到sys_xyz()中断服务程序,进入程序里面处理,在中断服务程序执行完之后会ret_from_sys_call,在return的过程中可能会发生进程调度,如果没有进程调度,就会iret,回到用户态接着执行。

内核实现了很多不同的系统调用, 进程必须指明需要哪个系统调用,这需要传递一个名为系统调用号的参数

system_call是Linux中所有系统调用的入口点,每个系统调用至少有一个参数,即由eax传递的系统调用号。具体过程如下:

1.一个应用程序调用fork()封装例程,那么在执行int $0x80之前就把eax寄存器的值置为2(即__NR_fork)。 2.这个寄存器的设置是libc库中的封装例程进行的
,因此用户一般不关心系统调用号 3.进入sys_call之后,立即将eax的值压入内核
堆栈
寄存器传递参数也有相应的限制:1.每个参数长度不能超过寄存器的长度(32位)2.在eax外,参数的个数不能超过6个(ebx,ecx,edx,esi,edi,ebp),超过6个就使用指针调用某一个块的内存。3、使用库函数API和C代码中嵌入汇编代码触发同一个系统调用:使用库函数获取系统当前的时间:命令:编写time程序:vi time.c编译:gcc time.c -o time -m32执行:./time实验总结:我认为系统调用的工作机制是:当用户态进程调用一个系统调用时,CPU切换到内核态并开始执行一个内核函数,由API、中断向量和中断处理程序协调完成。而在系统调用的过程中,系统调用号使用eax寄存器传递参数。
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: