Linux内核中的“ OldConfig” Makefile目标
1. 概述
在本教程中,我们将配置 Linux 内核并了解其oldconfig Makefile 目标。
2. 获取Linux内核的源代码
众所周知,Linux 内核是完全开源的,我们可以从https://kernel.org 获取它的源代码。在撰写本文时,最新版本是5.14.14。让我们用curl 下载它:
$ curl -LO "https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.14.14.tar.xz"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 115M 100 115M 0 0 2688k 0 0:00:43 0:00:43 --:--:-- 2831k
现在我们可以通过运行tar xf linux-5.14.14.tar.xz和cd 进入它来用tar 提取它。
3. 构建系统
Linux 内核的构建系统主要围绕与make 工具一起使用的 Makefile。它通过顶层配置各种构建选项。配置文件。我们使用顶层Makefile通过make targets以方便的方式配置和构建内核。
4. 配置内核
我们可以使用各种配置前端来配置 Linux 内核并轻松搜索配置选项。**为此,他们在内部使用Kconfig **文件。
4.1. 基于菜单的 TUI
我们可以通过运行make menuconfig通过一个基于菜单的交互式程序来配置内核:
.config - Linux/x86 5.14.14 Kernel Configuration
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
┌───────────────────────────────────────────────── Linux/x86 5.14.14 Kernel Configuration ─────────────────────────────────────────────────┐
│ Arrow keys navigate the menu. <Enter> selects submenus ---> (or empty submenus ----). Highlighted letters are hotkeys. Pressing <Y> │
│ includes, <N> excludes, <M> modularizes features. Press <Esc><Esc> to exit, <?> for Help, </> for Search. Legend: [*] built-in [ ] │
│ excluded <M> module < > module capable │
│ │
│ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │
│ │ General setup ---> │ │
│ │ [*] 64-bit kernel │ │
│ │ Processor type and features ---> │ │
│ │ Power management and ACPI options ---> │ │
│ │ Bus options (PCI etc.) ---> │ │
│ │ Binary Emulations ---> │ │
│ │ Firmware Drivers ---> │ │
│ │ [*] Virtualization ---> │ │
│ │ General architecture-dependent options ---> │ │
│ │ [*] Enable loadable module support ---> │ │
│ │ -*- Enable the block layer ---> │ │
│ │ IO Schedulers ---> │ │
│ │ Executable file formats ---> │ │
│ │ Memory Management options ---> │ │
│ │ [*] Networking support ---> │ │
│ │ Device Drivers ---> │ │
│ │ File systems ---> │ │
│ │ Security options ---> │ │
│ │ -*- Cryptographic API ---> │ │
│ │ Library routines ---> │ │
│ └────────────────────────────────v(+)──────────────────────────────────────────────────────────────────────────────────────────────────┘ │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ <Select> < Exit > < Help > < Save > < Load > │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
我们使用顶部的图例来识别各种符号的含义,然后按空格键切换功能,使用箭头键导航菜单。
此外,我们可以找到一个名为nconfig的类似菜单,它提供模糊搜索并具有深色 UI。
4.2. 明文菜单
**我们还可以使用make config通过基于提示的基本菜单来配置内核。**我们需要回答各种选项,例如Y启用功能,N禁用它,m将其构建为模块(如果可能):
$ make config
HOSTCC scripts/kconfig/conf.o
HOSTLD scripts/kconfig/conf
*
* Linux/x86 5.14.14 Kernel Configuration
*
*
* General setup
*
Compile also drivers which will not load (COMPILE_TEST) [N/y/?] y
Local version - append to kernel release (LOCALVERSION) []
Build ID Salt (BUILD_SALT) []
Kernel compression mode
> 1. Gzip (KERNEL_GZIP)
2. Bzip2 (KERNEL_BZIP2)
3. LZMA (KERNEL_LZMA)
4. XZ (KERNEL_XZ)
5. LZO (KERNEL_LZO)
6. LZ4 (KERNEL_LZ4)
7. ZSTD (KERNEL_ZSTD)
choice[1-7?]: 5
Default init path (DEFAULT_INIT) []
Default hostname (DEFAULT_HOSTNAME) [(none)]
Support for paging of anonymous memory (swap) (SWAP) [Y/n/?] Y
这可能非常麻烦,所以大多数人更喜欢menuconfig方法。
4.3. 自动生成的配置
我们可以自动生成一个配置以从各种目标构建:
- defconfig – 根据预定义规则为当前架构生成默认配置,例如x86_64系统的arch/x86/configs/x86_64_defconfig。
- localmodconfig – 根据当前内核的配置和加载的模块生成一个配置,以禁用不需要的模块。
- localyesconfig – 与localmodconfig类似,但将所有模块 ( m ) 选项更改为内置 ( =y )。
5. oldconfig目标
oldconfig目标更新预先存在的*.config文件以与新内核一起使用。**如果我们想将旧内核的配置文件与新内核一起使用,我们可能需要这样做。**让我们在正在运行的内核配置文件上运行make oldconfig*:
$ gzip -dc /proc/config.gz > .config
$ make oldconfig
*
* Restart config...
*
*
* General setup
*
Compile also drivers which will not load (COMPILE_TEST) [N/y/?] n
Local version - append to kernel release (LOCALVERSION) []
...
uselib syscall (USELIB) [N/y/?] n
Auditing support (AUDIT) [N/y/?] n
Core Scheduling for SMT (SCHED_CORE) [N/y/?] (NEW)
我们使用gzip 提取在*/proc/config.gz中找到的压缩内核配置,使用-c标志写入stdout*。现在我们可以看到一个类似于make config 的菜单。*这里最后一个选项在内核版本之间发生了变化,并标有(NEW)*,因此我们需要设置它的值。**我们不需要设置不变的选项,因为它们保持原始值。此外,如果旧配置文件与我们的新内核完全兼容,我们将不需要回答任何提示。
**这不仅会处理新的/删除的选项,还会处理依赖项更改。**例如,它将解决CONFIG_FOO在旧内核上需要CONFIG_BAR的情况,但现在它也需要CONFIG_BAZ。
我们还可以使用make olddefconfig将新选项设置为默认值。我们不会提示他们。
6. 缺少配置选项
如果*.config文件中的某个选项被禁用,我们会发现诸如CONFIG_FOO=n或# CONFIG_FOO is not set之类的行。不满足依赖关系的选项将被完全忽略。假设我们有一个需要CONFIG_DEBUG_INFO 的符号**DEBUG_INFO_REDUCED* –如果它被禁用, DEBUG_INFO_REDUCED将不会出现在文件中:
$ grep CONFIG_DEBUG_INFO .config
# CONFIG_DEBUG_INFO is not set
$ grep DEBUG_INFO_REDUCED .config # No matches
现在,如果我们设置CONFIG_DEBUG_INFO=y并运行make oldconfig,系统会提示我们选择上述选项:
Compile the kernel with debug info (DEBUG_INFO) [Y/n/?] y
Reduce debugging information (DEBUG_INFO_REDUCED) [N/y/?] (NEW)