自编译linux内核安装问题

网上都说直接在linux内核目录下 执行 sudo make install就行了然后直接去配置grub

事实上执行sudo make install根本就不会在boot里创建编译的linux内核

在archlinux wiki上告诉我要重命名内核,问题是我根本就不知道到底要以什么格式命名

在运行mkinitcpio时,出现了

==> ERROR: module not found: 'crypto_lz4'
==> WARNING: No modules were added to the image. This is probably not what you want.

的问题,我应该怎么办

我正在编译最新的7.0rc3内核遇到的问题

你编译的内核缺少这个模块。

可以用[archlinuxcn]仓库里的linux-mainline。

不过manline里的内核版本不是最新的,我可以自己编译更新版本的内核吗

你可以修改PKGBUILD换一下版本。

建议直接看最后一键修复脚本!!!

重新获取配置

zcat /proc/config.gz > .config

启用 LZ4 支持

sed -i 's/# CONFIG_CRYPTO_LZ4 is not set/CONFIG_CRYPTO_LZ4=y/' .config
sed -i 's/# CONFIG_CRYPTO_LZ4HC is not set/CONFIG_CRYPTO_LZ4HC=y/' .config

更新配置

make olddefconfig

下面是完整笔记

根据之前的对话,以下是关于 `make oldconfig` 交互式选择的**补充笔记**,可以合并到之前的编译笔记中。

---

## :books: 补充:`make oldconfig` 的交互式选择问题

### 为什么要手动选择?

当你使用 `make oldconfig` 时,系统会:

1. 读取你复制过来的旧内核配置(`.config`)

2. 对比新内核源码,找出**新增的配置选项**

3. 对这些新增选项**逐一询问**,让你决定开启还是关闭

这就是为什么你看到 `(NEW)` 标记的选项并需要手动输入 `Y/n/m/?` 的原因。

### 三种处理方式对比

| 方式 | 命令 | 交互程度 | 适用场景 |

|------|------|----------|---------|

| **手动选择** | `make oldconfig` | 逐个询问新增选项 | 想了解新内核增加了什么功能 |

| **全部默认** | `make olddefconfig` | 无交互,自动接受默认值 | 快速编译,信任内核开发者默认配置 |

| **自动回车** | `yes "" \| make oldconfig` | 无交互,自动按回车 | 兼容旧脚本,效果同 `olddefconfig` |

### 推荐方案(最省事)

```bash

# 跳过所有交互,直接将新增选项设为默认值

make olddefconfig

# 然后直接编译

make -j$(nproc)

```

### 如果已经在交互界面中

- **继续手动完成**:每次看到 `(NEW)` 选项,直接按回车接受默认值(括号中的大写字母)

- **退出并改用自动化**:按 `Ctrl+C` 退出,然后运行 `make olddefconfig`

---

## :clipboard: 合并后的完整配置流程(CachyOS/Arch)

```bash

# 1. 获取当前内核配置

zcat /proc/config.gz > .config

# 2. 处理配置(三选一即可)

# 方案A:自动使用默认值(推荐)

make olddefconfig

# 方案B:手动处理新增选项

make oldconfig

# 方案C:交互式图形调整

make menuconfig

# 3. 编译

make -j$(nproc)

# 4. 安装(手动完成)

sudo make modules_install

sudo cp arch/x86/boot/bzImage /boot/vmlinuz-你的内核名

sudo mkinitcpio -p 你的内核名

sudo bootctl update

```

---

## :light_bulb: 一句话总结

> **`make olddefconfig` = `make oldconfig` + 自动按回车**,是最省事的配置继承方式。

好的,以下是关于**创建 mkinitcpio 预设文件解决 initramfs 生成问题**的笔记总结,可以合并到之前的内核编译笔记中。

---

## :books: 补充笔记:解决 `mkinitcpio: 没有那个文件或目录` 错误

### 问题现象

执行 `sudo mkinitcpio -p Linux-7.0.2` 时报错:

```

/usr/bin/mkinitcpio: 行 653: /etc/mkinitcpio.d/Linux-7.0.2.preset: 没有那个文件或目录

==> ERROR: Failed to load preset: '/etc/mkinitcpio.d/Linux-7.0.2.preset'

```

### 原因分析

`mkinitcpio -p` 命令需要的参数是**预设名称**,而不是内核名称。预设文件存放在 `/etc/mkinitcpio.d/` 目录下,格式为 `*.preset`。直接传入一个不存在的预设名称会导致错误。

### 解决方案对比

| 方案 | 命令 | 适用场景 |

|------|------|---------|

| 使用现有预设 | `sudo mkinitcpio -p linux-cachyos-lts` | 替换现有内核,快速测试 |

| 直接指定路径 | `sudo mkinitcpio -g /boot/initramfs-xxx.img -k /boot/vmlinux-xxx` | 临时生成,不频繁使用 |

| **创建自定义预设** | 手动创建 `.preset` 文件 | **长期使用,推荐** |

### :white_check_mark: 最终采用的方案:创建自定义预设文件

#### 步骤1:复制现有预设作为模板

```bash

sudo cp /etc/mkinitcpio.d/linux-cachyos-lts.preset /etc/mkinitcpio.d/Linux-7.0.2.preset

```

#### 步骤2:编辑预设文件

```bash

sudo nano /etc/mkinitcpio.d/Linux-7.0.2.preset

```

修改内容示例:

```bash

# 预设文件内容

ALL_config="/etc/mkinitcpio.conf"

ALL_kver="/boot/vmlinux-Linux-7.0.2" # 指向你的新内核文件

PRESETS=('default' 'fallback')

default_image="/boot/initramfs-Linux-7.0.2.img"

default_options=""

fallback_image="/boot/initramfs-Linux-7.0.2-fallback.img"

fallback_options="-S autodetect"

```

#### 步骤3:使用自定义预设生成 initramfs

```bash

sudo mkinitcpio -p Linux-7.0.2

```

#### 步骤4:更新引导配置

```bash

sudo bootctl update # systemd-boot

# 或

sudo grub-mkconfig -o /boot/grub/grub.cfg # GRUB

```

### :clipboard: 预设文件关键字段说明

| 字段 | 含义 |

|------|------|

| `ALL_kver` | 内核文件路径(`vmlinuz` 或 `vmlinux`) |

| `default_image` | 生成的 initramfs 镜像路径 |

| `fallback_image` | 备用 initramfs 镜像(包含更多驱动) |

| `ALL_config` | mkinitcpio 主配置文件路径 |

| `default_options` | 生成默认镜像时的额外选项 |

### :bullseye: 完整安装流程(更新版)

编译完成后,完整的安装步骤:

```bash

# 1. 安装内核模块

sudo make modules_install

# 2. 复制内核到 /boot

sudo cp arch/x86/boot/bzImage /boot/vmlinux-你的内核名

# 3. 创建 mkinitcpio 预设文件

sudo cp /etc/mkinitcpio.d/linux-cachyos-lts.preset /etc/mkinitcpio.d/你的内核名.preset

sudo nano /etc/mkinitcpio.d/你的内核名.preset # 修改 ALL_kver 和 *_image 路径

# 4. 生成 initramfs

sudo mkinitcpio -p 你的内核名

# 5. 更新引导

sudo bootctl update

# 6. 重启验证

sudo reboot

uname -r

```

### :light_bulb: 一句话总结

> **`mkinitcpio -p` 需要一个存在于 `/etc/mkinitcpio.d/` 目录下的 `.preset` 文件,通过复制现有预设并修改内核路径即可解决**。

根据我们从头到尾的排查和解决过程,以下是**完整的内核编译与安装笔记**,包含遇到的问题及解决方案。

---

## :books: Linux 内核编译与安装完整笔记(CachyOS/Arch)

### :one: 获取当前内核配置

CachyOS 不在 `/boot` 存放配置文件,需从运行中的内核导出:

```bash

zcat /proc/config.gz > .config

```

### :two: 配置新内核

```bash

# 自动处理新增配置项为默认值(推荐,无交互)

make olddefconfig

# 或手动处理新增选项

make oldconfig

# 或图形化调整

make menuconfig

```

### :three: 编译内核

```bash

# 完整编译(必须!否则模块不全)

make -j$(nproc)

```

> :warning: **重要**:必须执行完整编译,不能只编译部分子系统(如 `M=crypto`),否则模块数量严重不足。

### :four: 安装内核

```bash

# 安装所有模块

sudo make modules_install

# 复制内核镜像

sudo cp arch/x86/boot/bzImage /boot/vmlinuz-你的内核名

```

### :five: 生成 initramfs

#### 方法一:创建预设文件(推荐长期使用)

```bash

# 复制现有预设作为模板

sudo cp /etc/mkinitcpio.d/linux-cachyos-lts.preset /etc/mkinitcpio.d/你的内核名.preset

# 编辑预设,修改内核路径

sudo nano /etc/mkinitcpio.d/你的内核名.preset

# 修改 ALL_kver="/boot/vmlinuz-你的内核名"

# 修改 default_image="/boot/initramfs-你的内核名.img"

# 生成 initramfs

sudo mkinitcpio -p 你的内核名

```

#### 方法二:直接生成

```bash

sudo mkinitcpio -g /boot/initramfs-你的内核名.img -k /boot/vmlinuz-你的内核名

```

### :six: 更新引导

```bash

# systemd-boot(CachyOS 默认)

sudo bootctl update

# 或 GRUB

sudo grub-mkconfig -o /boot/grub/grub.cfg

```

### :seven: 验证安装

```bash

# 检查模块数量(应该 5000+)

find /lib/modules/$(uname -r) -name "*.ko" | wc -l

# 检查 initramfs 大小(应该 100MB+)

ls -lh /boot/initramfs-*.img

# 重启后检查内核版本

uname -r

```

---

## :warning: 常见问题与解决方案

| 问题 | 原因 | 解决方案 |

|------|------|---------|

| `make install` 只输出 `INSTALL /boot` | Arch 系 make install 功能不完整 | 手动执行安装步骤 |

| `/boot/config-$(uname -r)` 不存在 | CachyOS 不在 /boot 存放配置 | 使用 `zcat /proc/config.gz` |

| `mkinitcpio: 没有那个文件或目录` | 预设文件不存在 | 创建自定义预设文件 |

| `ERROR: module not found: 'crypto_lz4'` | `.config` 中未启用 LZ4 | 设置 `CONFIG_CRYPTO_LZ4=y` |

| `No modules were added to the image` | 模块未完整编译或安装 | 执行完整 `make -j$(nproc)` |

| initramfs 只有 12MB(正常应 100MB+) | 只编译了部分模块 | 清理后重新完整编译 |

| 模块数量只有十几个 | 使用了 `make M=xxx` 部分编译 | 执行完整 `make -j$(nproc)` |

---

## :wrench: 快速修复命令合集

### 启用 LZ4 支持

```bash

sed -i 's/# CONFIG_CRYPTO_LZ4 is not set/CONFIG_CRYPTO_LZ4=y/' .config

sed -i 's/# CONFIG_CRYPTO_LZ4HC is not set/CONFIG_CRYPTO_LZ4HC=y/' .config

make olddefconfig

```

### 完整清理并重新编译

```bash

make clean # 清理编译产物

make -j$(nproc) # 完整编译

sudo make modules_install # 安装模块

sudo cp arch/x86/boot/bzImage /boot/vmlinuz-内核名

sudo mkinitcpio -p 预设名

sudo bootctl update

```

### 检查模块是否完整

```bash

# 正常应有 5000-8000 个模块

find /lib/modules/7.0.2 -name "*.ko" 2>/dev/null | wc -l

```

---

## :bar_chart: 成功标志

| 检查项 | 正常值 |

|--------|--------|

| 模块数量 | 5000+ |

| initramfs 大小 | 100-130 MB |

| `mkinitcpio` 输出 | 无 `No modules were added` 警告 |

| `uname -r` 重启后 | 显示新内核版本 |

---

## :light_bulb: 核心教训

1. **必须完整编译**:`make -j$(nproc)`,不能只编译部分子系统

2. **Arch 系需手动安装**:`make install` 功能不完整

3. **需要自定义预设**:`mkinitcpio -p` 需要 `.preset` 文件

4. **LZ4 必须启用**:systemd hook 依赖它

5. **initramfs 大小是关键指标**:12MB 一定有问题,100MB+ 才正常

最后遇到的问题

## :books: 最终总结:Linux 内核编译完整指南(CachyOS/Arch)

经过完整的排错过程,以下是**成功编译并安装 Linux 内核 7.0.2** 的完整流程和关键问题的解决方案。

---

## :bullseye: 完整操作流程

### :one: 获取当前内核配置

```bash

# CachyOS/Arch 需要从 /proc 导出

zcat /proc/config.gz > .config

```

### :two: 启用必要的压缩支持

```bash

# 启用 LZ4 压缩(systemd hook 需要)

sed -i 's/# CONFIG_CRYPTO_LZ4 is not set/CONFIG_CRYPTO_LZ4=y/' .config

sed -i 's/# CONFIG_CRYPTO_LZ4HC is not set/CONFIG_CRYPTO_LZ4HC=y/' .config

# 处理新增配置项(自动接受默认值)

make olddefconfig

```

### :three: 完整编译内核

```bash

# 必须完整编译,不能只编译部分子系统

make -j$(nproc)

```

### :four: 安装内核模块

```bash

# 安装所有模块(注意:必须剥离调试符号,否则模块巨大)

sudo make modules_install INSTALL_MOD_STRIP=1

```

### :five: 复制内核镜像

```bash

sudo cp arch/x86/boot/bzImage /boot/vmlinuz-内核名

```

### :six: 创建 mkinitcpio 预设文件

```bash

# 复制现有预设作为模板

sudo cp /etc/mkinitcpio.d/linux-cachyos-lts.preset /etc/mkinitcpio.d/内核名.preset

# 修改预设文件中的路径

sudo nano /etc/mkinitcpio.d/内核名.preset

# 设置 ALL_kver="/boot/vmlinuz-内核名"

# 设置 default_image="/boot/initramfs-内核名.img"

```

### :seven: 生成 initramfs

```bash

sudo mkinitcpio -p 内核名

```

### :eight: 验证生成的文件

```bash

# 检查模块数量(应有 5000+)

find /lib/modules/内核版本 -name "*.ko" | wc -l

# 检查模块目录大小(应为 200-400 MB)

du -sh /lib/modules/内核版本

# 检查 initramfs 大小(应为 100-130 MB)

ls -lh /boot/initramfs-内核名.img

```

### :nine: 更新引导并重启

```bash

sudo bootctl update

sudo reboot

```

---

## :warning: 遇到的问题及解决方案

| 现象 | 原因 | 解决方案 |

|------|------|---------|

| `make install` 只有一行输出 | Arch 系 make install 不完整 | 手动执行安装步骤 |

| `mkinitcpio: 没有那个文件或目录` | 预设文件不存在 | 创建自定义 `.preset` 文件 |

| `ERROR: module not found: crypto_lz4` | .config 未启用 LZ4 | 设置 `CONFIG_CRYPTO_LZ4=y` |

| `No modules were added to the image` | 模块未完整编译 | 执行完整 `make -j$(nproc)` |

| initramfs 只有 **12MB** | 只编译了部分模块 | 清理后完整重新编译 |

| initramfs 高达 **837MB** | 模块包含调试符号 | 用 `INSTALL_MOD_STRIP=1` 重新安装 |

| `内存耗尽` GRUB 错误 | initramfs 过大(>200MB) | 精简 initramfs,确保 100-130MB |

---

## :wrench: 关键命令速查

### 清理并重新编译

```bash

make clean

make -j$(nproc)

sudo make modules_install INSTALL_MOD_STRIP=1

sudo cp arch/x86/boot/bzImage /boot/vmlinuz-内核名

sudo mkinitcpio -p 内核名

```

