Linux 编译内核且增加一个系统调用
文章目录
一.在添加系统调用之前需要先编译一个Linux的内核。
解压
在下载了源码之后,需要对其进行解压和编译
sudo tar -xavf linux-5.7.tar.xz
解压文件到桌面
安装依赖
这个也是笔者在网上找的在编译时所需要的一些资源,直接安装就可以了。
sudo apt-get install gcc make libncurses5-dev openssl libssl-dev
sudo apt-get install build-essential
sudo apt-get install pkg-config
sudo apt-get install libc6-dev
sudo apt-get install bison
sudo apt-get install flex
sudo apt-get install libelf-dev
编译
1.进入刚刚解压的文件里面(此处我是在桌面操作的)
cd linux-5.7
2.复制一份系统自带的config文件(这个需要自己去目录下面找)
sudo cp /boot/config-5.3.0-53-generic .config
3.使用make menuconfig(如果想了解可以去看https://blog.csdn.net/xuyuefei1988/article/details/8635539)
sudo make menuconfig
这个可以直接关闭
4.然后就可以直接开始编译
这里所需要的时间有点长
sudo make -j4 #编译内核,这个时候你可以去吃点东西.......
sudo make modules_install #安装模块
安装内核
1.由于此时我们编译好的内核还在我们的桌面上,因此首先需要把内核移动到/usr/src目录内,然后切换到该目录下
sudo mv linux-5.7 /usr/src
cd /usr/src/linux-5.7/
2.安装内核
sudo make install
sudo mkinitramfs -o /boot/initrd.img-5.7.0
sudo update-initramfs -c -k 5.7.0
sudo update-grub2
可能大家现在发现了一件事,就是现在的系统内核还是之前的,此时需要重启电脑,然后开机后再次查看
此时的内核版本就已经改为了我们最新安装的。
编译内核到此就结束了。
二.系统调用
因为本文主要介绍怎么操作,因此不会介绍原理,如果大家感兴趣可以自行百度或Goole
声名和定义系统调用函数
声名
1.这个需要注意一下,最好是写在/usr/src/linux-5.7/include/linux 这个文件夹下,要不可能会找不到函数的声名
gedit syscalls.h #你也可以使用vim
定义
此处需要注意一点,就是在最新的里面"The x64_sys*() stubs are created on-the-fly for sys*() system calls"
这个定义和声名最好比接下来要写的系统调用id多上"_x64",要不可能会报错。
sudo vim kernel/sys.c
添加一个系统调用id
注意:id不要和已存在的系统调用重复
此处笔者多写了一个横杠,其实可以不要
sudo vim arch/x86/entry/syscalls/syscall_64.tbl
进行编译
sudo make clean
sudo make oldconfig #仍采用原内核配置文件
sudo make
sudo make modules_install
sudo make install
在编译完成之后 reboot 重启系统
可能出现的错误
1.arch/x86/entry/syscall_64.o:(.rodata+0xdb8):对‘__x64_sys_myno_name’未定义
这个一个可能是你文件路径找错了,根据我说的目录重新找过
还有一个可能就是,你在定义了id之后,把声明函数和定义函数写的和你所添加的一致,我之前也是这个问题,然后发现需要在声明函数和定义函数前**加上"_x64"**才可以
这个错误只适用于5.7版本的,以后会不会变,我也不知道。
2.ubuntu AER: device [8086:9d14] error status/mask=00000001/00002000
解决方法:
vim /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
pci=nomsi pci=noaer pcie_aspm=off
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash pci=nomsi pci=noaer pcie_aspm=off"
sudo update-grub
运行检验
#include <linux/unistd.h>
#include <sys/syscall.h>
int main(){
syscall(439);
return 0;
}
使用gcc 编译
gcc -o test test.c
./test
dmesg
OK!,结束了。