Chinaunix首页 | 论坛 | 博客
  • 博客访问: 526740
  • 博文数量: 96
  • 博客积分: 2102
  • 博客等级: 上尉
  • 技术积分: 1695
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-11 22:12
文章分类

全部博文(96)

文章存档

2014年(2)

2012年(94)

分类: LINUX

2012-04-15 18:39:25

         在操作系统中我们进程会听到‘系统调用’。并且在变编程中我们用到的很多函数都是通过系统调用实现的。例如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__));
……

阅读(2900) | 评论(3) | 转发(1) |
0

上一篇:程序编译的过程

下一篇:时间片 time_slice

给主人留下些什么吧!~~

glinuxi2012-04-17 17:06:24

对于程序返回值,是由寄存器eax存着的,使用fork后,父子进程分离开来,对于父进程的eax=子进程的pid,子进程的eax=0

十七岁的回忆2012-04-16 21:16:28

请问楼主
fork()返回值的不同      是如何实现的

☆彼岸★花开2012-04-16 21:05:36

文章不错,值得收藏。。。