Linux kernel 内核模块编译、装载和卸载

发布时间: 更新时间: 总字数:679 阅读时间:2m 作者: 分享 复制网址
专栏文章
  1. Linux kernel 介绍
  2. 如何快速的将Centos6.7快速升级3.10.9
  3. Centos7 切换内核
  4. Linux kernel 内核模块编译、装载和卸载(当前)

本文以 demo 例子的形式演示 Linux kernel 内核模块编译、装载和卸载

常用命令

  • 加载kernel模块命令
    • insmod
    • modprobe # insmod 安装时不处理依赖,仅安装当前模块;modprobe 会安装模块的依赖依次安装
  • modinfo # 查看模块信息
  • rmmod # 卸载模块

示例

demo 文件

假设编译目录为 /root/hello-module/,示例编译共涉及两个文件:

  • hello.c 源代码
$ cat hello.c
#include <linux/init.h>
#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");

/*
 * hello module init method
 */
static int hello_init(void)
{
    printk(KERN_INFO "hello kernel world!\n");

    return 0;
}

/*
 * hello module exit method
 */
static void hello_exit(void)
{
    printk(KERN_ALERT "bye kernel world!\n");
}

module_init(hello_init);
module_exit(hello_exit);
obj-m := hello.o
KERNEL_DIR := /lib/modules/`uname -r`/build
PWD := $(shell pwd)
default:
	make -C ${KERNEL_DIR} M=${PWD} modules
clean:
	rm -f *.o *.ko *.mod.c *.mod.o modules.* Module.*

说明:

  • obj-m := hello.o # 要生成 hello 模块即 hello.ko
    • 若有多个文件生成,则须添加 hello-objs :=file1.o file2.o…..
  • KERNEL_DIR # 内核源码目录
  • PWD # 当前目录,即:/root/hello-module/
  • make
    • -C ${KERNEL_DIR} # 指定内核源码目录
    • M=${PWD} modules  # 指定模块源码目录

环境准备

$ yum install kernel-devel-$(uname -r) kernel-headers-$(uname -r)  # 版本需要与当前的 kernel 版本对应
$ cd /lib/modules/`uname -r`/  # 查看 build 链接是否正常,若不正常,需要安装对应版本的 kernel-devel

编译

  • 编译
$ make
make -C /lib/modules/`uname -r`/build M=/root/hello-module modules
make[1]: Entering directory `/usr/src/kernels/3.10.0-1160.6.1.el7.x86_64'
  CC [M]  /root/hello-module/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /root/hello-module/hello.mod.o
  LD [M]  /root/hello-module/hello.ko
make[1]: Leaving directory `/usr/src/kernels/3.10.0-1160.6.1.el7.x86_64'
  • 编译后的文件
$ ls -l
total 228
-rw-r--r-- 1 root root    410 Apr 18 07:35 hello.c
-rw-r--r-- 1 root root 104768 Apr 18 07:59 hello.ko
-rw-r--r-- 1 root root    907 Apr 18 07:59 hello.mod.c
-rw-r--r-- 1 root root  60568 Apr 18 07:59 hello.mod.o
-rw-r--r-- 1 root root  47304 Apr 18 07:59 hello.o
-rw-r--r-- 1 root root    188 Apr 18 07:38 Makefile
-rw-r--r-- 1 root root     34 Apr 18 07:59 modules.order
-rw-r--r-- 1 root root      0 Apr 18 07:59 Module.symvers

加载

  • hello.ko 模块加载到内核,要使用绝对路径:
$ insmod /root/hello-module/hello.ko
  • 日志
$ dmesg -c
[ 1834.003419] hello kernel world!
  • 查看 hello 模块是否加载
$ lsmod | grep hello
hello                  12496  0
  • 查看 modinfo 信息
$ modinfo hello.ko
filename:       /root/hello-module/hello.ko
license:        Dual BSD/GPL
retpoline:      Y
rhelversion:    7.9
srcversion:     039659EB2884A32F2B6B26F
depends:
vermagic:       3.10.0-1160.6.1.el7.x86_64 SMP mod_unload modversions
  • 将 hello 模块从内核卸载
$ rmmod hello.ko
  • dmesg -ctail /var/log/messages 查看加载日志:
$ dmesg -c
[ 1907.262481] bye kernel world!

FAQ

编译kernel版本问题

编译 hello.ko 时用的 kenerl 不是安装机器的 kenerl 版本会报如下错误:

$ insmod hello.ko
insmod: ERROR: could not insert module hello.ko: Invalid module format
$ modprobe hello.ko
modprobe: FATAL: Module hello.ko not found.

参考

  1. Linux动态链接库和静态链接库
专栏文章
  1. Linux kernel 介绍
  2. 如何快速的将Centos6.7快速升级3.10.9
  3. Centos7 切换内核
  4. Linux kernel 内核模块编译、装载和卸载(当前)
最新评论
加载中...
Home Archives Categories Tags Statistics