linux 系统调用浅析

linux 系统调用浅析

刘柳 + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程+http://mooc.study.163.com/course/USTC-1000029000+titer2008@gmail.com
这期作业比较草率,后期将重新布局,请大家监督。

1)系统调用的流程图

linux 系统调用浅析_第1张图片
以上图是fork调用为实例说明问题,
1)当调用 Int 0x80 ,发生栈切换
2)切换后查找系统调用表
3)寻找到对应的系统调用执行,后期返回用户空间


2)系统调用号实例

%eax

Name

%ebx

%ecx

%edx

%esx

%edi

1

sys_exit

int

-

-

-

-

2

sys_fork

struct pt_regs

-

-

-

-

3

sys_read

unsigned int

char *

size_t

-

-

4

sys_write

unsigned int

const char *

size_t

-

-

5

sys_open

const char *

int

int

-

-

6

sys_close

unsigned int

-

-

-

-


3)参数传递过程的思考


常规函数调用
(不涉及到系统特权级别改变)
系统调用
传入参数的约定 32bit系统下,常用ebp一个进行寻址
个数为6个,
超过6个的话,利用ebx

一次系统调用中,只使用ebxecxedxesiedi五个寄存器来保存相对程序来说的输入数据,这些输入数据其实是传递给在系统调用过程中所访问的内核函数的实参。输入数据被保存的顺序如下:

  • ebx---第一个参数
  • ecx—第二个参数
  • edx—第三个参数

 

  • esi—第四个参数
  • edi—第五个参数

对于超过六个参数的情况是使用ebx保存相继而存的数据所在内存的起始地址。系统调用通过ebx内的地址访问这些数据。


返回错误码
系统变量errno
需要用户指定接受变量
            



4)代码实例(以chmod为例子)


linux 系统调用浅析_第2张图片

原始嵌入式汇编代码
linux 系统调用浅析_第3张图片

代码中,对于参数传入有些简略,故在代码注释里详细说明。

#include <stdio.h>
#
include <sys/types.h>
#
include <sys/syscall.h>
#
include <errno.h>

int main()
{
        
long rc;
        
char *file_name = "/etc/passwd";
        
unsigned short mode = 0444;

asm(
                
"int $0x80"
                
"=a" (rc)
                
"0" (SYS_chmod), "b" ((long)file_name), "c" ((long)mode)
        );

if ((unsigned long)rc >= (unsigned long)-132) {
                errno = -rc;
                rc = -
1;
        }

 

if (rc == -1)
                
fprintf(stderr, "chmode failed, errno = %d\n", errno);
        
else
                
printf("success!\n");

return 0;
}


运行过程介绍

运行纯版本,我们看到chmod在普通用户态(444)不能修改,超级用户状态下成功修改。达到预期。
linux 系统调用浅析_第4张图片

运行嵌入汇编版本,与纯c版本效果一致。

linux 系统调用浅析_第5张图片


5)总结
系统调用的工作机制
不同于用户态系统调用,这里涉及到用户态/核心态的切换;
特殊的场景,决定了参数的传递(个数/大小)都受到约束;
认识系统调用的最好方式是从汇编形式一行行复原出c代码的效果;


参考:
http://www.cnblogs.com/hazir/p/three_methods_of_syscall.html

todo:高级话题

自添加系统调用,内核断点 b   system_call
systementer
printf(李先进 ,strace)

参数:(没有参数的  fork...getpid,有多个参数的,超过6个参数的,结构体???)

你可能感兴趣的:(linux 系统调用浅析)