操作步骤
- 在系统调用表里添加一个表项,位于entry.s的ENTRY(sys_call_tall)
- 将系统调用号定义到<asm/unistd.h>中(定义位置:include/asm-i386/unistd.h)
- 在**sys_ni_syscal()**增加系统调用完成的功能
- 编译到内核映像
- 重新编译内核,启动新内核
- 封装系统调用例程,支持用户空间的访问
具体实现
1. 在系统调用表里添加一个表项,位于entry.s的ENTRY(sys_call_tall)
按之前编译内核时解压缩的源代码的目录下去找/arch/x86/entry/syscalls(下面是我的目录位置)
/usr/src/linux-5.6.4/arch/x86/entry/syscalls
sudo gedit syscall_64.tbl
系统调用编号:/根据自己的在后面增加,注意不要把之前的系统调用覆盖掉/
适用位数:x86/64/common
名称:自定义
函数名:/建议以sys_开头/
注:我的一开始用sys_开头,后来编译内核的时候出了问题,后来改成了 __x64_sys_开头
例如我打算添加两个系统调用:
long __x64_sys_MyInfo64(void)
long __x64_sys_MyInfoCommon(void)
2. 将系统调用号定义到<asm/unistd.h>中(定义位置:include/asm-i386/unistd.h)
/*在/usr/src/linux-5.6.4目录下*/
sudo gedit include/linux/syscalls.h

3. 在sys_ni_syscal()增加系统调用完成的功能
/*在/usr/src/linux-5.6.4目录下*/
sudo gedit kernel/sys.c
asmlinkage long __x64_sys_MyInfo64(void)
{
printk("My name is ZY\n");
printk("My student id is ************\n");
return 0;
}
asmlinkage long __x64_sys_MyInfoCommon(void)
{
printk("My name is ZY\n");
printk("My student id is *************\n");
return 0;
}

4.重新编译内核(我是切换到了linux-4.15.0内核版本下重新编译的)
/*在/usr/src/linux-5.6.4目录下*/
sudo su //进入root模式
make mrproper //清理以前编译内核的中间残留文件
cp /boot/config-`uname -r` ./.config //编译内核之前要选配置信息,但配置信息不太好选,所以用当前内核的配置信息
make menuconfig //对内核选项进行配置
//load->(.config)OK->SAVE->(.configbak)OK->EXIT
make clean //因为之前运行过make mrproper命令,所以可有可无
make bzImage //编译内核(检验成功看)
make modules //编译模块
make INSTALL_MOD_STRIPE=1 modules_install //安装模块
mkinitramfs /lib/modules/5.6.4 -o /boot/initrd.img-5.6.4-generic //基于刚才编译的模块,做一个内存的根文件系统(5.6.6是我编译的内核版本)
//到此为止,构建内核完成
//把内核映像和System.map拷贝到/boot/下
cp /usr/src/linux-5.6.4/arch/x86/boot/bzImage /boot/vmlinuz-5.6.4-generic
cp /usr/src/linux-5.6.4/System.map /boot/System.map-5.6.4
ln -s /boot/System.map-5.6.4 /boot/System.map
//修改grub配置文件
cd /boot/grub
chmod 777 grub.cfg
update-grub2
//重启,启动grub就可以看到自己新的内核
linux——编译内核(ubuntu18.04+linux-5.6.4)
https://blog.csdn.net/bdwdwks/article/details/106294349
5.测试
编写测试代码
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc,char **argv)
{
//439:long __x64_sys_MyInfo64()
printf("System call __x64_sys_MyInfo64 return %ld\n",syscall(439));
//440:long __x64_sys_MyInfoCommon()
printf("System call long __x64_sys_MyInfoCommon return %ld\n",syscall(440));
return 0;
}
编译并运行查看
sudo vim test.c
sudo gcc test.c -o test
sudo ./test
dmesg //查看日志文件,看是否有之前定义的输出


参考链接
https://blog.csdn.net/qq_36290650/article/details/83184088
版权声明:本文为bdwdwks原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
