CentOS新增系统调用(保姆级教程!)
CentOS 7 系统下载: 清华大学镜像源(下载DVD版本的ISO,安装虚拟机步骤自行搜索)
系统版本:CentOS Linux 7.9.2009
内核版本:3.10.0
查看系统版本
cat /etc/centos-release
查看内核版本
uname -r
下载CentOS内核源码:CentOS官网
依次点击 /版本号(7.9.2009)/os/Source/SPackages/ 找到带有 kernel-xxxx-xxx.src.rpm 的文件(可在浏览器内 ctrl+F 搜索 kernel),并下载他
安装rpm
将下载的源码压缩包拷贝到虚拟机系统中(拷贝步骤自行搜索)
在拷贝到的目录打开终端,安装他
rpm -ivh kernel-3.10.0-1160.el7.src.rpm
解压源码压缩包
安装完成后,在目录 /root/rpmbuild/SOURCES 下会有个 linux-3.10.0-1160.el7.tar.xz 的压缩包
su # 进入root模式 以下所有操作都在root模式下完成
cd /root/rpmbuild/SOURCES
tar -xJf linux-3.10.0-1160.el7.tar.xz
解压完成后我们便可以看到有个 linux-3.10.0-1160.el7 的目录,目录下即为Linux内核源代码,为了方便我们操作(学习),我们修改该目录的权限
chmod 777 linux-3.10.0-1160.el7
二、添加新的系统调用
2.1、添加新的系统调用函数
在目录 /root/rpmbuild/SOURCES/linux-3.10.0-1160.el7/kernel 找到 sys.c
在文件 末尾(最后一行新增一行) 添加自定义函数 sys_mysyscall()
# 当前已在路径 /root/rpmbuild/SOURCES
vim ./linux-3.10.0-1160.el7/kernel/sys.c
键盘按下 G(shift+g) 跳转末尾,插入新的函数 sys_mysyscall
这里函数自己写即可,具体需要实现什么自定义即可,这里只做示例仅供参考
自定义函数 返回一个数的立方
asmlinkage long sys_mysyscall(long number) {
return number * number * number;
}
按下 esc 输入 :wq 保存退出
2.2、添加函数调用声明
在目录 /root/rpmbuild/SOURCES/linux-3.10.0-1160.el7/include/linux 编辑 syscalls.h
为新增函数添加声明
vim ./linux-3.10.0-1160.el7/include/linux/syscalls.h
同样的 按下 G 跳转末尾,在 #endif
前面插入一行声明代码
asmlinkage long sys_mysyscall(long number);
按下 esc 输入 :wq 保存退出
2.3、添加系统调用号
在目录 /root/rpmbuild/SOURCES/linux-3.10.0-1160.el7/arch/x86/syscalls/ 编辑 syscall_64.tbl
为新增系统调用添加系统调用号
vim ./arch/x86/syscalls/syscall_64.tbl
说明
1、插入位置为32为系统调用号区域之上,也就是331号之下新建一行,调用号必须为顺序加1,即为332
2、64为64位调用
3、mysyscall为调用函数名,是去除了系统调用前缀 sys_ 后的名称,后面的sys_mysyscall为系统调用函数
332 64 mysyscall sys_mysyscall
按下 esc 输入 :wq 保存退出
2.4、添加系统调用宏、宏号
在目录 /root/rpmbuild/SOURCES/linux-3.10.0-1160.el7/include/uapi/asm-generic 编辑 unistd.h
vim ./include/uapi/asm-generic/unistd.h
插入位置紧跟最后一个定义的宏号之下,例如我这里系统最后一个为 1079 则在下面插入新的定义 1080
#define __NR_mysyscall 1080
__SYSCALL(__NR_mysyscall,sys_mysyscall)
按下 esc 输入 :wq 保存退出
三、重新编译内核并测试
首先将 /root/rpmbuild/SOURCES/linux-3.10.0-1160.el7 复制到 /usr/src 目录下,并进入该目录
\cp -vrf /root/rpmbuild/SOURCES/linux-3.10.0-1160.el7/ /usr/src/
cd /usr/src/linux-3.10.0-1160.el7
其次先安装几个需要使用到的包(安装过的可以跳过)
# 配置文件所需要的包
yum install -y ncurses-devel
# 安装内核所需要的包
yum install elfutils-libelf-devel
1、清空之前的编译信息
make mrproper
make clean
2、生成配置清单文件
make menuconfig
随后在终端界面弹出配置项目:
键盘上下键移动可以将光标选择需要导入的配置,按 Y 选择导入,按 N 则不导入,我们 默认 即可。
键盘左右键移动移动到 Save 按下回车:
继续回车 Ok
回车 Exit 再选择到 Exit 回车退出配置
3、编译内核
-j4参数让make最多允许4个编译命令同时执行,这样可以更有效的利用CPU资源。
此时将根据自己处理器的最大线程数目来编译,建议允许的情况下给虚拟机分配多个处理器
make -j4
# 之后遍等待编译,快的话几十分钟,慢的话几个小时,根据你给该虚拟机分配的处理器个数 (我的分配了4核2G内存编译了大概40分钟)
#
# 切勿关机!!!建议空闲时候操作
#
4、安装内核到系统中
make modules_install
make install # 安装内核(卡住 不动 不要着急 等几分钟 )
5、重新启动虚拟机
重启后选择我们新编译的系统(第一个)
6、测试新增系统调用
写一个代码去测试新增的系统调用
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main() {
long s = syscall(332, 2);
printf("%ld\n", s);
return 0;
}
编译文件并运行
gcc test.c -o test
./test