免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2345 | 回复: 0
打印 上一主题 下一主题

由表及里之系统调用(getpid) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-27 00:56 |只看该作者 |倒序浏览

                1.看一段程序
这个程序调用了一个函数getpid(),用于获取当前进程的ID号。
               
               
                #includestdio.h>
#includeunistd.h>
int main()
{
    int id;
    id=getpid();
    printf("%d",id);
    reurn 0;
}
2. getpid()是什么?在哪里声明?在哪里实现?
(1)getpid()是一个POSIX标准的API,用于用户程序从用户态进入到内核态,在内核态读取当前进程的(tack_struct)的Pid,然后
返回给用户态的程序。
(2)getpid()函数在/usr/include/unistd.h里面声明。你可以试着找到这个声明。
(3)getpid()函数在glibc函数库里面实现。gcc 编译程序时,会到glibc函数库里面寻找getpid()的实现代码,然后编译。
[是所有API都要进入内核态吗?NO.比如字符串函数strcpy()就不会进入内核态。要请求操作系统服务的API才进入内核态。]
3. getpid()是怎么使cpu进入内核态的?getpid()往内核传递了什么信息?从内核获得了什么信息?
(1)getpid()是通过软中断的方式使程序进入内核态的。getpid()编译成汇编代码时,里面会有条这样的指令:int 0x80,当执行到这条
指令时,getpid()的工作暂停,内核开始工作。
(2)getpid()的功能是返回当前进程的ID,它本身是不能完成的,必须请求操作系统服务,让操作系统把当前进程的ID告诉给getpid().
操作系统能够提供很多服务,那么,getpid()就得告诉操作系统提供什么服务,所以,getpid()给内核一个参数__NR_getpid(系统调用号),
把__NR_getpid这个服务号(系统调用号),放在了一个寄存器eax里面。内核就从eax这个寄存器里面取出值,就明白了:哦!原来getpid()是让
我提供__NR_getpid这个服务啊。[当API请求服务时,可能会告诉内核多个参数,这时就要把这些参数放在:
ebx --- 置第一个参数
ecx --- 置第二个参数
edx --- 置第三个参数
esi --- 置第四个参数
edi --- 置第五个参数
ebp --- 置第六个参数 (系统调用最大参数个数为6)]
(3)getpid()自然从内核得到当前进程的ID号,因为内核已经把ID号放在了getpid()的堆栈里面。
getpid()是在glibc里面实现的。实现过程大概入下:
getpid()
{
    往exa寄存器存入__NR_getpid;
    int 0x80,产生软中断。
    ---------
    内核执行
    ---------
    从堆栈里面读取ID返回。
}
不要到glibc库里面去看,只会浪费时间,因为很难明白。
4. 内核是如何为getpid()提供服务的?具体过程是什么?
int 0x80 ; 进入软中断,cpu进入高级特权模式
   
CPU到地址(中断描述符表IDT地址 + 0x80),取出指令并执行。执行结果,跳到标号system_call处执行;
system_call:
           保存现场;
           读取exa寄存器的值__NR_getpid;
           读取数组 sys_call_table[__NR_getpid]的值;这个值就是__NR_getpid()服  务程序的地址;
           跳到__NR_getpid()服务程序的地址,执行。即,执行内核函数,sys_getpid();
                           
           [sys_getpid()读取用户进程数据结构task_struct的成员变量pid,把用户进程的pid放在了eax寄存器中。]
                           
           把eax寄存器的值复制到用户态”eax寄存器栈单元“里面。
         
           恢复现场,返回到用户态。
5. getpid()在eax寄存器栈单元里面取出pid,给用户程序。一切ok!
后记:网上任何人写的文档都不如,Source Insight + linux内核源代码。内核的学习是不能故意去学习的,只能是你在高层想知道内核是怎么工作的时候才去看看代码。下一篇博客将是有关Bootloder方面的。
参考博客:
http://www.yuanma.org/data/2009/0208/article_3495.htm
关于gcc,libc等相关概念的理解
http://blog.openrays.org/blog.php?do=showone&tid=422
绕过 libc 直接使用系统调用
http://www.kerneltravel.net/journal/iv/syscall.htm
系统调用
http://www.diybl.com/course/6_system/linux/Linuxjs/200798/70550.html
系统调用
http://book.51cto.com/art/200810/93819.htm
使用通用接口
http://book.51cto.com/art/200810/93813.htm
linux内核标准教程
http://blog.csdn.net/sylin/archive/2006/07/20/949420.aspx
被glibc忽悠了
http://book.51cto.com/art/200810/93826.htm
系统调用过程
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/108840/showart_2131840.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP