【实验内容】:
向Linux添加一个系统调用
测试该系统调用
使用ptrace或类似的系统跟踪工具来对该测试程序进行跟踪调试
【软件】:VMWare支持的Ubuntu虚拟机 VSCode
【步骤】
1.在实验之前先下载好相关软件包
不过如果升级了make以后,如果内核版本低,会报错
1. sudo apt-get install make 2. sudo apt-get install gcc 3. sudo apt-get install libncurses5-dev 4. sudo apt-get install flex 5. sudo apt-get install bison 6. sudo apt-get install libssl-dev 7. sudo apt-get install libelf-dev
2.进入 /usr/src下载内核源码(实验所用源码为 linux-5.5.7)
内核5.5.7所需要的存储空间特别大!!!一定要提前准备好!!!
1. cd /usr/src 2. wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.5.7.tar.xz
3.下载好之后在当前目录进行解压
1. tar -xvf linux-5.5.7.tar.xz
4.编写系统调用的入口表
1. sudo vim linux-5.5.7/arch/x86/entry/syscalls/syscall_64.tbl
添加
1. 335 common mysyscall __x64_sys_mysyscall
5.编写系统调用函数声明
1. sudo vim linux-5.5.7/include/linux/syscalls.h
在里面添加
1. asmlinkage long sys_mysyscall(int number);
6.实现系统调用函数
1. sudo vim linux-5.5.7/kernel/sys.c
在里面添加
1. SYSCALL_DEFINE1(mysyscall, int, number) { 2. int result = number * number * number; 3. printk("The result is %d\n", result); 4. return 0; 5. }
7.重新编译内核
1. cd linux-5.5.7/ //进入内核文件夹 2. sudo cp /usr/src/linux-headers-5.3.0-40-generic/.config /usr/src/linux-5.5.7 //复制内核配置 3. make mrproper //删除以前编译产生的垃圾文件 4. make clean 5. make menuconfig //选择Save保存再Exit 6. make -j4 //编译内核 7. make modules_install //安装模块 8. make install //安装内核
8.重启选择linux-5.5.7进入
(因为linux系统会自动选择高版本内核加载,因此重启虚拟机后加载的内核就是刚刚编译完成的5.5.7内核)
9. 编写测试程序test.c验证系统调用是否成功
1. #include <stdio.h> 2. #include <sys/ptrace.h> 3. #include <sys/types.h> 4. #include <sys/wait.h> 5. #include <sys/user.h> 6. #include <sys/reg.h> 7. #include <sys/syscall.h> 8. #include <unistd.h> 9. #include <linux/kernel.h> 10. 11. int main () { 12. syscall(335,4); 13. return 0; 14. }
编译执行后用dmsg查看结果
正确哒!!!
10.用strace进行追踪
能看到系统调用成功
11.常见错误汇总!!
我太难了我编译了五次才成功!
make首先,一定要在解压好的文件夹里make,内核也一定解压到那个文件夹!!!千万不能自己创一个文件夹写那个名字!!!我有个朋友这么干的哈哈哈哈
最常见的错误就是包没装全,如果报错就装就好了。
然后在make -4j之前,一定要检查一下有没有问题,因为make -4j一旦失败enmmmmmm。。。我的方法就是不sudo输入make -4j,这样除了权限报错以外,别的错误也会报错
之后就是内核编译的错误了
它是这样报错的:
[[email protected] module]# make
make -C /opt/kangear/kernel/linux-2.6.32.2 M=/root/桌面/kangear/module modules
make[1]: Entering directory `/opt/kangear/kernel/linux-2.6.32.2‘
ERROR: Kernel configuration is invalid.
include/linux/autoconf.h or include/config/auto.conf are missing.
Run ‘make oldconfig && make prepare‘ on kernel src to fix it.
WARNING: Symbol version dump /opt/kangear/kernel/linux-2.6.32.2/Module.symvers
is missing; modules will have no dependencies and modversions.
Building modules, stage 2.
/opt/kangear/kernel/linux-2.6.32.2/scripts/Makefile.modpost:42: include/config/auto.conf: 没有那个文件或目录
make[2]: *** 没有规则可以创建目标“include/config/auto.conf”。 停止。
make[1]: *** [modules] 错误 2
make[1]: Leaving directory `/opt/kangear/kernel/linux-2.6.32.2‘
make: *** [all] 错误 2
[[email protected] module]#
内核配置文件.config出错。
可以参照一下这个博客https://blog.csdn.net/u013225150/article/details/48272853
然后总结一下我这五次编译的卑微过程吧……
0.编译前因为安装包不全,在make -4j之前失败了很多次
1.第一次编译,因为在写程序的时候用了for函数,编译时并不支持,导致失败
2.去掉for函数之后,显示找不到配置的.config文件,发现make menuconfig的操作有误,内核配置文件的命令输入同样错误,并没有把内核配置成功复制
3.配置好内核,把所有相关包检查升级后再次编译,出现pkg错误,上网查资料后发现是make版本过高,一开始选择的4.18内核不支持
4.选择最新的5.5.7内核进行编译,因为虚拟机空间不足报错
5.不加sudo编译时(即会报错但因权限不足无法全部编译,通过这种办法节省时间查找错误)报错arch/x86/Makefile:129: CONFIG_X86_X32 enabled but no binutils support,查找网上资料后说是缺少binutils支持,检查更新没有问题,之后找到方案在内核配置时选择:
--> Device Drivers
--> Multiple devices driver support (RAID and LVM)
--> Device mapper support
(这一项改为n)
再次编译后成功。
原文地址:https://www.cnblogs.com/jhjgarden/p/12591453.html