操作系统原理-实验-linux增加系统调用

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

中国地质大学(武汉)《操作系统原理》课程实验报告
数据科学与大数据技术专业
班级195182学生姓名钟欢
任课教师康晓军
完成时间2020年3月31日
实验一——实现一个linux的系统调用
一、实验目的
1.加深对系统调用的理解,掌握增加与调用系统调用的方法。

2.掌握内核编译方法。

二、实验思路
1.增加新的系统调用:
新增的系统调用名为Hello,其功能是打印输出“This is ZhongHuan ’ s system call ! wo zhong yu cheng gong le !”
2.编译内核:
用编译内核的方法,将其增加进内核源码并编译内核。

3.测试:
在用户控件编写测试程序测试该系统调用。

三、实验步骤
1.系统调用的添加
在Linux中添加新的系统调用,需执行多个步骤才能添加成功:
(1)第一步
完成系统调用函数在内核源码目录kernel/sys.c文件中编写待添加的系统调用函数。

该函数的名称应该是新的系统调用名称前面加上sys_标志。

新加的系统调用为hello(void),在kernel/sys.c文件中添加源代码:asmlinkage long sys_hello(void)
{
printk("This is ZhongHuan's system call! wo zhong yu cheng gong le!");
return 1;
}
(2)第二步
在系统函数表中表项添加新的系统调用后,需要让Linux内核的其余部分知晓该程序的存在。

在内核源码目录arch/x86/entry/syscalls下修改文件syscall_64.tbl。

该文件用来对sys_call_table[]数组实行原始化,数组包含指向内核中每个系统调用的指针。

在该文件中的最后一行添加自己的系统调用表项:335 64 hello sys_hello(),这样就在数组中添加了新的内核函数指针。

(3)第三步
添加系统调用号在内核源码目录arch/x86/include/asm下修改头文件unistd_32.h。

该文件包含系统调用清单,用来给每个系统调用分配一个独一的号码。

文件中每一行的格式如下:
#define__NR_nameNNN
其中,name用系统调用名称代替,而NNN则是该系统调用对应的号码。

应该将新的系统调用名称加到清单的结尾,并给它分配号码序列中下一个可用的系统调用号。

在该文件后面添加系统调用号:
#define__NR_hello 335
修改系统中所用的系统调用数目:
#define_NR_syscalls 336
这里系统调用号为335,是因为Linux-2.6内核自身的系统调用号码已经用到334,新添加的系统调用号不能与前面已有的重复。

至此系统调用的
添加已经完成,然后就是重新编译内核,用新的内核引导即可使用新的系统调用。

新系统调用的测试代码中,使用syscall()函数,通过指定它的调用索引和一组参数来调用系统调用,如syscall(335),其中335是系统调用号,因为新加的系统调用函数是无参函数,所以不需要添加参数。

2.Linux内核编译
作为自由软件,在广大爱好者的支持下,Linux内核版本不断更新。

新内核修订了旧内核的bug,并增加了许多新特性。

如果用户想要使用这些新特性,或想根据自己的系统度身定制一个更高效、更稳定的内核,就需要重新编译内核通常,更新的内核会支持更多的硬件,具备更好的进程管理能力,运行速度更快、更稳定,并且会修复老版本中发现的许多洞等,经常性地选择升级更新的系统内核是Linux使用者的必要操作内容。

要增加对某部分功能的支持,比如网络之类,可以把相应部分编译到内
核中(build-in),也可以把该部分编译成模块(module),动态用。

如果将要增加对某部分功能编译到内核中,在内核启动时就可以自动支持相应部分的功能,其优点是方便、快速,机器一启动,就可以使用这部分能;缺点是会使内核变得庞大,不管是否需要这部分功能,它都会存在。

建议经常使用的部分直接编译到内核中,比如网卡。

如果编译成模块,就会生成对应的.o文件,使用时动态加载,优点是不会使内核过分庞大,缺点是需要手工调用这些模块。

