(操作系统课程项目)系统调用

来源:互联网 发布:最牛象棋软件 编辑:程序博客网 时间:2024/05/22 17:00

一、实验目的

学习Linux内核的系统调用,理解、掌握Linux系统调用的实现框架、用户界面、参数传递、进入/返回过程。阅读Linux内核源代码,通过添加一个简单的系统调用实验,进一步理解Linux操作系统处理系统调用的统一流程。

二、实验内容

1.修改“任务一”下载的内核源码,加入自己的系统调用

2.系统调用的功能是将自己的名字和学号在终端或内核日志里显示出来(printk

3.重新编译内核

4.编写用户态程序,调用前面自己所加入的系统调用,运行输出,输出结果

三、实验仪器设备

Linux环境:CentOS_6.5,内核3.16.3

待编译的内核:Linux3.16.3

四、实验步骤

1.下载并部署内核源代码

此步已经在实验一中完成。

2.修改内核的系统调用库函数

       a.CentOS6.5(可不用修改)

       /usr/include/asm-generic/unist.h文件中修改

       b.内核3.16.3(要修改)

# cd  /usr/src/kernels/linux-3.16.3/  进入已经解压的目录,之后终端界面一直停留在这个目录。

     #vimusr/include/asm/unistd_64.h由于是64位的操作系统,故选择进入unistd_64.h进行编辑。如果是32位的操作系统,就选择对unistd_32.h进行编辑。添加系统调用号#define  __NR_name ×××,其中,name为你要添加的名称,×××为系统调用号,此时要注意不同版本的内核版本调用号不一样,可以根据内核版本不同对系统调用号进行修改,系统调用号应该是没有用过的,如下图所示:


3.在系统调用表中添加或修改相应表项

系统调用处理程序(system_call)会根据eax中的索引到系统调用表(sys_call_table)中寻找相应的表项。所以,我们必须在那里添加我们自己的一个值。在3.16.3的内核中,只需要修改arch/x86/syscalls/syscall_64.tbl。注意,32位机选择syscall_32.tbl文件。#vimarch/x86/syscalls/syscall_64.tbl进入文件:


注意,<number>为选择的系统调用号,<entry_point>为要进入的系统调用函数。修改如下:


 到现在为止,系统已经能够正确地找到并且调用sys_rksyscall。剩下的就只有一件事情,那就是sys_rksyscal的实现。

4. sys_rksyscal的实现

       我们把一小段程序添加在kernel/sys.c里面。在这里,我们并没有在kernel目录下另外添加自己的一个文件,这样做的目的是为了简单,而且不用修改makefile,省去不必要的麻烦。

       #vimkernel/sys.c进入sys.c文件进行修改,修改如下:


5.重新编译内核

一定要重新编译内核。内核编译完成后,重新启动编译后的新内核。

6.编写用户态程序

要测试新添加的系统调用,需要编写一个用户态测试程序(test.c)调用mysyscall系统调用。mysyscall系统调用中printk函数输出的信息在/var/log/message文件中。也可以在shell下用dmesg命令查看。用户态测试程序实现如下:


#gcc –o test  test.c   gcc编译程序

#./test    运行程序

#dmesg 查看日志,截图如下:


一、实验问题

1) 详细描述完成整个任务遇到的问题和解决问题的方法;

重点解决上述要注意的问题。

2) 回答问题:“什么是操作系统的系统调用(system call)?系统调用过多会引起进程的性能开销么?为什么?”

Linux内核中设置了一组用于实现各种系统功能的子程序,称为系统调用。用户可以通过系统调用命令在自己的应用程序中调用它们。从某种角度来看,系统调用和普通的函数调用非常相似。区别仅仅在于,系统调用由操作系统核心提供,运行于核心态;而普通的函数调用由函数库或用户自己提供,运行于用户态。系统调用过多会引起进程的性能开销,因为系统调用需要从用户空间陷入内核空间,处理完后,又需要返回用户空间。其中除了系统调用服务例程的实际耗时外,陷入/返回过程和系统调用处理程序(查系统调用表、存储\恢复用户现场)也需要花销一些时间,这些时间加起来就是一个系统调用的响应速度。系统调用不比别的用户程序,它对性能要求很苛刻,因为它需要陷入内核执行,所以和其他内核程序一样要求代码简洁、执行迅速。



0 0
原创粉丝点击