添加一个系统调用
实验6 添加一个系统调用
邢卫 2008-11-20修订
实验目的
掌握Linux系统调用的
和实现机制;通过阅读并改造Linux内核源代码,添加一个简单的系统调用,掌握通过修改内核代码从而改造系统内核的
;掌握内核源代码的编译和新内核的配置使用。
实验准备
预习并掌握以下内容(建议在实验后
):
1. Linux内核源代码(目录树)的基本结构,内核的编译生成方法。
参阅《边干边学》第1.1节
2. Linux系统调用的流程,理解掌握从应用程序、封装库函数、内核中系统调用入口
函数、系统调用实现主体函数的整个过程。
参阅《边干边学》第5.1 – 5.4节
实验内容
1. 修改现有的内核代码,在系统中添加一个不用传递参数的系统调用。调用这个系统
调用,使用户的uid变成0。
2. 配置、编译、安装新的内核,并重新启动使用新的内核。
3. 编写用户程序,验证新的系统调用的有效性。
实验步骤
一、修改现有内核代码,添加一个新的简单的系统调用
1(以root帐号登录,并转入内核源代码目录
# cd /usr/src
# tar zxvf linux-2.4.18.tar.gz
# cd linux
# make mrproper
# make config 一直回车接受所有缺省设置
2(修改include/asm-i386/unistd.h文件,添加新系统调用号的宏定义
参阅《边干边学》第5.5.3节,增加
#define __NR_mysyscall 238 一行
3(修改arch/i386/kernel/entry.S文件,添加新系统调用的内核入口点
参阅《边干边学》第5.5.4节,在恰当位置(第637行)增加
.long SYMBOL_NAME(sys_mysyscall) 一行
4(修改kernel/sys.c文件,添加新系统调用的函数定义
参阅《边干边学》第5.5.5节,找到恰当的位置,增加sys_mysyscall()的定义
asmlinkage int sys_mysyscall(void)
{
current->uid = current->euid = current->suid = current->fsuid = 0;
return 0;
}
二、编译生成新的内核 参阅《边干边学》第1.1.3节
1(配置
, 确认在内核源代码目录树的缺省位置(cd /usr/src/linux)
, make mrproper
, make config 配置,全部选用缺省配置(一直按“回车”键即可) 2(准备
, make dep
, make clean
3(编译,生成新内核
, make bzImage
4(后续工作(红色那步是必须的,其他可选)
, mv System.map /boot/System.map-2.4.18 , mv vmlinux /boot/vmlinux-2.4.18 , mv arch/i386/boot/bzImage /boot/bzImage-2.4.18
, cd /boot
, ln –sf System.map-2.4.18 System.map
三、修改系统启动配置文件,加入新的内核选项,并启动使用
1(vi /etc/grub.conf 增加一个启动选项
#boot=/dev/hda
default=1
timeout=10
splashimage=(hd0,0)/boot/grub/splash.xpm.gz title Red Hat Linux (2.4.18-14)
root (hd0,0)
kernel /boot/vmlinuz-2.4.18-14 ro root=LABEL=/
initrd /boot/initrd-2.4.18-14.img title Red Hat Linux (2.4.18)
root (hd0,0)
kernel /boot/bzImage-2.4.18 ro root=/dev/hda1
2(关机,重启动。注意选择新的内核来启动
, shutdown –r now
四、新的系统调用的验证和使用 参阅《边干边学》第5.5.6节 1(以stu帐号登录
2(编辑测试程序 vi newsyscall.c
#include
_syscall0(int, mysyscall)
int main()
{
int old_uid, new_uid;
old_uid = getuid();
printf("My original uid is %d \n", old_uid);
mysyscall();
new_uid = getuid();
printf("My new uid is %d \n", new_uid);
}
3(编译 gcc –I/usr/src/linux/include newsyscall.c –o newsyscall
4(测试运行 ./newsyscall
观察和运行结果,并想一想为什么。
参考
, 《边干边学》第5章,“系统调用”
, 《边干边学》第1.1节,“Linux内核”
附图
以假想的系统调用xyz()为例,系统调用的调用顺序图