主内核 "make" 命令是否也在内部制作模块?
Does the main kernel "make" command also make modules internally?
我正在学习如何编写内核驱动程序,这是我第一次尝试构建内核驱动程序。我为我的模块文件创建了一个文件夹 drivers/naveen/
- hello.c
、Kconfig
和 Makefile
。这些是这些文件的内容:
Kconfig
config HELLO_WORLD
tristate "Hello World support"
default m
---help---
This option enables printing hello world
生成文件
obj-$(CONFIG_HELLO_WORLD) += hello.o
hello.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
static int __init hello_init(void)
{
printk(KERN_ERR "This is NAVEEN module");
return 0;
}
static int __exit hello_exit(void)
{
printk(KERN_ERR "NAVEEN exiting module");
return 0;
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Naveen");
MODULE_LICENSE("GPL");
此外,我在 drivers/Makefile
中添加了以下行:
obj-$(CONFIG_HELLO_WORLD) += naveen/
和 drivers/Kconfig
中的以下行:
source "drivers/naveen/Kconfig"
我生成的 .config
包含 CONFIG_HELLO_WORLD=m
.
我做了 make ARCH=x86_64 -j16
,我可以看到生成了 hello.ko
。为什么?我期望只有在我完成 make modules
之后才会生成它,因为它的集合与 .config
中的 m
一样模块化,而不是仅使用 make 进行编译。有人可以向我解释这种行为或我做错了什么吗?
这是否意味着 make
也 make modules
。我可以从 make help
看到 make
实际上意味着 make all
因此它应该在内部也做 make modules
,所以应该没有必要做 make modules
一旦制作成功。
你没有做错任何事。 modules
目标自内核版本 2.6.0 以来一直是 all
目标的依赖项(我认为实际上是从内核版本 2.5.60 开始)。
添加模块的方式是将其添加到内核源代码树中。也可以在内核源代码树之外构建自定义模块——所谓的 "out-of-tree" 内核模块。通常,那些不需要 Kconfig 文件,obj-$(CONFIG_HELLO_WORLD)
将在 Makefile 中替换为 obj-m
。
这是 "out-of-tree" 版本的 "hello" 模块的 Makefile:
ifneq ($(KERNELRELEASE),)
# Kbuild part of Makefile
obj-m += hello.o
else
# Normal part of Makefile
#
# Kernel build directory specified by KDIR variable
# Default to running kernel's build directory if KDIR not set externally
KDIR ?= "/lib/modules/`uname -r`/build"
all:
$(MAKE) -C "$(KDIR)" M=`pwd` modules
clean:
$(MAKE) -C "$(KDIR)" M=`pwd` clean
endif
此 Makefile 使用了一个通用技巧,因此可以将同一个 Makefile 作为 "normal" Makefile 和 "kbuild" Makefile 调用。 else
和 endif
行之间的 "normal" 部分在内核的 Makefile 上调用 $(MAKE)
(其位置由 KDIR
变量指定),告诉它在当前目录中构建 modules
目标(由 M=`pwd`
指定)。 "kbuild" 部分位于 ifneq($(KERNELRELEASE),)
和 else
行之间,是构建内核部分的正常 "kbuild" 格式。
该技巧取决于 KERNELRELEASE
变量最初未设置或为空。它将被内核的 Makefile 规则设置为一个非空值。
Linux 内核由两部分组成——核心内核和模块。当我们简单地做 make
时,它的意思是 make all
,也就是 make vmlinux && make modules
。因此,如果我们已经完成了 make
,我们就不需要再做 make modules
,我们可以简单地 运行 命令 make modules_install
而无需执行 make modules
.
我正在学习如何编写内核驱动程序,这是我第一次尝试构建内核驱动程序。我为我的模块文件创建了一个文件夹 drivers/naveen/
- hello.c
、Kconfig
和 Makefile
。这些是这些文件的内容:
Kconfig
config HELLO_WORLD
tristate "Hello World support"
default m
---help---
This option enables printing hello world
生成文件
obj-$(CONFIG_HELLO_WORLD) += hello.o
hello.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
static int __init hello_init(void)
{
printk(KERN_ERR "This is NAVEEN module");
return 0;
}
static int __exit hello_exit(void)
{
printk(KERN_ERR "NAVEEN exiting module");
return 0;
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_AUTHOR("Naveen");
MODULE_LICENSE("GPL");
此外,我在 drivers/Makefile
中添加了以下行:
obj-$(CONFIG_HELLO_WORLD) += naveen/
和 drivers/Kconfig
中的以下行:
source "drivers/naveen/Kconfig"
我生成的 .config
包含 CONFIG_HELLO_WORLD=m
.
我做了 make ARCH=x86_64 -j16
,我可以看到生成了 hello.ko
。为什么?我期望只有在我完成 make modules
之后才会生成它,因为它的集合与 .config
中的 m
一样模块化,而不是仅使用 make 进行编译。有人可以向我解释这种行为或我做错了什么吗?
这是否意味着 make
也 make modules
。我可以从 make help
看到 make
实际上意味着 make all
因此它应该在内部也做 make modules
,所以应该没有必要做 make modules
一旦制作成功。
你没有做错任何事。 modules
目标自内核版本 2.6.0 以来一直是 all
目标的依赖项(我认为实际上是从内核版本 2.5.60 开始)。
添加模块的方式是将其添加到内核源代码树中。也可以在内核源代码树之外构建自定义模块——所谓的 "out-of-tree" 内核模块。通常,那些不需要 Kconfig 文件,obj-$(CONFIG_HELLO_WORLD)
将在 Makefile 中替换为 obj-m
。
这是 "out-of-tree" 版本的 "hello" 模块的 Makefile:
ifneq ($(KERNELRELEASE),)
# Kbuild part of Makefile
obj-m += hello.o
else
# Normal part of Makefile
#
# Kernel build directory specified by KDIR variable
# Default to running kernel's build directory if KDIR not set externally
KDIR ?= "/lib/modules/`uname -r`/build"
all:
$(MAKE) -C "$(KDIR)" M=`pwd` modules
clean:
$(MAKE) -C "$(KDIR)" M=`pwd` clean
endif
此 Makefile 使用了一个通用技巧,因此可以将同一个 Makefile 作为 "normal" Makefile 和 "kbuild" Makefile 调用。 else
和 endif
行之间的 "normal" 部分在内核的 Makefile 上调用 $(MAKE)
(其位置由 KDIR
变量指定),告诉它在当前目录中构建 modules
目标(由 M=`pwd`
指定)。 "kbuild" 部分位于 ifneq($(KERNELRELEASE),)
和 else
行之间,是构建内核部分的正常 "kbuild" 格式。
该技巧取决于 KERNELRELEASE
变量最初未设置或为空。它将被内核的 Makefile 规则设置为一个非空值。
Linux 内核由两部分组成——核心内核和模块。当我们简单地做 make
时,它的意思是 make all
,也就是 make vmlinux && make modules
。因此,如果我们已经完成了 make
,我们就不需要再做 make modules
,我们可以简单地 运行 命令 make modules_install
而无需执行 make modules
.