Eudyptula挑战和内核路径

时间:2015-05-04 13:16:47

标签: makefile linux-kernel eudyptula-challenge

我决定采用Eudyptula Challenge。 在我提交了第一个任务之后,就是构建一个简单的“Hello World!”模块,我收到了以下答案。

  

请阅读Makefile的要求并允许该模块   针对文件系统上的任何内核源代码树构建,而不仅仅是那些   在某个时间点碰巧安装在/lib/中的内核。

要求是:

  

Makefile应该能够构建内核模块   当前运行的内核的源代码以及能够接受的内容   来自环境变量的任意内核源目录。

我正在做的是检查是否设置了环境变量KERNELRELEASE。如果是我构建模块

$(KERNELRELEASE)/build  

如果不反对

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

我无法理解为什么这不能满足这项任务的要求。

1 个答案:

答案 0 :(得分:26)

根据Eudyptula challenge规则,禁止直接向您提供解决方案,因此我将尝试描述答案的元素,以便您自己提出解决方案。基本上,下面我写的所有内容都在Documentation/kbuild/modules.txt文件中进行了详细介绍(尤其是在section 3.1 - Shared Makefile文件中),因此我认为这不会违反某些规则。以下是对上述文档中描述内容的解释。

KERNELRELEASE变量

您错误的是认为$(KERNELRELEASE)旨在保留内核的路径。 $(KERNELRELEASE)变量实际意味着什么 - 您可以在Documentation/kbuild/makefiles.txt中找到它:

  

KERNELRELEASE

     

$(KERNELRELEASE)是一个单独的字符串,例如"2.4.0-pre4",非常合适   用于构造安装目录名称或显示在   版本字符串。某些拱门Makefiles将其用于此目的。

问题是,您的Makefile将被执行2次:来自您的 make命令以及内核 {{1} }。 Makefile可以帮助您解决问题:

  1. 如果未定义此变量,则$(KERNELRELEASE)正在运行Makefile命令;在这一步,您将执行内核make(使用Makefile param提供内核目录)。为内核的Makefile(来自Makefile的里面)运行-C后,您的make将第二次执行(参见下一项)。
  2. 如果定义了此变量,则Makefile正在从内核Makefile执行(Makefile(定义此变量并将Makefile调回)。在此步骤中,您可以使用内核构建系统功能,例如obj-m
  3. -C param

    您真正需要做的是在Makefile中定义一些自定义变量,该变量将保存内核目录路径。例如,您可以将其称为KDIR。如您所知,您的内核源位于此路径:/lib/modules/$(shell uname -r)/build。接下来,您可以在执行内核的Makefile时将此变量提供给-C param(请参阅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