在Linux内核中添加系统调用
本文在Linux内核6.8.0中加入新系统调用,编译、安装新的Linux内核,测试新的系统调用。
编译Linux内核会产生大量中间文件,建议为Ubuntu系统保留至少50G硬盘空间,否则会超出容量,不能完成编译。
操作系统:Ubuntu 24.04.1 LTS。
在终端输入uname -r查看当前系统版本号,为6.8.0-x-generic。
下载源代码
在系统设置->系统->软件更新->设置中,下载源代码项打勾,确定并更新软件源。
安装dpkg-dev。(下载Ubuntu源代码的命令依赖dpkg-dev)
1 | sudo apt install dpkg-dev |
在/usr/src目录下执行以下命令,获得当前内核源代码。linux内核源代码目录为linux-6.8.0。
1 | sudo apt source linux-image-unsigned-$(uname -r) |
安装编译Linux内核所需的工具。
1 | sudo apt build-dep linux linux-image-unsigned-$(uname -r) |
注册新系统调用
查看arch/x86/entry/syscalls/syscall_64.tbl文件,可以看到注释要求在所有使用common二进制接口的系统调用后添加新系统调用,因此在461号后添加以下内容,从而注册系统调用处理函数sys_my_syscall。
1 | 462 common my_syscall sys_my_syscall |
定义系统调用处理函数
在kernel/sys.c的第961行后加入下列代码,定义sys_my_call()为返回进程号的函数,相当于sys_getpid()。
1 | SYSCALL_DEFINE0(my_syscall) |
如果在新增的C语言文件定义新系统调用处理函数,则需要修改相应文件夹中Makefile的obj-y,并在include/linux/syscalls.h中声明新函数。
编译和安装内核
在Linux内核源代码目录/usr/src/linux-6.8.0下,执行以下命令,从当前启动目录拷贝配置信息,意思是编译内核的配置与当前环境一致。
1
sudo cp -v /boot/config-$(uname -r) .config
编辑.config,把CONFIG_SYSTEM_TRUSTED_KEYS和CONFIG_SYSTEM_REVOCATION_KEYS改为空字符串。或使用以下命令。
1
2sudo scripts/config --disable SYSTEM_TRUSTED_KEYS
sudo scripts/config --disable SYSTEM_REVOCATION_KEYS执行以下命令启动配置界面
1
2sudo make menuconfig # 使用当前配置
# sudo make defconfig # 使用默认配置
出现蓝色背景的kernel configuration界面,说明配置成功。save后exit即可。
运行make命令,编译Linux内核。需要较长时间。
1
sudo make -j$(nproc) # 按照核心数量多核编译
运行make modules_install命令安装内核模块。就是把编译好的模块拷贝到/lib/modules/$(uname -r)目录下。
运行make install命令安装新内核。
1
2sudo make modules_install # 安装内核模块
sudo make install # 安装新内核完成内核编译后,重启系统,自动进入新内核。
uname -r或uname -a查看内核版本,显示为6.8.x(而不是上面看到的6.8.0-x-generic),说明成功安装新内核。
测试程序
下列C代码中,调用syscall函数传递系统调用号,获得新系统调用处理函数的返回值,即当前进程号。相当于调用<unistd.h>
中的getpid()。
在主函数main()里打印syscall()和getpid()的返回值,如果两个值相等,打印“Successfully added my system call.”(成功加入我的系统调用。)
1 |
|
用gcc编译并运行。
1 | gcc test.c && ./a.out |
参考文献
- AimTao. Linux 内核|系统调用[EB/OL]. aimtao.net, (2022-04-12)[2024-12-15]. https://www.aimtao.net/system-call/
- Adding a system call to Linux CS 273 (OS), Spring 2022[EB/OL]. Stolaf.edu, (2022-04-29)[2024-12-15]. https://www.stolaf.edu/people/rab/os/newsyscall.html
- Arnold Lu. Ubuntu 22.04内核代码下载、编译、调试[EB/OL]. 博客园, (2024-03-10)[2024-12-15]. https://www.cnblogs.com/arnoldlu/p/18064348
- robotech_erx. 在Ubuntu上编译安装linux内核详细过程[EB/OL]. 博客园, (2024-04-16)[2024-12-15]. https://www.cnblogs.com/robotech/p/16152269.html