Linux 内核 Makefile 解释Linux 内核 Makefile 解释Linux 内核 Makefile 解释Linux 内核 Makefile 解释
  • 业务
  • 目标
  • 支持
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容

Linux 内核 Makefile 解释

发表 admin at 2025年2月28日
类别
  • 未分类
标签

在软件开发中,创建和管理大型代码存储库的过程很容易变得非常复杂。

为了管理和降低这种复杂性,软件开发人员将代码组织在链接到特定模块的小文件中。开发人员可以单独编译每个文件,然后将它们链接在一起以创建最终的软件可执行文件。

例如,C 项目由扩展名为 .c 的源代码文件和扩展名为 .h 的软件接口组成。每个源文件与要创建的头文件一起编译。 o 使用库链接在一起的对象,从而创建可执行文件。

为了执行此过程,软件开发人员使用 Make 等工具来自动执行构建过程和所需的文件依赖项。 Make 使用 Makefile 来管理编译过程的行为。

GNU Make 工具提供了一组用于创建 Makefile 的规则和约定,降低了复杂性,提高了效率。

在本教程中,我们将讨论 Linux 内核 Makefile,特别是 Kconfig 和 Kbuild。

在开始之前,需要注意的是,本文并不假装教授有关内核构建系统的所有内容。不过,我们提供了构建 vmlinux 映像和模块的高级概述。

如果您需要本教程范围之外的信息,我们建议您使用以下资源以获得更好的信息:

https://linkfy.to/goMakefilesDocs

https://linkfy.to/gnuMake

内核 Makefile:概述

内核构建系统,也称为配置系统,对于那些需要它的人来说是一个必不可少的工具,它已经存在了一段时间。然而,并不是每个人都会使用这个系统;甚至驱动程序和其他低级软件开发人员也很少使用它。既然您正在阅读本文,这意味着您想了解更多有关内核构建系统的信息。

因此,我们将讨论内核是如何编译的,并讨论 Kbuild 和 Kconfig 系统,以便您可以更好地理解它们。

内核 Makefile 有五个核心组件:

  1. Makefile:这是位于源根目录中的顶级 make 文件。

  2. arch/$ (ARCH) Makefile:这是 arch Makefile;它作为顶层 Makefile 的补充。

  3. .config:这是内核配置文件。

  4. Scripts/Makefile.*:这定义了所有 kbuild Makefile 的设置规则。

  5. Kbuild Makefiles: kbuild Makefiles 大约有 500 个,而且它们不太容易阅读。考虑一个文件,例如:

https://elixir.bootlin.com/linux/latest/source/scripts/Kbuild.include

内核配置

Kconfig 文件包含在使用 make *config 时提供帮助的模块。它帮助内核进行选择性配置,为内核构建过程创建模块化和可定制性。

Kconfig 系统指定了各种配置目标。您可以使用 make help 查看可用的目标。这些目标在构建过程中由内核提供的各种程序处理。

一些 Kconfig 目标包括:

  • 配置:这用于使用线路程序更新内核配置文件。

  • Menuconfig:这是一个 Kconfig 功能或机制,提供对内核选项的基于菜单的访问。要启动 menuconfig 和其他 Kconfig 功能,您应该位于平台项目目录中。您可以使用以下命令启动 Kconfig menuconfig 功能。但是,您还可以使用其他 GUI Linux 内核配置功能(例如 xconfig 和 gconfig)启动 menuconfig。

  • make linux-windriver.menuconfig – Executes menuconfig in a separate terminal session.
  • gconfig 和 xconfig: Gconfig 激活基于 GUI 的 Linux 内核功能。 Gconfig 采用 GTK 或(基于 X)的 UI。另一方面,Xconfig 使用基于 Qt 的 UI。使用以下命令分别启动 gconfig 和 xconfig:

make linux-windriver.gconfig

make linux-windriver.xconfig

注意:要使用 gconfig 和 xconfig,您应该在主机系统上安装 QT 开发工具。

  • Nconfig: Nconfig 功能运行当前配置(Buildtools)并适用于 Ncurses 菜单驱动程序。这允许您在构建内核时选择要构建的包,例如 CPU、驱动程序和文件系统。使用命令:make nconfig。

  • Oldconfig:oldconfig 功能允许您将较新的 .config 文件应用到较旧的内核配置文件。例如,旧的 .config 文件和较新的 .config 文件(较新的内核版本)会有差异,这意味着您需要在内核构建之前更新当前配置。您可以使用 make oldconfig 通过应用旧配置文件中缺少的选项来交互式更新旧配置。

  • Defconfig:此功能允许内核构建系统将 defconfig 提供的新配置添加到 .config 文件中。更准确地说,Kbuild 系统检查所有 Kconfig 文件。如果 defconfig 在文件中指定了一个选项,Kbuild 系统将使用指定的值将该选项添加到 .config 中。如果 defconfig 没有提及该选项,Kbuild 将使用 .config 中的默认值。

考虑以下:

来自以下资源的 Defconfig 代码快照:

https://elixir.bootlin.com/linux/v5.9/source/scripts/kconfig/Makefile#L98

