Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2050850
  • 博文数量: 610
  • 博客积分: 11499
  • 博客等级: 上将
  • 技术积分: 5511
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-12 19:27
文章分类

全部博文(610)

文章存档

2016年(5)

2015年(18)

2014年(12)

2013年(16)

2012年(297)

2011年(45)

2010年(37)

2009年(79)

2008年(101)

分类:

2012-04-16 11:13:37

         在操作系统中我们进程会听到‘系统调用’。并且在变编程中我们用到的很多函数都是通过系统调用实现的。例如fork() 函数、pause() 函数 、printf() 函数……
         我学习了linux 0.11 内核的系统调用。
         系统调用使用的函数名叫做:syscall [0,1,2……], 标注:在方括号的数字表示的系统调用的函数含有几个参数。其中syscall函数在system_call.s 实现。
        对于系统调用实际就是:用户使用终端调用int 0x80和放在eax寄存器的功能号来使用呢和提供的 各种功能服务。操作系统提供的功能叫做系统调用。
        对于所用系统调用的实现函数,内横将它们按照系统调用功能号数排列成一张函数指针表(在include/linux/sys.h): sys_call_table(72个)。然后在中断 int 0x80 的处理过程中根用户提供的功能号调用对应的系统调用函数。sys_name
         对于系统调用的中断处理过程,可以将它看作一个'接口'进程。
        这个程序在刚开始检测eax(功能号)是否有效。如果无效在退出。否则保存一些有用的寄存器的值到堆栈上,例如 linux 内核默认把段寄存器ds,es存储内核数据段,而fs用于用户数据段。然后根据地址跳转表(sys_call_table)调用对应的C语言。在C语言调用完之后将返回值压入栈保存其来。
       接下来查看当前进程的状态,如果进程已经不出运行状态(由于调用函数、时间片用完等其他原因)则调用schedule函数。由于在调度函数在运行之前已将返回地址ret_from_sys_call入栈了,所以只要调用schedule后最终返回即可。从ret_from_sys_call 开始做一些系统调用后的处理工作。
      1》如果当前进程为进程0 ,在直接退出此次系统调用,中断返回
      2》如果当前进程是内核进程(根据代码段描述符和堆栈判断),弹出栈 ,终中断返回
      在末端用来处理调用系统调用的信号。
      最后,该程序回复保存的寄存器内容,推出此次中断并且返回
     
在main.c中:
static inline _syscall0(int, fork);因为inline是替换的意思:

点击(此处)折叠或打开

  1. static inline int fork(void)
  2. {
  3. __asm__ volatile("int $0x80","=a"(__res):"0"(NR_fork));
  4. if(__res>=0)
  5. return (int)__res;
  6. errno = -__res;
  7. return -1;
  8. }

在linux 中sys_fork在sys_call.s中实现
流程:
call  find_empty_process ------>返回nr
call copy_process------->创建进程,将父进程想过数据结构赋值到子进程。
           |
           |
      copy_mem   此时父子进程共享地址空间
 
标注; 在用户态调用fork时,我使用命令:gcc -E name.c -o name,i
……
extern __pid_t fork (void) __attribute__ ((__nothrow__));
……

阅读(624) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~