Eudyptula Challenge 和内核路径

Eudyptula Challenge and kernel path

我决定参加 Eudyptula Challenge。 在我提交第一个任务是构建一个简单的 "Hello World!" 模块后,我收到了以下答案。

Please read the requirements for the Makefile and allow the module to be built against any kernel source tree on the filesystem, not just those kernels that happened to be installed in /lib/ at some point in time.

要求是:

The Makefile should be able to build the kernel module against the source of the currently-running kernel as well as being able to accept an arbitrary kernel sources directory from an environment variable.

我正在做的是检查是否设置了环境变量KERNELRELEASE。如果是,我将针对

构建模块
$(KERNELRELEASE)/build  

如果不反对

/lib/modules/$(shell uname -r)/build

我不明白为什么这不能满足这个任务的要求。

根据 Eudyptula challenge rules, it is prohibited to give you direct solution, so I will try to describe elements of answer, so you can come up with solution by yourself. Basically, everything I've written below is described pretty much in Documentation/kbuild/modules.txt file (especially in section 3.1 - Shared Makefile ),所以我认为这不会违反某种规则。所以下面只是对提到的文档中描述的内容的解释。

KERNELRELEASE变量

你认为 $(KERNELRELEASE) 是为了保留通往内核的路径是错误的。 $(KERNELRELEASE) 变量的实际含义——您可以在 Documentation/kbuild/makefiles.txt:

中找到它

KERNELRELEASE

$(KERNELRELEASE) is a single string such as "2.4.0-pre4", suitable for constructing installation directory names or showing in version strings. Some arch Makefiles use it for this purpose.

事实是,您的 Makefile 将被执行 2 次:来自 您的 make 命令和来自 kernel Makefile$(KERNELRELEASE) 可以帮助理解:

  1. 如果未定义此变量,则您的 Makefile 是 运行ning 来自您的 make 命令;在此步骤中,您将执行内核的 Makefile(使用 -C 参数提供内核目录)。一旦内核的 Makefile 有了 运行 make(来自 Makefile 的 inside),你的 Makefile 将被第二次执行(见下一节)项).
  2. 如果定义了此变量,则您的 Makefile 将从内核的 Makefile 执行(它定义了此变量并调用了您的 Makefile )。在此步骤中,您可以使用内核构建系统功能,例如 obj-m.

-C参数

您真正需要做的是在 Makefile 中定义一些自定义变量,它将保存内核目录路径。例如,您可以将其称为 KDIR。如您所知,您的内核源代码位于此路径:/lib/modules/$(shell uname -r)/build。接下来,您可以在执行内核的 Makefile 时将此变量提供给 -C 参数(参见 man 1 make)。

接下来,您必须能够从 Makefile 外部传递此变量。为此,可以使用 conditional variable assignment operator:

KDIR ?= /lib/modules/$(shell uname -r)/build

如果您将 KDIR 变量传递给您的 Makefile,则采用这种方式,如下所示:

$ make KDIR=bla-bla-bla

KDIR 变量将具有您传递的值。否则它将包含默认值,即 /lib/modules/$(shell uname -r)/build.