欢迎来到天天文库
浏览记录
ID:40749646
大小:477.33 KB
页数:11页
时间:2019-08-07
《linux0.11系统调用原理及实验总结》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、Linux0.11系统调用原理及实验总结1系统调用的原理1.1概述系统调用是一个软中断,中断号是0x80,它是上层应用程序与Linux系统内核进行交互通信的唯一接口。通过int0x80,就可使用内核资源。不过,通常应用程序都是使用具有标准接口定义的C函数库间接的使用内核的系统调用,即应用程序调用C函数库中的函数,C函数库中再通过int0x80进行系统调用。 所以,系统调用过程是这样的: 应用程序调用libc中的函数->libc中的函数引用系统调用宏->系统调用宏中使用int0x80完成系统调用并返回。另外一种访问内核的方式是直接添
2、加一个系统调用,供自己的应用程序使用,这样就不再使用库函数了,变得更为直接,效率也会更高。1.2相关的数据结构 在说具体的调用过程之前,这里先要说几个数据结构。1.2.1 系统调用函数表 系统调用函数表sys_call_table是在sys.h中定义的,它是一个函数指针数组,每个元素是一个函数指针,它的值是各个系统提供的供上层调用的系统函数的入口地址。也就是说通过查询这个表就可以调用软中断0x80所有的系统函数处理函数。1.2.2 函数指针偏移宏 这是一系列宏,它们的定义在unistd.h中,基本形式为#define_N
3、R_namevalue,name为系统函数名字,value是一个整数值,是name所对应的系统函数指针在sys_call_table中的偏移量。1.2.3系统调用宏 系统调用宏_syscalln(type,name)在内核的unistd.h文件中定义的,对它展开就是:typename(参数列表){调用过程;};其中,n为参数个数,type为函数返回值类型,name为所要调用的系统函数的名字。在unistd.h中共定义了4个这样的宏(n从0到3),也就是说,0.11核中系统调用最多可带3个参数。那么下面就说这个宏干了什么,也就是说上
4、面的那个“调用过程”是怎么样的呢?在这个宏中嵌入了汇编代码,做的工作就是int0x80,其中将字符串“_NR_”和name连接,组成一个宏并将这个宏的值,也就是被调用的系统函数在sys_call_table中偏移量送到eax寄存器中;同时指明系统函数将来的返回值放到eax中。1.1系统调用处理过程 下面我再说一下系统调用的核心软中断int0x80具体干了什么。这条指令会引起CPU的软件中断,cpu会根据中断号找到中断处理程序。这个中断处理程序是在System_call.s中。在中断处理程序的工作过程大致是这样的:1.1.1将寄存器
5、ds,es,fs以及存有参数的edx,ecx,ebx入栈,再ds,es,指向内核段,fs指向用户段。1.1.2根据eax中的偏移值,在函数表sys_call_table中找到对应的系统函数指针(函数的入口地址)。并利用call指令调用系统函数,返回后,程序把返回值加入堆栈。1.1.3检查执行本次系统调用的进程的状态,如果发现由于某种原因原进程没处在就绪状态或者时间片到了,就会执行进程调度函数schedule()。1.1.4通过执行这次调用的程序的代码选择符判断它是不是普通用户程序,如果是就调用信号处理函数。若不是就直接弹出栈内容,
6、并返回2添加一个系统调用的实验2.1实验内容在linux0.11版本中添加两个系统调用,并编写一个简单的应用程序测试它们。第一个系统调用是iam(),其原型为:intiam(constchar*name);完成的功能是将字符串参数name的内容拷贝到内核中保存下来。要求name的长度不能超过23个字符。返回值是拷贝的字符数。如果name的字符个数超过了23,则返回“-1”,并置errno为EINVAL。第二个系统调用是whoami(),其原型为:intwhoami(char*name,unsignedintsize);它将内核中由
7、iam()保存的名字拷贝到name指向的用户地址空间中,同时确保不会对name越界访存(name的大小由size说明)。返回值是拷贝的字符数。如果size小于需要的空间,则返回“-1”,并置errno为EINVAL。2.2代码添加修改步骤2.2.1在unistd.h中添加系统调用接口#define__NR_whoami72#define__NR_iam73intwhoami(void);intaim(void);1.1.1在exit.c文件中添加系统调用处理函数的实现系统调用的函数可以在其他.c文件中添加或在新建文件中添加,只要编
8、辑进image都是可以的,这里为了调试方便就在exit.c文件中添加了。#defineMAX23charN_MAX[26];intsys_whoami(char*name,unsignedintsize){if(strlen(N_MAX)>size
此文档下载收益归作者所有