目录

 

前言

一、内核版本的选择和下载导入

二、添加新函数

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作为开发的版本才成功。


centos7编译内核源码并替换 centos7编译内核模块_linux

失败的内核编译,运行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

centos7编译内核源码并替换 centos7编译内核模块_根目录_02

/usr/src/linux-4.15.10/arch/x86/entry/syscalls/syscall_64.tbl 目录

    按照这个方法理论上来说可以找到各种版本内核的三个文件的位置。

1.添加新函数

      使用vim编译器打开/kernel/sys.c文件:

cd kernel/
vim sys.c

:$进入文档最后一行,在#endif前加入自己的新函数。

       

centos7编译内核源码并替换 centos7编译内核模块_linux_03

因为这是在内核态进行编程,所以用于用户态输出的printf不能使用了,要使用内核态输出函数printk。   

然后按ESC键输入:wq!保存并退出。 (!是强制执行wq命令,内核的文件如果不加上!是不能直接使用wq命令退出来的)

2.添加函数声明

/usr/src/linux-4.15.10/include/linux

centos7编译内核源码并替换 centos7编译内核模块_系统调用_04

vim工具打开,然后在最末尾或者别的空的地方加入自己的函数声明(这个函数声明按照自己写的新函数写,我这里定义的新函数是long形的,传入一个int的参数)

asmlinkage long sys_mysyscall(int number);

然后按ESC键输入:wq!保存并退出。

3.修改系统调用表

    4.15内核的系统调用表的位置在/usr/src/linux-4.15.10/arch/x86/entry/syscalls

    

centos7编译内核源码并替换 centos7编译内核模块_根目录_05

    使用vim工具打开,然后在末尾或者别的空的地方加入一个自己函数的系统调用,这个调用号只要不是系统目前在用的调用号就行。

333     64      mysyscall               sys_mysyscall

centos7编译内核源码并替换 centos7编译内核模块_根目录_06

 

三、编译内核

依次输入以下命令:

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

centos7编译内核源码并替换 centos7编译内核模块_根目录_07

4.配置配置项(使用默认配置即可)

make menuconfig(注意,如果报错很有可鞥是因为窗口太小了,把窗口拖大就可以解决)

centos7编译内核源码并替换 centos7编译内核模块_centos7编译内核源码并替换_08

直接按两下ESC键,然后在弹出的窗口按回车即可

5.编译内核

    make all

   静静等待编译完成,大概需要一个多小时,如果在编译时报错说No space left on device就是说没有足够的空间了,自行百度linux扩容根目录


centos7编译内核源码并替换 centos7编译内核模块_根目录_09

报错信息

     使用如下命令查看磁盘占用

df -l

 

centos7编译内核源码并替换 centos7编译内核模块_系统调用_10

 

6.安装模块

    在长时间的等待后,终于好了!

   现在我们来安装模块

make modules_install

7.安装核心

   等待模块安装好后,

make install安装核心,执行完后reboot重启虚拟机看看效果

四、启动新内核,验证新函数

   1.启动新内核

   在内核选择页面选择新的内核:

centos7编译内核源码并替换 centos7编译内核模块_centos7编译内核源码并替换_11

uname -r查看内核版本号 

    

centos7编译内核源码并替换 centos7编译内核模块_根目录_12

    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

输出结果:

centos7编译内核源码并替换 centos7编译内核模块_系统调用_13

使用dmesg 命令查看printk的输出情况。

centos7编译内核源码并替换 centos7编译内核模块_centos7编译内核源码并替换_14

五、清除编译产生的.o文件

     清除编译产生的.o文件释放空间

cd /usr/src/linux-4.15.10/
make mrproper


centos7编译内核源码并替换 centos7编译内核模块_linux_15

清除.o文件

 

 

总结

内核编程其实最重要的一步就是内核版本的选择,基本上选对了内核接下来就很简单了,反而如果选错了内核就会出各种各样的问题,所以做这个的时候一定要先选择好内核版本阿。