目录
前言
一、内核版本的选择和下载导入
二、添加新函数
0.找到下面提到的文件
1.添加新函数
2.添加函数声明
3.修改系统调用表
三、编译内核
0.预安装软件:
1.进入内核的根目录中
2.清除原先编译的.o文件
3.把当前使用的内核配置复制到编译的内核中
4.配置配置项(使用默认配置即可)
5.编译内核
6.安装模块
7.安装核心
四、启动新内核,验证新函数
1.启动新内核
2.测试新函数
五、清除编译产生的.o文件
总结
前言
PS:整个实验中最好用root账号进行。
PS2:一定要给自己的虚拟机留下足够的根目录空间,起码要10g以上,否则就会报错。空间不足可以尝试删除之前编译的内核的.o文件(使用 make mrproper)或者扩容根目录。
一、内核版本的选择和下载导入
首先可以用uname-r查看自己的内核版本,一般来说Centos7的内核版本是3.10,按照其他的教程一般是要选择跟自己的内核版本接近的内核版本进行编译,但是我使用2.6.27和3.11.1版本的内核都会出现各种各样离谱的问题,最后我选择了linux-4.15.10作为开发的版本才成功。
失败的内核编译,运行3.11会报错说禁用CPU
内核的下载地址:https://mirrors.edge.kernel.org/pub/linux/kernel/
Ctrl+F
快速查找
选择4.15.10内核进行下载。
WIN-SCP导入虚拟机中,地址是:/usr/src/
tar命令解压
tar -zxvf linux-4.15.10.tar.gz
cd /usr/src/linux-4.15.10/命令进入文件夹中。
(如果实在是不行的话,我把我的添加了新函数的内核放在这里,下载解压之后直接从编译开始就行了
链接:https://pan.baidu.com/s/1DEXfD5OO3rYuAI6G5eVwQg
提取码:wwww )
二、添加新函数
0.找到下面提到的文件
/usr/src/linux-4.15.10/这个目录下或者在find命令后面加上这个目录
syscall_64.tbl的位置:
find -iname syscall_64.tbl
/usr/src/linux-4.15.10/arch/x86/entry/syscalls/syscall_64.tbl 目录
按照这个方法理论上来说可以找到各种版本内核的三个文件的位置。
1.添加新函数
使用vim编译器打开/kernel/sys.c文件:
cd kernel/
vim sys.c
:$进入文档最后一行,在#endif前加入自己的新函数。
因为这是在内核态进行编程,所以用于用户态输出的printf不能使用了,要使用内核态输出函数printk。
然后按ESC键输入:wq!保存并退出。 (!是强制执行wq命令,内核的文件如果不加上!是不能直接使用wq命令退出来的)
2.添加函数声明
/usr/src/linux-4.15.10/include/linux
vim工具打开,然后在最末尾或者别的空的地方加入自己的函数声明(这个函数声明按照自己写的新函数写,我这里定义的新函数是long形的,传入一个int的参数)
asmlinkage long sys_mysyscall(int number);
然后按ESC键输入:wq!保存并退出。
3.修改系统调用表
4.15内核的系统调用表的位置在/usr/src/linux-4.15.10/arch/x86/entry/syscalls
使用vim工具打开,然后在末尾或者别的空的地方加入一个自己函数的系统调用,这个调用号只要不是系统目前在用的调用号就行。
333 64 mysyscall sys_mysyscall
三、编译内核
依次输入以下命令:
cd /usr/src/ linux-4.15.10/
make mrproper
cp /boot/config-`uname –r` ./.config(这里输到/boot/config-就可以按tab补全了,后面的是你编译的内核版本)
make menuconfig(采用默认配置即可)
make all(此步骤要1个小时左右,这时你可以离开电脑干别的去了)
make modules_install
make install
(这些make命令的详细代码在根目录的Makefile文件中,感兴趣的话可以打开好好看看)
0.预安装软件:
(如果yum -y提示找不到可以自行百度更新yum源)
gcc编译器:
yum -y install gcc
ncurses-devel,这个是文本菜单配置界面也就是第四步需要用到的程序:
yum -y install ncurse*
elfutils-libelf-devel
和 openssl-devel,这些是编译内核时用的:
yum install elfutils-libelf-devel openssl-devel
1.进入内核的根目录中
cd /usr/src/ linux-4.15.10/
2.清除原先编译的.o文件
make mrproper
最后内核编译完成后可以进入内核根目录中执行这条命令清除编译产生的.o文件,编译好的内核不受影响,文件夹的大小会减少很多。
3.把当前使用的内核配置复制到编译的内核中
cp /boot/config-`uname –r` ./.config
4.配置配置项(使用默认配置即可)
make menuconfig(注意,如果报错很有可鞥是因为窗口太小了,把窗口拖大就可以解决)
直接按两下ESC键,然后在弹出的窗口按回车即可
5.编译内核
make all
静静等待编译完成,大概需要一个多小时,如果在编译时报错说No space left on device就是说没有足够的空间了,自行百度linux扩容根目录
报错信息
使用如下命令查看磁盘占用
df -l
6.安装模块
在长时间的等待后,终于好了!
现在我们来安装模块
make modules_install
7.安装核心
等待模块安装好后,
make install安装核心,执行完后reboot重启虚拟机看看效果
四、启动新内核,验证新函数
1.启动新内核
在内核选择页面选择新的内核:
uname -r查看内核版本号
2.测试新函数
在任何文件夹下(最好是在自己的家目录里)创建一个测试文件
vim mysyscall.c
在测试文件中写入测试代码:
#include<unistd.h>
#include<stdio.h>
#include<sys/syscall.h>
#include<linux/kernel.h>
int main()
{
long int a = syscall(333,100);
printf("%d\n",a);
return 0;
}
其中syscall()函数是系统调用函数,第一个参数是系统调用号,第二个参数是传给自己写的函数的参数。
使用gcc编译器编译,修改编译后的文件为可执行文件,执行文件。
gcc mysyscall.c -o myscall
chmod 777 myscall
./myscall
输出结果:
使用dmesg 命令查看printk的输出情况。
五、清除编译产生的.o文件
清除编译产生的.o文件释放空间
cd /usr/src/linux-4.15.10/
make mrproper
清除.o文件
总结
内核编程其实最重要的一步就是内核版本的选择,基本上选对了内核接下来就很简单了,反而如果选错了内核就会出各种各样的问题,所以做这个的时候一定要先选择好内核版本阿。