Ubuntu22.04添加系统调用(编译内核法)

1. 环境

Ubuntu 的具体版本:Ubuntu 22.04.4 LTS

内核版本:6.9.8

gcc版本:gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0

2. 具体实现步骤

(1)将内存开到100G,防止编译过程中内存不够而报错。处理器可以根据自己电脑配置设置(加快编译速度)

(2)查看现有版本:uname -r

(3)在虚拟机浏览器中打开链接(The Linux Kernel Archives),下载6.9.8

(4)下载完成,在“下载”页面打开终端,将压缩包移动到/usr/src目录下,移动命令:

sudo cp linux-6.9.8.tar.xz /usr/src

(5)在/usr/src目录下,查看是否移动成功。再在/usr/src目录下打开终端解压文件。解压命令(在root用户下,防止权限问题):

tar -xvf linux-6.9.8.tar.xz

(6)修改系统调用表

打开在/usr/src/linux-6.9.8/arch/x86/entry/syscalls路径下的syscall_64.tbl文件目录,打开终端,修改系统调用表命令:

sudo gedit syscall_64.tbl

<<462为增加的系统调用号,64为系统调用的参数个数,mycall为调用函数名,sys_mycall为系统调用的内核函数名称(格式要与上一行格式相同)>>注意:两数之间不是空格是Tab缩进。

(7)实现系统调用函数

打开在/usr/src/linux-6.9.8/kernel路径下的sys.c文件目录下,打开终端,添加上自己的系统调用函数的声明,修改命令:

sudo gedit sys.c

在文件最下一行添加函数(按G直接跳转最后一行)

(8)添加系统调用头文件

打开在/usr/src/linux-6.9.8/include/linux路径下的syscalls.h文件目录下,打开终端,添加上自己的系统调用函数的声明,修改命令:

sudo gedit syscall.h

(9)安装编译内核所需的依赖包(全部下载成功,否则会编译出错)

sudo apt-get update
sudo apt-get install make
sudo apt-get install build-essential
sudo apt-get install libncurses5-dev
sudo apt-get install pkg-config
sudo apt-get install libssl-dev
sudo apt-get install libelf-dev
sudo apt-get install bison
sudo apt-get install flex

(10)编译内核(在cd /usr/src/linux-6.9.8目录下进行)

1)清除内核编译过程产生的中间文件,如果之前编译过内核源码,由于出错或者其它原因想重新编译,则需要先清理下之前的编译结果

sudo make mrproper

2)清除以前生成的目标文件和其他文件

sudo make clean

3)配置编译参数

sudo make menuconfig

配置编译参数,编译的内核模块选择,出现以下界面。并且修改此文件需在 sudo make clean ;sudo make mrproper指令之后执行,不然修改过的.config文件又会复原。

操作过程:Save--->ok--->Exit--->Exit

4)

​​​​​​​sudo gedit .config

将下面两行的“”内的内容删除成这样子后保存,否则会报错(编译内核错误——*** 没有规则可制作目标“debian/canonical-certs.pem”,由“certs/x509_certificate_list” 需求。 停止)

5)make加上-jn选项多线程编译内核来加速内核编译(根据自己设置的处理器内核总数设置)(花了将近三个小时)

sudo make -j8

7)安装模块,大概需要十几分钟

sudo make modules_install

8)查看是否安装成功

在/lib/moudles目录下查看

是否生成内核压缩镜像文件,在/arch/x86/boot下查看生成bzImage

10)安装内核

sudo make install

11更改系统启动参数

update-grub2

12)重启进入新内核

sudo reboot

13)查看内核版本,内核替换成功

uname -a

3. 运行及测试

 (1)代码

测试代码test.c:

#include<stdio.h>
#include<stdlib.h>
#include<linux/kernel.h>
#include<sys/syscall.h>
#include<unistd.h>

int main()
{
    printf("dll' mycall: %ld\n", syscall(462, 20221911));//若返回值为-1,调用失败;若返回值为0,调用成功(因为我在系统调用函数的声明时,设置返回值为0,可以设置自己想要返回的值)
}

(2)运行命令

(3)运行./test(返回值不为-1,调用成功)

(4)查看日志:sudo dmesg(系统调用成功)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值