1.  defconfig: $(obj)/conf
2.  ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG)),)
3.      @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
4.      $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
5.  else
6.      @$(kecho) "*** Default configuration is based on target '$(KBUILD_DEFCONFIG)'"
7.      $(Q)$(MAKE) -f $(srctree)/Makefile $(KBUILD_DEFCONFIG)
8.  endif
9.   
10. %_defconfig: $(obj)/conf
11.     $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
12.  
13. configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@)
14.  
15. %.config: $(obj)/conf
16.     $(if $(call configfiles),, $(error No configuration exists for this target on this architecture))
17.     $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles)
18.     $(Q)$(MAKE) -f $(srctree)/Makefile olddefconfig

来自以下资源的旧配置代码快照:

https://elixir.bootlin.com/linux/v5.9/source/scripts/kconfig/conf.c#L694

1.      case olddefconfig:
2.      default:
3.          break;
4.      }
5.   
6.      if (input_mode == savedefconfig) {
7.          if (conf_write_defconfig(defconfig_file)) {
8.              fprintf(stderr, "n*** Error while saving defconfig to: %s\n\n",
9.                  defconfig_file);
10.             return 1;
11.         }
12.     } else if (input_mode != listnewconfig && input_mode != helpnewconfig) {
13.         if (!no_conf_write && conf_write(NULL)) {
14.             fprintf(stderr, "\n*** Error during writing of the configuration.\n\n");
15.             exit(1);
16.         }
17.  
18.         /*
19.          * Create auto.conf if it does not exist.
20.          * This prevents GNU Make 4.1 or older from emitting
21.          * "include/config/auto.conf: No such file or directory"
22.          * in the top-level Makefile
23.          *
24.          * syncconfig always creates or updates auto.conf because it is
25.          * used during the build.
26.          */
27.         if (conf_write_autoconf(sync_kconfig) && sync_kconfig) {
28.             fprintf(stderr,
29.                 "\n*** Error during sync of the configuration.\n\n");
30.             return 1;
31.         }
32.     }
33.     return 0;
34. }
  • Savedefconfig:该规则以./defconfig的形式保存当前的.config,它被视为最小配置文件。使用命令:make savedefconfig

  • Listnewconfig:这用于列出新选项。

  • Kvmconfig:这将启用 KVM 支持选项。使用命令:make kvm_guest.config

  • Allyesconfig:这将构建一个新的内核配置文件,并将所有选项设置为 yes。它与 allnoconfig 相反。

  • Allmodconfig:这会构建一个新的内核配置,默认情况下会启用该模块。

  • Randconfig:这会构建一个新的内核配置文件,其中包含所有选项的随机答案。

  • Tinyconfig:这使得最小的内核成为可能。

Kconfig系统中有很多目标。一些常见的包括 config 和 menuconfig。

如前所述,目标由主机系统中的各种程序处理,提供 GUI 或命令行。您可以在内核源代码的 /scripts/Kconfig 中找到 Kconfig 工具。

https://elixir.bootlin.com/linux/latest/source/scripts/kconfig

https://elixir.bootlin.com/linux/latest/source/scripts/kconfig/Makefile

第一个过程通常是读取根目录下的Kconfig文件,该文件用于构建初始配置数据库。随着该过程的继续,数据库在按以下顺序读取文件时更新:

.config

/lib/modules/$(shell,uname-r)/.config

/etc/kernel-config

/boot/config-$(shell,uname-r)

ARCH_DEFCONFIG

arch/$(ARCH)/defconfig

然后将 .config 文件放入syncconfig,后者接受 .config 文件作为输入。它处理文件并输出文件,然后将文件分为各种类别,例如:

  • autoconf.h:用于C语言源文件。

  • auto.conf 和 tristate.conf: 它们用于 Makefile 文本处理。

  • /includes/config: 这些是依赖项跟踪中使用的空头文件。

Kbuild 文件

几乎所有内核文件都是使用 Kbuild 基础结构的 Kbuild Makefile,这是一个递归 make 功能。递归Make 是一种将Make 工具用作Makefile 中的命令的方法。编译大型项目时,递归非常有用。

Kbuild 通过引用我们在上一节中提到的所有文件来工作。

Kbuild 系统使用顶级 Makefile 构建其组件,其中包括配置文件中名为 arch/$ (ARCH)/Makefile 的 arch Makefile。它递归地下降到子目录中,使用 script/Makefile.* 中的例程在组件上调用 Make。然后 Kbuild 在相邻对象的基础上构建并将它们链接到对象中,创建 vmlinux。

要了解有关 Kbuild Makefile 中使用的语法的更多信息,请参阅文档。

考虑以下脚本。

https://github.com/torvalds/linux/blob/master/scripts/link-vmlinux.sh

用于创建 vmlinux 的 o 目标文件首先在各自的内置 .a 文件中编译为 var KBUILD_VMLINUX_INIT,MAIN,LIBS。这些都是在 vmlinux 中编写的。

https://github.com/torvalds/linux/blob/master/scripts/Makefile.build

结论

在本指南中,我们了解了内核构建系统中的 Kbuild 和 Kconfig 系统及其工作原理。正如我们在教程开头提到的,讨论的主题很广泛,无法在单个教程中涵盖。

©2015-2025 Norria support@norria.com