您的位置:首页 > 运维架构 > Linux

【Linux OS】(实验)重建Linux内核和添加系统调用

2013-05-19 19:28 295 查看
(2009-12-27)

一、实验背景

操作系统的主要功能是为应用程序的运行创建良好的环境,为了达到这个目的,内核提供一系列具备预定功能的多内核函数,通过一组称为系统调用(system call)的接口呈现给用户。系统调用把应用程序的请求传给内核,调用相应的的内核函数完成所需的处理,将处理结果返回给应用程序,如果没有系统调用和内核函数,用户将不能编写大型应用程序。读者熟知的系统调用例子有:进程控制的fork、exit等,文件系统操作的open、close、read、write等,网络套接口的bind、accept、send、recv、sendto、recvfrom等。

二、实验目的

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

三、实验内容

在现有的系统中添加一个不用传递参数的系统调用。调用这个系统调用,使用户的uid变成0。实验主要内容:

(1)添加系统调用的名字

(2)利用标准C库进行包装

(3)添加系统调用号

(4)在系统调用表中添加相应表项

(5)sys_mysyscall的实现

(6)编写用户态测试程序

四、实验步骤

(一)重建Linux内核

(1)下载内核源代码压缩包:linux-2.6.20.tar.gz,下载地址:http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.20.tar.gz。然后将压缩包放到/usr/src目录下。

(2)进入/usr/src目录:cd /usr/src,然后解压内核包:tar zxvf linux-2.6.20.tar.gz,这样生成的内核源代码就在linux-2.6.20目录中了。

(3)进入内核代码目录:cd linux-2.6.20,执行命令:make mrproper,确保该目录下没有相关文件和配置。

(4)执行命令:make menuconfig,配置内核模块的功能。主要做了以下几项配置:选中所有支持ext3文件系统的配置项编译进内核(如图1所示);选择SCSI device support的部分功能编译进内核(如图2、图3所示)。



图1 将ext3文件系统的功能选项编译进内核



图2 将SCSI disk support功能编译进内核



图3 将SCSI low-level drivers下的BusLogic SCSI support编译进内核
(5)编译内核,执行命令:make。

(6)编译和安装内核模块,执行命令:make modules_install。

(7)安装内核,执行命令:make install。

(8)清除编译时的临时文件,执行命令:make clean。

(9)重新启动Linux操作系统。

(二)添加系统调用

(1)进入新内核源代码所在目录:cd /usr/src/linux-2.6.20。

(2)进入unistd.h文件所在目录:cd include/asm。再进入unistd.h文件对之进行编辑:vi unistd.h。在unistd.h里面添加自己的系统调用号:__NR_mysyscall,如图4所示:



图4 添加系统调用号__NR_mysyscall
(3)进入系统调用表文件所在目录:

cd /usr/src/linux-2.6.20/arch/i386/kernel,然后进入系统调用表文件对之进行编辑:vi syscall_table.S。在该文件中添加与我们定义的系统调用号相应的表项sys_mysyscall,如图5所示:



图5 添加系统调用表项sys_mysyscall
(4)系统调用的实现。进入内核代码目录下的kernel目录:

cd /usr/src/linux-2.6.20/kernel,然后进入其下的sys.c文件:vi sys.c,将系统调用实现函数sys_mysyscall(void)添加到sys.c中,该系统调用实现的功能是遍历输出进程,如图6所示:



图6 系统调用实现函数sys_mysyscall(void)
(5)按照(一)中所述重建Linux内核的方法重新编译安装内核,然后重新启动Linux操作系统。

(6)编写用户态测试程序test.c来测试我们新添的系统调用,程序如图7所示:



图7 用户态测试程序test.c
编译程序:gcc –o test test.c,运行程序:./test。

五、实验结果和分析

(一)重建Linux内核实验结果

(1)执行make命令后的结果,如图8所示:



图8 执行make后的结果
(2)执行make_modules_install命令后的结果,如图9所示:



图9 执行make_modules_install后结果
(3)执行make_install命令后的结果,如图10所示:



图10 执行make_install后结果
(4)重启Linux操作系统后显示的选择内核版本界面,表示重建内核成功,如图11所示(原lInux版本是2.4.20):



图11 选择内核版本
(二)添加系统调用测试结果

运行test后,由于mysyscall系统调用中的printk函数输出的信息在/var/log/messages文件中,所以打开该文件就可以看到运行结果了,如图12所示:



图12 运行结果

六、遇到的问题和解决方法

(1)在第一次执行make后,出现下列错误:

make[1]:***No rule to make target ‘|’,needed by ‘firmware/keyspan/usa19qi.fw.S’.Stop.

make:***[firmware] Error 2

对于此错误,执行下列编译命令:make bzImage,刚才的错误消失,取而代之的是下列错误:

OBJCOPY arch/i386/boot/compressed/vmlinux.bin

BFD: Warning: Writing section‘.bss' to huge (ie negative) file offset 0xc0277000.

objcopy: arch/i386/boot/compressed/vmlinux.bin: File truncated

make[2]: *** [arch/i386/boot/compressed/vmlinux.bin] Error 1

make[1]: *** [arch/i386/boot/compressed/vmlinux] Error 2

make: *** [bzImage] Error 2

解决方法是:在arch/i386/Makefile里面做一些修改:将OBJCOPYFLAGS所在那一行改成如下的:

OBJCOPYFLAGS :=-O binary --change-section-lma .bss-0xc0000000 –R .note -R .comment –S

改完后无论用make bzImage还是make都能编译成功。

(2)make install时报错:No module BusLogic found for kernel 2.6.20,解决方法是在/etc/modules.conf中删除BusLogic的加载项,即把下列这行注释掉:alias scsi_hostadapter BusLogic。此后make install就能成功了。

(3)当添加系统调用功能实现完后,重新编译内核时,执行make install时出现如下错误:All of your loopback devices are in use.mkinitrd failed,这时可能由于笔者还在2.6.20内核下编译,因为修改完一个版本的内核不能马上就在该版本下编译自己,所以重启系统进入原来的2.4.20-8内核下编译改后的2.6.20内核,然后make install成功。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: