# Ubuntu 24.04:安装自编译 HWE 6.17 内核 deb(自定义补丁或上游源码树产物) 面向:**先按第 0 节在 Noble 上编译出 deb**,再在 **`kernel-src/`**(与源码 **`kernel-src/linux-hwe-6.17-6.17.0/`** 同级)得到 `linux-image-unsigned-*`、`linux-modules-*` 等包,然后在 **目标机** 上安装并重启验证。也可只读 **第 1 节起**(仅安装他人编译好的 deb)。 ### 路径约定(本仓库) 以下命令默认你在 **本机克隆目录** 下操作;若路径不同,只改 **`REPO_ROOT`** 一处即可。 | 变量 / 目录 | 含义 | |-------------|------| | `REPO_ROOT` | 仓库根,例如 `~/chromebox_10th_audio_driver` | | `$REPO_ROOT/kernel-src/linux-hwe-6.17-6.17.0` | HWE 6.17 解压源码(`SRC`,打补丁与 `debian/rules` 在此) | | `$REPO_ROOT/kernel-src` | **`fakeroot debian/rules binary-generic` 生成的 `.deb` 通常落在此目录**(与源码子目录同级;`scripts/ubuntu-hwe-617-build.sh install` 亦从该父目录取 deb) | | `$REPO_ROOT/patches/ubuntu-hwe-6.17/` | 自定义补丁(如 `0001-*.patch`) | | `$REPO_ROOT/scripts/ubuntu-hwe-617-build.sh` | 应用补丁 / 依赖 / 编译 / 安装脚本 | ```bash REPO_ROOT="$HOME/chromebox_10th_audio_driver" DEB_DIR="$REPO_ROOT/kernel-src" SRC="$REPO_ROOT/kernel-src/linux-hwe-6.17-6.17.0" ``` 若把 deb 拷到其它机器安装,将下文中的 **`DEB_DIR`** 换成你存放 `.deb` 的目录即可。 更细的源码获取方式(`apt source`)见 **[kernel-src/README.md](../kernel-src/README.md)**。 --- ## 0. 编译:打补丁与生成 deb 环境:**Ubuntu 24.04 (Noble) amd64**,已用 `apt source` 将 **`linux-hwe-6.17`** 解压到 **`$REPO_ROOT/kernel-src/linux-hwe-6.17-6.17.0/`**(目录名需与脚本里 **`SRC`** 一致)。 ```bash REPO_ROOT="$HOME/chromebox_10th_audio_driver" export SRC="$REPO_ROOT/kernel-src/linux-hwe-6.17-6.17.0" ``` **可选补丁**(有则设置 **`PATCH` 为绝对路径**;无补丁则不要 `export PATCH`,并**不要**执行下面的 `apply`): ```bash export PATCH="$REPO_ROOT/patches/ubuntu-hwe-6.17/0001-ASoC-SOF-ipc3-pcm-await-DSP-reply-for-FREE-and-trigger.patch" ``` 在**未打过该补丁**的干净源码树上执行一次 `apply`;若提示 *Reversed or previously applied*,说明已打过,**跳过 `apply`** 即可: ```bash "$REPO_ROOT/scripts/ubuntu-hwe-617-build.sh" apply ``` 安装编译依赖(需联网、`sudo`;一台机通常只需做一次): ```bash "$REPO_ROOT/scripts/ubuntu-hwe-617-build.sh" deps ``` 编译内核 deb(耗时与磁盘占用大;并行度可用环境变量控制): ```bash export CONCURRENCY_LEVEL="$(nproc)" "$REPO_ROOT/scripts/ubuntu-hwe-617-build.sh" build ``` 等价于在 **`SRC`** 下执行 **`fakeroot debian/rules clean`** 与 **`fakeroot debian/rules binary-generic`**。成功后 **`.deb` 一般在 `$REPO_ROOT/kernel-src/`**(与 `linux-hwe-6.17-6.17.0` 同级)。 **注意**: - 若在 **`SRC`** 里跑过 **`make defconfig` / `make`** 等,再执行 **`build`** 可能报源码树不干净;在 **`SRC`** 根目录执行 **`make mrproper`** 后再 **`build`**(说明见 [kernel-src/README.md](../kernel-src/README.md))。 - 脚本 **`all`** 仅 **`deps` + `build`**,**不会**自动 `apply`;需要补丁时请显式 **`apply`**。 --- ## 1. 安装前确认 - **架构**:deb 文件名含 `_amd64.deb`,仅适用于 64 位 x86。 - **版本成对**:`linux-image-unsigned-6.17.0-19-generic` 与 `linux-modules-6.17.0-19-generic` 的 **版本号后缀必须一致**(例如均为 `6.17.0-19.19~24.04.2`)。 - **Secure Boot**:`linux-image-unsigned` **未签名**。若 UEFI 中 **Secure Boot 开启**,可能无法启动该内核(黑屏或回到固件)。需 **关闭 Secure Boot**,或改用带签名的官方内核流程(本仓库不覆盖自行签名)。 - **回滚**:安装前建议记下当前内核:`uname -r`。保留旧内核可在 GRUB「Advanced options」里选回。 --- ## 2. 推荐安装命令 在存放 deb 的目录执行(本仓库一般为 **`DEB_DIR` = `~/chromebox_10th_audio_driver/kernel-src`**): ```bash REPO_ROOT="$HOME/chromebox_10th_audio_driver" DEB_DIR="$REPO_ROOT/kernel-src" cd "$DEB_DIR" sudo dpkg -i \ linux-image-unsigned-6.17.0-19-generic_6.17.0-19.19~24.04.2_amd64.deb \ linux-modules-6.17.0-19-generic_6.17.0-19.19~24.04.2_amd64.deb ``` **重要(WiFi / 其它外设)**:Ubuntu HWE 6.17 常把大量驱动拆到 **`linux-modules-extra-*`**,Intel 无线还常有独立包 **`linux-modules-iwlwifi-*`**。**只装 `linux-image` + `linux-modules` 而不装与当前内核同版本的 extra / iwlwifi**,可能出现 **无线网卡无模块、WiFi 消失**。同一次 `binary-generic` 产物目录里若有这些 deb,请 **一并安装**(版本号与文件名以你本机为准): ```bash REPO_ROOT="$HOME/chromebox_10th_audio_driver" DEB_DIR="$REPO_ROOT/kernel-src" cd "$DEB_DIR" sudo dpkg -i \ linux-image-unsigned-6.17.0-19-generic_*.deb \ linux-modules-6.17.0-19-generic_*.deb \ linux-modules-extra-6.17.0-19-generic_*.deb sudo apt-get install -f # 若同目录存在 iwlwifi 分包(Intel 无线常见),再执行(无此文件则跳过): # sudo dpkg -i linux-modules-iwlwifi-6.17.0-19-generic_*.deb && sudo apt-get install -f ``` **依赖提示**:`linux-modules-extra-*` 依赖 **`wireless-regdb`**。若 `dpkg -i` 报 *depends on wireless-regdb*,可先 `sudo apt-get install -y wireless-regdb`,再 `sudo dpkg -i ... linux-modules-extra-...` 或 `sudo apt-get install -f`(按提示装齐后执行 `sudo dpkg --configure -a`)。 若目录下 **没有** `linux-modules-extra-*.deb`,说明未拷贝全量产物,需从编译机 **`$REPO_ROOT/kernel-src/`** 把同版本 **`linux-modules-extra-*`、`linux-modules-iwlwifi-*`**(若有)拷回再装。 版本号随你实际编译输出变化时,可用通配符(注意目录里不要有多个冲突版本): ```bash sudo dpkg -i linux-image-unsigned-6.17.0-19-generic_*.deb linux-modules-6.17.0-19-generic_*.deb ``` 若本机已通过 `apt` 安装 **同版本的官方 signed** `linux-image-6.17.0-19-generic`,上述一条命令会 **冲突失败**(unsigned 装不上、modules 可能被覆盖)。请先阅读 **第 2.1 节**,并按其中 **「反复 `dpkg -i` 仍报冲突」** 一小节的顺序操作。 也可用仓库脚本(在 **`DEB_DIR` = `kernel-src`** 下选**最新**的 `linux-image-*` 与 `linux-modules-*` deb;`SRC` 必须指向解压源码树): ```bash REPO_ROOT="$HOME/chromebox_10th_audio_driver" export SRC="$REPO_ROOT/kernel-src/linux-hwe-6.17-6.17.0" "$REPO_ROOT/scripts/ubuntu-hwe-617-build.sh" install ``` **若 `sudo update-grub` 报 `command not found`**(精简系统或未装 GRUB 包):先试 **`sudo /usr/sbin/update-grub`**;仍没有则用 **`sudo grub-mkconfig -o /boot/grub/grub.cfg`**。若缺少 `grub-mkconfig`,先 **`sudo apt-get install -y grub-efi-amd64`**(UEFI 常见)或 **`grub-pc`**(传统 BIOS),再执行上一行。 **Proxmox VE:在 LXC(CT)里编译或试装 deb 时** - CT 与**宿主机共用内核**;在容器内安装 **`linux-image-*.deb` 不会让 CT 单独换内核**,也不用于验证「自编内核在实体机上是否启动」。 - **推荐**:在 CT 里只做 **`apt source` / 打补丁 / `binary-generic` 编译**,把 **`kernel-src/*.deb` 拷到 Kaisa 实体机**(或带独立虚拟磁盘的 **完整 KVM 虚拟机**)再按上文 **`dpkg -i`** 与 **`update-grub` / `grub-mkconfig`** 安装。 - CT 内运行 **`grub-mkconfig`** 常失败(例如 **`grub-probe` … `/dev/loop0`**、`update-grub` 不存在),**可忽略**;在**真机**装好 deb 后再更新 GRUB 菜单。 --- ## 2.1 与官方 **signed** `linux-image` 冲突(常见) 若系统已通过 `apt` 安装 **Ubuntu 官方带签名的** `linux-image-6.17.0-19-generic`,再执行 `dpkg -i linux-image-unsigned-6.17.0-19-generic_*.deb` 时会出现: `linux-image-unsigned-... 与之冲突 linux-image-6.17.0-19-generic`(或英文 `conflicts with linux-image-6.17.0-19-generic`) 含义:**同一 ABI(`6.17.0-19-generic`)下,签名镜像包与 unsigned 镜像包只能二选一**,dpkg 会**拒绝安装** unsigned,整次 `dpkg -i` 可能以错误结束。 此时常见结果是: - **`linux-modules-6.17.0-19-generic` 已解压/覆盖成功**(你日志里就是这样); - **`linux-image-unsigned-...` 未装上**,`/boot/vmlinuz-6.17.0-19-generic` 仍是 **官方签名内核**,不含你在源码树里对 **vmlinuz 内置代码** 的改动。 部分驱动/补丁若只落在 **`.ko` 模块**里,仅换 `linux-modules` 可能已带上补丁;但 **`sof_board_helpers.c` 一类若编进主镜像**,则**必须**换成自编的 **unsigned** `vmlinuz` 才会生效。因此若你验证「补丁无效」,先确认是否已真正启动 **unsigned** 镜像。 ### 处理步骤(务必先留一条可启动的备用内核) 1. **重启**,在 GRUB 里先选 **另一条内核** 进入系统(例如你已存在的 `6.17.0-20-generic` 或 `6.17.0-14-generic`),避免卸掉 `6.17.0-19` 后无内核可进。 2. 卸掉 **官方 signed** 的 19 镜像包(包名以 `dpkg -l | grep 6.17.0-19` 为准): ```bash sudo apt remove linux-image-6.17.0-19-generic ``` 若 `apt` 提示会一并移除 `linux-modules-6.17.0-19-generic`,**允许移除**;下一步会重装你自己的 modules deb。 3. 再安装自编的 unsigned 镜像 + 模块(版本号与文件名按你本机 deb 为准): ```bash REPO_ROOT="$HOME/chromebox_10th_audio_driver" DEB_DIR="$REPO_ROOT/kernel-src" cd "$DEB_DIR" sudo dpkg -i \ linux-image-unsigned-6.17.0-19-generic_6.17.0-19.19~24.04.2_amd64.deb \ linux-modules-6.17.0-19-generic_6.17.0-19.19~24.04.2_amd64.deb sudo apt-get install -f ``` 4. `sudo update-grub`,重启后选 **`6.17.0-19-generic`**,用 `uname -r` 与(若需要)`/proc/version` 确认启动的是自编树产物。 ### 反复 `dpkg -i` 仍报「与之冲突 linux-image-6.17.0-19-generic」 只要 **`linux-image-6.17.0-19-generic`(官方 signed)仍在软件包数据库里且未卸掉**,再执行多少次 ```bash sudo dpkg -i linux-image-unsigned-6.17.0-19-generic_*.deb linux-modules-6.17.0-19-generic_*.deb ``` **unsigned 镜像都不会装上**;`linux-modules` 可能每次都被覆盖,但 **`vmlinuz-6.17.0-19-generic` 仍是官方内核**。 **禁止**:在 **`uname -r` 为 `6.17.0-19-generic`**(正在运行 19)且 **未先卸官方 signed 19** 的情况下,指望仅靠 `dpkg -i` 解决冲突。 **正确顺序(逐项做完再装 deb)**: 1. **重启**,GRUB → **Advanced options for Ubuntu** → 选 **`6.17.0-20-generic`** 或 **`6.17.0-14-generic`**(或你机上任意 **非 19** 且已存在的条目)。 `update-grub` 日志里出现 `Found linux image: ...6.17.0-20...` / `...14...` 即表示 **/boot 里已有备用内核**,应能选到。 2. 进入桌面后 **必须确认**: ```bash uname -r ``` 输出 **不得** 为 `6.17.0-19-generic`。 3. 卸官方 signed 的 19: ```bash sudo apt remove linux-image-6.17.0-19-generic ``` 若提示会移除 **`linux-modules-6.17.0-19-generic`**,**允许**;下一步会重装你自己的 modules deb。 4. 再安装自编 deb(路径按实际目录): ```bash REPO_ROOT="$HOME/chromebox_10th_audio_driver" DEB_DIR="$REPO_ROOT/kernel-src" cd "$DEB_DIR" sudo dpkg -i \ linux-image-unsigned-6.17.0-19-generic_6.17.0-19.19~24.04.2_amd64.deb \ linux-modules-6.17.0-19-generic_6.17.0-19.19~24.04.2_amd64.deb sudo apt-get install -f sudo update-grub ``` 此时 **不应再出现** 与 `linux-image-6.17.0-19-generic` 的冲突。 5. 重启,在 GRUB 中选 **`6.17.0-19-generic`**,`uname -r` 应为 `6.17.0-19-generic`。 6. 防止日后 `apt upgrade` 再次装回官方 signed 19,可 hold(见下节「防止 apt upgrade…」)。 若 **Advanced options 里根本没有 20/14**,请先完成下文 **「GRUB 里只有 Ubuntu…」** 小节的 **A / D**,装出第二条官方内核后再从本小节第 1 步重做。 ### GRUB 里只有「Ubuntu」、看不到备用内核时 很常见:菜单被设为隐藏、或顶层只显示一项,**子菜单里才有内核列表**。 **A. 先查清本机是否已有多个内核(未必会在顶层显示)** ```bash ls /boot/vmlinuz-* dpkg -l 'linux-image-*' | grep '^ii' ``` 若这里 **已有** 多个 `vmlinuz-*-generic`,只是 GRUB 没让你选: **B. 重启时调出 GRUB 菜单** - 开机 logo 出现后 **立刻连按 `Shift`**(传统 BIOS 常见)或 **`Esc`**(部分 UEFI);或 **按住 `Shift` 不放** 直到出现菜单。 - 若只出现 **「Ubuntu」** 一条:用方向键选中后,找 **`Advanced options for Ubuntu`**(或中文「Ubuntu 的高级选项」)进入,里面应列出 **多个 `6.17.0-xx-generic`**。 **C. 让菜单每次显示几秒(在能进系统时执行)** 编辑 `/etc/default/grub`,例如: ```text GRUB_TIMEOUT_STYLE=menu GRUB_TIMEOUT=5 ``` 保存后执行: ```bash sudo update-grub ``` (若原为 `GRUB_TIMEOUT_STYLE=hidden`,顶层仍可能只显示「Ubuntu」,但 **Advanced options** 子菜单里仍可切换内核。) **D. 若 `ls /boot/vmlinuz-*` 确实只有一个版本** 在卸掉 `linux-image-6.17.0-19-generic` **之前**,先 **安装官方另一条内核**(示例为同系列更新小版本;以你仓库里实际能装到的包名为准): ```bash sudo apt update sudo apt install linux-image-6.17.0-20-generic linux-modules-6.17.0-20-generic sudo update-grub ``` 装好并 `reboot` 后,在 **Advanced options** 里应能看到 **20 与 19**。**先选非 19 的那条进系统**,再按上文步骤 2–4 换 unsigned 的 19。 **E. 若卸包/换内核后无法启动** 需用 **Ubuntu Live USB** 等介质 **chroot** 修复(重装 `linux-image-*`、执行 `update-grub`)。因此 **务必按 D 先装出第二条可启动内核** 再卸官方 19。 ### 防止 `apt upgrade` 再次装回 signed、把 unsigned 顶掉 在改用 unsigned 并成功启动后,可对自编包加 **hold**(包名以实际为准): ```bash sudo apt-mark hold linux-image-unsigned-6.17.0-19-generic linux-modules-6.17.0-19-generic # 若还安装了同版本 extra / iwlwifi,建议一并 hold,避免 apt 用官方包覆盖混用: # sudo apt-mark hold linux-modules-extra-6.17.0-19-generic linux-modules-iwlwifi-6.17.0-19-generic ``` 需要恢复跟随官方更新时再: ```bash sudo apt-mark unhold linux-image-unsigned-6.17.0-19-generic linux-modules-6.17.0-19-generic # sudo apt-mark unhold linux-modules-extra-6.17.0-19-generic linux-modules-iwlwifi-6.17.0-19-generic ``` --- ## 3. 依赖缺失:`linux-base` 若 `dpkg` 报错类似: `linux-image-unsigned-... depends on linux-base ... however: Package linux-base is not installed` 先安装依赖并完成半配置状态: ```bash sudo apt-get install -y linux-base sudo dpkg --configure -a ``` 然后再按需重跑一次 `dpkg -i`(通常配置完成后已无需重复)。 --- ## 4. 其它依赖与 `apt-get install -f` 若 `dpkg -i` 仍提示未满足依赖,可: ```bash sudo apt-get install -f ``` 按提示补齐缺失包后,再 `sudo dpkg --configure -a`。 --- ## 5. 可选:`linux-modules-extra` 与 `linux-headers` - **`linux-modules-extra-*`**:额外模块集合;若你需要其中某驱动再装,需与 image **同版本**。 - **`linux-headers-*`**:编译树外内核模块、或让 **DKMS** 为新内核自动构建模块时需要。 安装 headers 示例(deb 需与当前内核版本一致,且通常在同一次 `binary-generic` 产物目录 **`$REPO_ROOT/kernel-src`** 中): ```bash REPO_ROOT="$HOME/chromebox_10th_audio_driver" DEB_DIR="$REPO_ROOT/kernel-src" cd "$DEB_DIR" sudo dpkg -i linux-headers-6.17.0-19-generic_6.17.0-19.19~24.04.2_amd64.deb sudo apt-get install -f # 若提示还缺 linux-headers-*-common 等 ``` 未装 headers 时,安装/升级内核后日志里可能出现: `dkms: autoinstall for kernel ... was skipped since the kernel headers ... do not seem to be installed` 这是**提示**:仅表示 DKMS 未给该内核编模块,**不代表** image/modules 安装失败。 ### 5.1 安装后 WiFi 消失(常见:未装 `linux-modules-extra` / `linux-modules-iwlwifi`) **现象**:换用自编 `6.17.0-19-generic` 后,`uname -r` 正确,但 **无线网络不可用**(无 wlan、NetworkManager 里无 WiFi)。 **常见原因**:只装了 `linux-image-*` + `linux-modules-*`,**未装同版本** 的 **`linux-modules-extra-*`**;Intel 平台还常需 **`linux-modules-iwlwifi-*`**(与官方 `apt` 安装「整套 HWE 内核」时自动拉齐不同,**手工 `dpkg -i` 容易漏装**)。 **处理**(deb 须与当前内核 **ABI 一致**,来自同一次 `binary-generic` 输出目录;本仓库一般为 **`$REPO_ROOT/kernel-src`**): ```bash REPO_ROOT="$HOME/chromebox_10th_audio_driver" DEB_DIR="$REPO_ROOT/kernel-src" cd "$DEB_DIR" ls linux-modules-extra-6.17.0-19-generic_*.deb sudo dpkg -i linux-modules-extra-6.17.0-19-generic_*.deb # 若目录里还有 iwlwifi 分包,再执行(无该文件则不要执行下一行,避免通配符未展开报错): ls linux-modules-iwlwifi-6.17.0-19-generic_*.deb 2>/dev/null && sudo dpkg -i linux-modules-iwlwifi-6.17.0-19-generic_*.deb sudo apt-get install -f sudo reboot ``` 装完可在本机核对(无线网卡名因机而异): ```bash sudo dmesg | grep -iE 'iwl|wifi|80211|firmware' | tail -40 lsmod | grep -i iwl || true ``` 若仍无 WiFi:确认 **`linux-firmware`** 包已安装(`sudo apt install --reinstall linux-firmware`),并对比 **启动旧内核(如 6.17.0-20)** 时 WiFi 是否恢复,以判断是 **缺模块 deb** 还是 **别的问题**。 --- ## 6. 重启与验收 ```bash sudo reboot ``` 启动后在 GRUB 中选择 **`6.17.0-19-generic`**(若多内核,可能在 Advanced 子菜单)。进入系统后: ```bash uname -r ``` 应显示 `6.17.0-19-generic`(或你实际安装的 flavor 名称)。 HDMI 音频验证可结合项目内 [CHROMEOS_VS_UBUNTU_HDMI_NOTES.md](CHROMEOS_VS_UBUNTU_HDMI_NOTES.md) 与 [WORK_PROGRESS.md](WORK_PROGRESS.md) 中的排错思路。 --- ## 7. 卸载(可选) 若需移除该内核,先确认当前装的是 **unsigned** 还是 **官方 signed**(`dpkg -l | grep linux-image | grep 6.17.0-19`): - **unsigned**: ```bash sudo apt-mark unhold linux-image-unsigned-6.17.0-19-generic linux-modules-6.17.0-19-generic 2>/dev/null || true sudo apt-get purge linux-image-unsigned-6.17.0-19-generic linux-modules-6.17.0-19-generic ``` - **官方 signed**:包名一般为 `linux-image-6.17.0-19-generic`,用 `purge` 时同理写对包名。 然后: ```bash sudo apt-get autoremove --purge ``` 卸载前请确认 GRUB 中仍有可启动的旧内核,避免误删唯一内核镜像。