Chinaunix首页 | 论坛 | 博客
  • 博客访问: 121104
  • 博文数量: 31
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 361
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-11 15:38
文章分类

全部博文(31)

文章存档

2008年(31)

我的朋友

分类: LINUX

2008-04-23 15:39:22

    今天看了一下Linux的系统调用,虽然看的不多,也不是很深,但感到收获还是挺不少的。
    一、概述
    系统调用是一个软中断,中断号是0x80,它是上层应用程序与Linux系统内核进行交互通信的唯一接口。通过int 0x80,就可使用内核资源。不过,通常应用程序都是使用具有标准接口定义的C函数库间接的使用内核的系统调用,即应用程序调用C函数库中的函数,C函数库中再通过int 0x80进行系统调用。
    所以,系统调用过程是这样的:
    应用程序调用libc中的函数->libc中的函数引用系统调用宏->系统调用宏中使用int 0x80完成系统调用并返回。
    二、相关的数据结构
     在说具体的调用过程之前,这里先要说几个数据结构。
    1)系统调用函数表
    系统调用函数表sys_call_table是在sys.h中定义的,它是一个函数指针数组,每个元素是一个函数指针,它的值是各个系统提供的供上层调用的系统函数的入口地址。也就是说通过这个表就可以调用各个系统函数。
    2)函数指针偏移宏
    这是一系列宏,它们的定义在unistd.h中,基本形式为#define _NR_name value,name为系统函数名字,value是一个整数值,是name所对应的系统函数指针在sys_call_table中的偏移量。
    3)系统调用宏
    系统调用宏_syscalln(type,name)在内核的unistd.h文件中定义的,对它展开就是:
                        type name(参数列表)
                        {
                              调用过程;
                        };
    其中,n为参数个数,type为函数返回值类型,name为所要调用的系统函数的名字。在unistd.h中共定义了4个这样的宏(n从0到3),也就是说,0.11核中系统调用最多可带3个参数。
那么下面就说这个宏干了什么,也就是说上面的那个“调用过程”是怎么样的呢?在这个宏中嵌入了汇编代   码,做的工作就是int 0x80,其中将字符串“_NR_”和name连接,组成一个宏并将这个宏的值,也就是系统   函数在sys_call_table中偏移量送到eax中;同时指明系统函数将来的返回值放到eax中。
  三、系统调用处理过程
     下面我再说一下系统调用的核心软中断int 0x80具体干了什么。这条指令会引起CPU的软件中断,cpu会根据中断号找到中断处理程序。这个中断处理程序是在System_call.s中。在中断处理程序的工作过程大致是这样的:
     1)将寄存器ds,es,fs以及存有参数的edx,ecx,ebx入栈,再ds,es,指向内核段,fs指向用户段。
     2)根据eax中的偏移值,在函数表sys_call_table中找到对应的系统函数指针(函数的入口地址)。并利用call指令调用系统函数,返回后,程序把返回值加入堆栈。
     3)检查执行本次系统调用的进程的状态,如果发现由于某种原因原进程没处在就绪状态或者时间片到了,就会执行进程调度函数schedule()。
     4)通过执行这次调用的程序的代码选择符判断它是不是普通用户程序,如果是就调用信号处理函数。若不是就直接弹出栈内容,并返回。
阅读(1155) | 评论(0) | 转发(0) |
0

上一篇:Linux栈的使用

下一篇:Linux硬件-门描述符

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