linux内核源码编译安装-如何编译Linux内核模块

Ubuntu版本:ubuntu-gnome-16.04-desktop-amd64,gnome版本

-------------------------------------------------- ----------------------------------

本文主要介绍如何在内核外编译内核模块,即:

如何构建树外内核模块。

1. 代码hello.c

#include  //所有模块都需要的头文件
#include    // init&exit相关宏
#include 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("baoli");
MODULE_DESCRIPTION("hello world module");
static int __init hello_init(void)
{
      printk(KERN_WARNING "hello world.n");
      return 0;
}
static void __exit hello_exit(void)
{
      printk(KERN_WARNING "hello exit!n");
}
module_init(hello_init);
module_exit(hello_exit);

2. 生成文件

ifneq ($(KERNELRELEASE),)
obj-m :=hello.o
else
KDIR :=/lib/modules/$(shell uname -r)/build
all:
	make -C $(KDIR) M=$(PWD) modules
clean:
	rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order
endif

3. 编译和测试

makesudo insmod hello.kodmesgsudo rmmod 你好

内核信息如下:

[156596.317933]你好世界。

[156604.933930]你好退出!

linux内核源码编译安装-如何编译Linux内核模块

4.Makefile分析

4.1 多个源文件

如果你有一个名为 module.ko 的模块,它来自多个源文件(我们称它们为 file1.c 和 file2.c),正确的写法应该是:

obj-m := 模块.o

模块-objs := file1.o file2.o

4.2 清洁

rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order

可以替换为:

使 -C $(KDIR) M=$(PWD) 干净

4.3 内核释放

在典型的构建中该 makefile 会被读取两次。

KERNELRELEASE 是在内核源代码的顶层 Makefile 中定义的变量。 第一次(一开始)读取并执行Makefile时,KERNELRELEASE没有定义(空),所以make会在执行完else后读取内容。 如果make的目标是clean,则直接执行clean操作,然后结束。 当make的目标为all时,-C(KDIR)表示跳转到内核源码目录去读取那里的Makefile,M=(PWD)表示返回当前目录继续读取并执行当前的Makefile。 从内核源码目录返回时,KERNELRELEASE已经被定义,kbuild也已经开始解析kbuild句型的句子,make会继续读取else之前的内容(指obj-m:=hello.o) 。 else之前的内容是一句kbuild句型,表示模块源码中各个文件的依赖关系,以及要生成的目标模块的名称。

4.4 对象-m

obj-m :=hello.o 表示编译连接后会生成hello.o模块。

module-objs := file1.o file2.o file3.o 表示 module.o 是由 file1.o、file2.o 和 file3.o 链接生成的。

在modules.txt中提到:

obj-m := .o

kbuild系统将从.c构建.o,

链接后,将生成内核模块 .ko。

上面的行可以放入“Kbuild”文件或“Makefile”中。

当模块是从多个源构建时,需要添加一行

需要列出文件:

-y := .o .o ...

4.5 $(KDIR)

/lib/modules/$(shell uname -r)/build 是内核顶层makefile 所在的路径。

$(shell uname -r):调用shell命令显示内核版本。 在我的系统上它是 4.4.0-109-generic

4.6 kbuild 生成文件

Kbuild系统使用Kbuild Makefile来编译内核或模块。 解析Kernel Makefile后linux内核源码编译安装,Kbuild将读取相关的Kbuild Makefile来编译内核或模块。 Kbuild Makefile 有特定的句型来指定哪些内容编译到内核中,哪些内容编译成模块,以及对应的源文件是什么。 内核和驱动程序开发人员需要编译此 Kbuild Makefile。

目标定义是Kbuild Makefile的主要部分和核心部分。 主要定义了要编译的文件、所有选项以及执行递归操作的子目录。 最简单的 Kbuild makefile 仅包含一行:

示例:obj-y += foo.o

这个例子告诉Kbuild这个目录中有一个名为foo.o的目标文件。 foo.o 将从 foo.c 或 foo.S 文件编译。 如果要将 foo.o 编译成模块,则必须使用 obj-m。 使用的方法如下:

示例: obj-$(CONFIG_FOO) += foo.o

$(CONFIG_FOO) 可以是 y(编译到内核)或 m(编译到模块)。 如果CONFIG_FOO不是y和m,那么该文件将不会被编译和连接。

4.7 -C $KDIR 和 M=$PWD

下面是内核文档/kbuild/modules.txt中介绍的。

-C$KDIR

内核源码所在的目录。

“make”实际上会更改到指定目录

执行时会变回来。

M=$PWD

通知 kbuild 正在构建外部模块。

赋予“M”的值是绝对路径

外部模块(kbuild 文件)所在目录

位于。

4.8 模块

构建外部模块时,仅使用“make”的子集

目标是可用的。

make -C $KDIR M=$PWD [目标]

默认情况下将构建位于当前位置的模块

目录linux内核源码编译安装,因此不需要指定目标。 全部

输出文件也将在此目录中生成。 不

尝试更新内核源代码,这是一个

前提是已经执行了成功的“make”

核心。

模块

外部模块的默认目标。 它有

与未指定目标的功能相同。 看

上面的描述。

模块安装

安装外部模块。 默认位置是

/lib/modules//extra/,但前缀可能

添加 INSTALL_MOD_PATH(第 5 节中讨论)。

干净的

仅删除模块目录中所有生成的文件。

帮助

列出外部模块的可用目标。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 源码编译 linux内核源码编译安装-如何编译Linux内核模块 https://www.wkzy.net/game/198574.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务