Exam02_实验2添加系统调用.docVIP

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Exam02_实验2添加系统调用

添加系统调用 实验目的 学习Linux内核的系统调用,理解、掌握Linux系统调用的实现框架、用户界面、参数传递、进入/返回过程。 实验内容 本实验分两步走。 第一步,在系统中添加一个不用传递参数的系统调用;执行这个系统调用,使用户的uid等于0。显然,这不是一个有实际意义的系统调用。我们的目的并不是实用不实用,而是通过最简单的例子,帮助熟悉对系统调用的添加过程,为下面我们添加更加复杂的系统调用打好基础。 第二步,用kernel module机制,实现系统调用gettimeofday的简化版,返回调用时刻的日期和时间。 实验指导 2.1一个简单的例子 在我们开始学习系统调用这一章之前,让我们先来看一个简单的例子。就好像哪个经典的编程书上都会使用到的例子一样: 1: int main(){ 2: printf(“Hello World!\n”); 3: } 我们也准备了一个例子给你: 1: #include linux/unistd.h /* all system calls need this header */ 2: int main(){ 3: int i = getuid(); 4: printf(“Hello World! This is my uid: %d\n”, i); 5: } 这就是一个最简单的系统调用的例子。与上面那个传统的例子相比,在这个例子中多了2行,他们的作用分别是: 第一行:包括unistd.h这个头文件。所有用到系统调用的程序都需要包括它,因为系统调用中需要的参数(例如,本例中的“__NR_getuid”,以及_syscall0()函数)包括在unistd.h中;根据C语言的规定,include linux/unistd.h意味着/usr/include/linux目录下整个unistd.h都属于Hello World源程序了。 第三行:进行getuid()系统调用,并将返回值赋给变量i。 好了,这就是最简单的一个使用了系统调用的程序,现在你可以在你的机器上试一试它。然后我们一起进入到系统调用的神秘世界中去。 2.2 简单系统调用的添加 在这一节中,我们将要实现一个简单的系统调用的添加。我们先给出题目: 题目 :在现有的系统中添加一个不用传递参数的系统调用。 功能要求:调用这个系统调用,使用户的uid等于0。 目的 :显然,这不是一个有实际意义的系统调用,我们的目的并不是有用,而是一种证明,一个对系统调用的添加过程的熟悉,为下面我们添加更加复杂的系统调用打好基础。 怎么样?觉得困难还是觉得太简单?我们首先承认,每个人接触Linux的时间长短不一样,因此基础也会有一点差别。那么对于觉得太简单的人呢,请你迅速地合上书本,然后跑到电脑前面,开始实现这个题目。来吧,不要眼高手低,做完之后,你就可以跳过这一节,直接进入下一节的学习了。对于觉得有点困难的人呢,不用着急,这一节就是专门为你准备的。我们会列出详细的实现步骤,你一定也没有问题的。 如果你前面对整个系统调用的过程有一个清晰的理解的话,我们就顺着系统调用的流程思路,给出一个添加新的系统调用的步骤: 2.2.1决定你的系统调用的名字 这个名字就是你编写用户程序想使用的名字,比如我们取一个简单的名字:mysyscall。一旦这个名字确定下来了,那么在系统调用中的几个相关名字也就确定下来了。 系统调用的编号名字:__NR_mysyscall; 内核中系统调用的实现程序的名字:sys_mysyscall; 现在在你的用户程序中出现了: #include linux/unistd.h int main() { mysyscall(); } 流程转到标准C库。 2.2.2利用标准C库进行包装吗 编译器怎么知道这个mysyscall是怎么来的呢?在前面我们分析的时候,我们知道那时标准C库给系统调用作了一层包装,给所有的系统调用做出了定义。但是显然,我们可能不愿意去改变标准C库,也没有必要去改变。那么我们在自己的程序中来做: #include linux/unistd.h _syscall0(int,mysyscall) /* 注意这里没有分号 */ int main() { mysyscall(); } _syscall0这个宏,mysyscall将得到定义。但是现在系统会去找系统调用号,以放入eax。所以,接下来我们定义系统调用号。 2.2.3添加系统调用号 系统调用号在文件unistd.h里面定义。这个文件可能在你的系统上会有两个版本:一个是C库文件版本,出现的地方是在/usr/include/unistd.h和/usr/include/asm/unistd.h;另外还有一个版本是内核自己的unistd.h,出现的地方是在你解压出来

文档评论(0)

xy88118 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档