编译内核的流程如下:
(1)第一步:下载内核
到下载新内核到/usr/src(如linux-2.6.34.tar.bz2),然后将其解压到/usr/src目录下,得到linux-2.6.34:tar-jxvflinux-
2.6.34.tar.bz2。

如果下载的是.tar.gz(.tgz)文件,使用命令tar-zxvflinux-2.6.34.tar.gz。

(2)第二步:配置内核
配置内核之前,先用命令“makeclean”清除原有不需要的模块和文件,命令“make mrproper”把原来编译产生的垃圾删除。

配置内核可以根据需要与爱好使用下面命令中的一个。

#make config(基于文本的、最为传统的配置界面)
#make menuconfig(基于文本选单的配置界面)
#make xconfig(基于图形窗口模式的配置界面)
#make oldconfig(如只需在原来内核配置的基础上修改一些小地方,该命令会省去不少麻烦)
这几个命令中,makexconfig的界面最为友好(需要Xwindow的支持),make menuconfig次之。

进行配置时,大部分选项可以使用其缺省值,只有小部分需要根据用户不同的需要选择。

选择的原则是将与内核其他部分关系较远且不经常使用的部分功能代码编译成为可加载模块,有利于减小内核的长度,减小内核消耗的主存,简化该功能相应的环境改变时对内核的影响;不需要的功能不要选;与内核关系紧密而且经常使用的部分功能代码直接编译到内核中。

在添加新的系统调用后重构内核时,执行make menuconfig,利用当前的内核配置详单设置将要编译的内核(即选择默认选项)后存盘退出即可。

(3)第三步:编译内核
在内核源码目录下执行:
#make clean(确保所有有关文件都处于最新版本状态)
#make或makezImage(编译内核,makezImage可以编译压缩形式的内核)在需要内核支持较多的外设和功能时,内核可能变得很大,此时可以利用make bzImage编译大内核。

如果选择了可加载模块,编译完内核后,需要对选择的模块进行编译:
#make modules(编译选择的模块)
#make modules_install(将编译后的模块转移到系统标准位置)
#make install(把压缩内核映象拷贝到/boot目录下,并创建相应的System.map符号链接)
(4)第四步:启动项配置
调用mkinitrd程序创建内核的initrd映象:mkinitramf–o/boot/initrd.img-2.6.34.6在/boot/grub/grub.cfg中设置启动项的配置:照着原来的inux-headers-2.6.32-24-generic增加linux-2.6.34.6。

至此,整个内核的编译就全部完成。

重启系统时,选择进入新的内核就可以使用新内核了。

3.测试添加的系统调用
编写程序验证:创建C程序并执行系统调用
(1)安装vim:在终端输入命令sudo apt-get install vim
(2)使用vim建立c文件:终端输入命令vim hello.c
(hello.c为我的文件名)
(3)键盘上点字母a,进入插入(insert)模式,在编辑区输入主程序代码(如下图,图中335为之前自己添加的系统调用号)
int main()
{
syscall(335);
syscall(335);
syscall(335);
syscall(335);
syscall(335);
syscall(335);
syscall(335);
syscall(335);
syscall(335);
syscall(335);
syscall(335);
return 0;
}
(4)保存并退出:按一下Esc键,输入:wq 点回车,则保存并退出(5)编译c程序:终端输入命令:gcc -o hello hello.c
(6)执行:终端输入命令 ./hello,终端输入dmesg查看结果
(7)完成实验
实验二——实现一个U盘的启动程序
(1)设置bios为u盘启动优先
(2)写一小段汇编程序,调用bios中断输出一个字符(或字符串)汇编程序如下:
org 0x7c00
mov ax, cs
mov ds, ax
mov es, ax
call dispstr
jmp $
dispstr:
mov ax, 0x1301
mov bx, 0x000c
mov cx, 10
mov dx, 0x1010
mov bp, BootMessage
int 0x10
ret
BootMessage: db "hello zhonghuan!", 0
times 510-($-$$) db 0
dw 0xaa55
(3)编译程序为二进制代码
(4)将程序段写入U盘的mbr
(5)开机后,屏幕输出你设定好的字符(字符串)
(6)完成实验。

相关文档
最新文档