目录
一、内核源码下载
The Linux Kernel Archiveshttps://www.kernel.org/
uname -r查看当前内核的版本
我这里装的是Ubuntu20.04.6
然后下载内核源码,这里我下载的是5.15.160
接下来将压缩包解压到/usr/src目录下
tar -xavf linux-5.15.160.tar.xz -C /usr/src
cd /usr/src/linux-5.15.160
(记得开启root权限)
su root
二、添加系统调用
1、添加调用号
vim arch/x86/entry/syscalls/syscall_64.tbl
64位就写入syscall_64.tbl,32位就写入syscall_32.tbl
可以通过以下方式查看Ubuntu系统位数:
uname -m
添加调用号后:
2、添加声明
vim include/linux/syscalls.h
依据我们写入调用号的内容,添加如下声明:
(在文件末尾添加即可)
asmlinkage long sys_mysleep(void);
3、添加函数实现
vim kernel/sys.c
函数实现:
(同样的,这里也在文件末尾添加即可)
SYSCALL_DEFINE0(mysleep){
printk("This is my sleep");
unsigned int time = 3 + prandom_u32() % 3;
msleep(time * 1000);
return 0;
}
tips:pthread_u32函数在版本6.x的版本中似乎已被停止使用,在当前版本使用该函数时需要添加如下头文件:
#include <linux/random.h>
三、内核编译
1、清除无用文件
#记得使用root权限
make mrproper
make clean
2、配置
cp /boot/config-5.15.0-107-generic ./.config
make menuconfig
选择Load->OK->Save->OK->Exit
3、更改配置文件(很重要)
vim .config
需要做出如下更改:
CONFIG_DEBUG_INFO_BTF=n
CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
CONFIG_SYSTEM_TRUSTED_KEYS=""
CONFIG_SYSTEM_BLACKLIST_HASH_LIST=""
CONFIG_SYSTEM_REVOCATION_KEYS=""
tips:CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"在原配置文件中便是如此,不用修改,我参考了很多博主的文章,这里都做了一些修改,但这可能会导致后续内核编译中出现SSL认证相关的错误。
4、内核编译与安装
make modules -j8
tips:这里我开启了8线程编译,提高编译速度(根据内核数量修改),大概会跑一个多小时吧
然后进行内核安装
make modules_install
tips:如果期间出现错误:
Missing file: arch/x86/boot/bzImage
那么在make install之前,先单独进行一次make bzImage即可解决
打包:
mkinitramfs /lib/modules/5.15.160 -o /boot/initrd.img-5.15.160-generic
内核映像拷贝:
cp /usr/src/linux-5.15.160/arch/x86/boot/bzImage /boot/vmlinuz-5.15.160-generic
cp /usr/src/linux-5.15.160/System.map /boot/System.map-5.15.160
5、更新grub配置文件
cd /boot/grub
chmod 777 grub.cfg
update-grub2
四、内核切换
重启虚拟机(需要在root权限下执行)
reboot
在加载界面按住shift,直至出现如下界面
选择Ubuntu的高级选项
选择我们要切换的内核,回车
切换成功
五、系统调用测试
#include <unistd.h>
#include <sys/syscall.h>
int main(){
syscall(449);
return 0;
}
编译并运行
gcc -o test test.c
./test
由于我们在函数实现时使用了printk函数,接下来我们以下指令查看结果
dmesg -w
如下所示:
参考文章: