美文网首页分布式存储-Lustre
CentOS7编译自己的内核模块

CentOS7编译自己的内核模块

作者: Eason_Ye | 来源:发表于2017-11-05 16:56 被阅读0次

      部门已经有固定下来的内核编译方式。迁出完整代码后,加载环境变量文件,直接make即可重新编译内核。修改了某个模块,直接到模块目录下make即可生成模块,很方便。最近想尝试在centos下进行内核开发,查阅了几个centos内核编译wiki说明。感觉比较零散,于是整理出来方便后续查阅和分享。

    下载内核源码

    $ uname -r
    3.10.0-514.26.2.el7.x86_64
    

    有两种方式可以下载centos与当前内核版本一致的源码:
    方式1:使用yumdownloader自动下载

    $ sudo yum install yum-utils
    $ sudo yumdownloader --source kernel
    kernel-3.10.0-514.26.2.el7.src.rpm
    

    要注意的是kernel源码下载速度可能很慢,需要挂VPN下载,否则可能会下载失败。

    方式2:手工从镜像网站下载
    由于软件源镜像站点只保留二进制软件包,所以我们要去centos软件包归档站点“http://vault.centos.org”去下载内核源码。下载地址:http://vault.centos.org/7.3.1611/updates/Source/SPackages/kernel-3.10.0-514.26.2.el7.src.rpm

    编译内核源码

      注意:官方强烈建议不要以root身份编译内核源码。主要原因是编译过程中可能有对系统文件的修改操作,如果用root编译就可能在你不知情的情况下直接修改了。用普通用户编译过程中,要是有对系统文件的修改,会因权限不足而报错。详见参考“[5] Building Source RPM as non-root under CentOS ”。

    • 以普通用户创建编译rpm所需的基础目录结构
    $ mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
    $ echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros
    
    • 安装编译内核所需软件包
    $ sudo yum install kernel-devel
    $ sudo yum install rpm-build redhat-rpm-config asciidoc hmaccalc perl-ExtUtils-Embed pesign xmlto
    $ sudo yum install audit-libs-devel binutils-devel elfutils-devel elfutils-libelf-devel
    $ sudo yum install ncurses-devel newt-devel numactl-devel pciutils-devel python-devel zlib-devel
    
    • 安装内核源码
    $ rpm -i kernel-3.10.0-514.26.2.el7.src.rpm 2>&1 | grep -v exist
    $ cd ~/rpmbuild/SPECS
    $ rpmbuild -bp --target=$(uname -m) kernel.spec
    现在可以在“~/rpmbuild/BUILD/kernel*/linux*”看到完整的内核源代码了。
    
    • 内核编译设置
    $ cd ~/rpmbuild/BUILD/kernel-*/linux-*/
    $ cp /boot/config-`uname -r` .config
    $ cp /usr/src/kernels/`uname -r`/Module.symvers .
    $ cp /usr/src/kernels/`uname -r`/System.map .
    $ cp /usr/src/kernels/`uname -r`/vmlinux.id .
    

      这里拷贝了当前内核的配置到源码目录。因为只是要编译自己的内核模块,所以直接复用当前内核的配置。避免了重新编译整个内核,以及内核版本校验导致新模块加载错误的问题。

    $ make prepare
    $ make modules_prepare
    
    • 编译新增模块
    $ cd ~/rpmbuild/BUILD/kernel-*/linux-*/
    $ mkdir modules
    
    • 增加加载/移除时会打印提示信息的hello模块
      hello/hello.c
    #include <linux/init.h>
    #include <linux/kernel.h>
    #include <linux/module.h>
    
    static int hello_init(void)
    {
        printk(KERN_ERR "Module init: Hello linux kernel.\n");
        return (0);
    }
    
    static void hello_exit(void)
    {
        printk(KERN_ERR "Module exit: Bye-bye linux kernel.\n");
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    

    hello/Makefile

    obj-m += hello.o
    
    all:
        make -C $(PWD) M=$(PWD) modules
    
    clean:
        make -C $(PWD) M=$(PWD) clean
    
    $ make M=modules/hello
    $ sudo cp modules/hello/hello.ko /lib/modules/`uname -r`/extra
    
    • 新模块加载/移除
    $ cd /lib/modules/`uname -r`/extra
    $ sudo insmod hello.ko
    $ sudo rmmod hello
    
    $ tail -f /var/log/messages
    “
    * localhost kernel: Module init: Hello linux kernel.
    * localhost kernel: Module exit: Bye-bye linux kernel.
    ”
    

    messages打印出了模块加载/移除时的提示信息,新增模块工作正常。

    参考
    [1] SystemTap on CentOS,https://sourceware.org/systemtap/wiki/SystemTapOnCentOS
    [2] 我需要内核的源代码,https://wiki.centos.org/zh/HowTos/I_need_the_Kernel_Source
    [3] 我需要创建一个自设的内核,https://wiki.centos.org/zh/HowTos/Custom_Kernel
    [4] 创建你自己的内核模块,https://wiki.centos.org/zh/HowTos/BuildingKernelModules
    [5] Building Source RPM as non-root under CentOS,http://www.owlriver.com/tips/non-root/

    修订记录
    2017-11-05 PM:从网易博客迁移至简书;
    2017-07-16 PM:初稿;

    版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证

    相关文章

      网友评论

        本文标题:CentOS7编译自己的内核模块

        本文链接:https://www.haomeiwen.com/subject/qyqhmxtx.html