OS添加系统调用
OS添加系统调用
一 题目介绍
让系统倒计时指定秒数后重启
提示:可能会用到reboot()函数或者kernel_restart()。
二 实验思路
环境:ubuntu18.04
一、源码阅读
1、用uname -r查看ubuntu适合的内核源码版本,下载v5.4.218并解压至/usr/src。地址:https://www.kernel.org/
2、Linux内核中设置了一张系统调用表,用于关联系统调用号及其相对应的服务例程入口地址,定义在./arch/x86/entry/syscalls/syscall_64.tbl文件中。
系统调用服务例程:每个系统调用都对应一个内核服务例程来实现系统调用的功能,其命名的格式都是以”sys_开头。其代码通常放在./kernel/sys.c中,服务例程的原型声明则是放在./include/liux/syscall.nh中。
找到reboot的调用号
3、查看系统调用表
四列分别为系统调用号、应用二进制接口、系统调用名、服务例程入口地址。
4、阅读内核源码,阅读reboot函数。本部分请移步到我的另一篇文章:系统重启-Linux内核源码阅读
二、编写系统调用函数
1、打开/usr/src/linux-4.19.25/arch/x86/entry/syscalls/syscall_64.tbl修改系统调用表,添加系统调用表表项。
2、打开/usr/src/linux-4.19.25/include/linux/syscalls.h,在文件最后声明系统调用服务例程。(tips:vim中shift+G快速移动到文件末端)
3、打开/usr/src/linux-4.19.25/kernel/sys.c,实现系统调用服务例程
4、使用命令sudo apt-get install libncurses5-dev make openssl libssl-dev bison flex查漏补缺
5、使用命令make menuconfig编译内核
6、选择save->ok->exit->exit
6、修改.config的宏,使用命令sudo make -j32 2> error.log编译内核,错误信息输出到error.log,j32表示32线程。
7、使用命令sudo make modules_install进行安装模块。
8、使用命令sudo make install安装内核。
9、编写test.c测试
10、修改指定默认内核,参考:https://www.cnblogs.com/zoneofmine/p/13229347.html
11、chmod 777 a.out为程序添加执行权限(重要)。
12、gcc test.c编译运行,成功重启系统
三 遇到问题及解决方法
1、在sys.c中无法找到reboot的代码,最后使用网站进行查找,成功找到reboot函数定义在reboot.c中,明白了不是所有系统调用服务例程都会定义在sys.c中。
2、在编译内核时报错
在查找资料后发现要先运行make modules,并提前安装包libssl-dev、libncurses5-dev、qt4-default、qt4-dev-tools,把.config中的CONFIG_SYSTEM_TRUSTED_KEYS=”debian/canonical-certs.pem” 改为 CONFIG_SYSTEM_TRUSTED_KEYS=””