Contents

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.xzcd 进入它来用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)