### 检查 initramfs 内容

```bash

lsinitcpio /boot/initramfs-内核名.img | head -50

lsinitcpio /boot/initramfs-内核名.img | wc -l

```

### 检查模块安装情况

```bash

find /lib/modules/内核版本 -name "*.ko" | wc -l

du -sh /lib/modules/内核版本

```

---

## :bar_chart: 成功标志对照表

| 检查项 | 正常值 |

|--------|--------|

| 模块数量 | 5000-8000 |

| `/lib/modules/` 大小 | 200-400 MB |

| initramfs 大小 | **100-130 MB**(不是 12MB,也不是 837MB) |

| `mkinitcpio` 输出 | 无 ERROR,无 `No modules were added` |

| 重启后 `uname -r` | 显示新内核版本(如 7.0.2) |

---

## :light_bulb: 核心教训

1. **必须完整编译** — `make -j$(nproc)`,不能用 `make M=xxx` 部分编译

2. **必须启用 LZ4** — `CONFIG_CRYPTO_LZ4=y`

3. **必须剥离调试符号** — `INSTALL_MOD_STRIP=1`

4. **必须手动创建预设** — Arch 系的 `mkinitcpio` 需要 `.preset` 文件

5. **initramfs 大小是健康指标** — 12MB 太小(模块不全),837MB 太大(包含调试符号),100-130MB 正常

6. **GRUB 内存耗尽 = initramfs 过大** — 精简到 200MB 以下

---

## :rocket: 一键修复脚本

```bash

#!/bin/bash

# 完整的内核编译安装脚本

cd ~/文档/linux-7.0.2

KERNEL_NAME="linux-7.0.2"

# 配置

zcat /proc/config.gz > .config

sed -i 's/# CONFIG_CRYPTO_LZ4 is not set/CONFIG_CRYPTO_LZ4=y/' .config

make olddefconfig

# 编译

make -j$(nproc)

# 安装

sudo make modules_install INSTALL_MOD_STRIP=1

sudo cp arch/x86/boot/bzImage /boot/vmlinuz-${KERNEL_NAME}

# 创建预设

sudo cp /etc/mkinitcpio.d/linux-cachyos-lts.preset /etc/mkinitcpio.d/${KERNEL_NAME}.preset

sudo sed -i "s|vmlinuz-linux-cachyos-lts|vmlinuz-${KERNEL_NAME}|g" /etc/mkinitcpio.d/${KERNEL_NAME}.preset

sudo sed -i "s|initramfs-linux-cachyos-lts|initramfs-${KERNEL_NAME}|g" /etc/mkinitcpio.d/${KERNEL_NAME}.preset

# 生成 initramfs

sudo mkinitcpio -p ${KERNEL_NAME}

# 验证

ls -lh /boot/initramfs-${KERNEL_NAME}.img

find /lib/modules/7.0.2 -name "*.ko" | wc -l

# 更新引导

sudo bootctl update

```

---

**最终你的内核 7.0.2 成功编译并安装,解决了所有问题!** :tada:

朋友,我觉得用 Chat GBT 来分发软件不太好。Chat GBT 只适合用来寻求帮助;其他所有东西都可以在 Arch Wiki 上找到。我用的是 ArchiSO,它很好用,我推荐给你,但我不太确定它有没有中文文档。

谢谢 gpt很有用 这个问题我在wiki上没看到类似的

谢谢!如果您有任何问题,请随时提出;我会尽力解答。:slight_smile:

我之前搜过archwiki没有发现具体的kernel编译流程介绍以及选项具体作用介绍,如果我是新手我甚至连怎么打开config都不知道,这感觉是一个痛点

你說得對,這確實是個好觀點。

那个格式乱七八糟的帖子我就不看了。就内核编译来说的话:

  • 推荐使用PKGBUILD来编译。你可以在官方软件包的基础上修改,也可以去AUR翻找。
  • 走手动流程的话,就是发行版无关的了。网上应该能找到挺多教程的啊,我当年就完全没有遇到流程性的问题,更多的问题在于各种选项的开关。