.. _gentoo_genkernel: =========================== Gentoo genkernel =========================== 在解决 :ref:`gentoo_mbp_wifi` 安装 ``net-wireless/broadcom-sta`` ( Broadcom 的私有 ``wl`` 驱动),需要完成内核编译。为了方便完成内核编译,按照推荐先安装 ``sys-kernel/genkernel`` ,然后使用这个工具来完成自动的内核编译 ``genkernel`` 是一个由Gentoo创建的用于自动化完成 :ref:`kernel` 和 :ref:`initramfs` 构建的工具: - 配置内核源代码 - 编译压缩的内核 ``bzImage`` 并复制到 ``/boot`` - 创建 :ref:`initramfs` 并复制到 ``/boot`` - 在 ``/boot`` 中创建软链接 - 添加指向initramfs的定制内容,例如加密相关文件,启动splash图像,扩展模块等 - 配置bootloader来启动新创建的kernel和initramfs .. note:: ``genkernel`` 并不是 "自动" 生成自定义内核配置,它只是自动执行内核构建过程并组装initramfs,所以并不会生成自定义配置文件。 如果没有提供内核配置,那么 ``genkernel`` 将使用 "通用内核配置" (generic kernel configuration) 文件,来生成适合日常使用的通用内核(代价就是非常大的模块化内核) ``genkernel`` 的 ``initramfs`` 也是如此: :ref:`initramfs` 主要用途 是 调用挂载包含根文件系统的块设备,以便能够尽快将控制权转交给真实的系统(磁盘上的操作系统) 安装 ======= - 安装 ``genkernel`` : .. literalinclude:: gentoo_genkernel/install_genkernel :caption: 安装 ``genkernel`` 使用 ======== ``genkernel`` 的大多数选线可以在 ``/etc/genkernel.conf`` 配置,或者通过 ``genkernel`` 命令参数传递。通过命令行参数传递的选项优先级高于配置文件 内核源代码 -------------- - 首先在系统中安装内核源代码: .. literalinclude:: gentoo_genkernel/install_kernel_source :caption: Gentoo安装内核源代码 .. note:: 在 :ref:`install_gentoo_on_mbp` 安装的内核是 ``Distribution Kernel`` ,也就是通用的(庞大的) ``sys-kernel/gentoo-kernel`` 。需要注意这个 ``sys-kernel/gentoo-kernel`` 也是源代码,只不过gentoo为原生内核源代码打过补丁,并且每次(重新)安装 ``sys-kernel/gentoo-kernel`` 都会全面重新编译一次内核,这个内核编译是不需要任何人工干预的,编译生成的是最通用的内核。类似于其他发行版,如 :ref:`ubuntu_linux` 安装的发行版内核 - 编辑 ``/etc/genkernel.conf`` 参考注释修改配置参数: .. literalinclude:: gentoo_genkernel/genkernel.conf :caption: 修改 ``/etc/genkernel.conf`` - 执行创建内核: .. literalinclude:: gentoo_genkernel/genkernel_all :caption: 编译内核 采用 :ref:`install_gentoo_on_mbp` 同样的 ``efibootmgr`` 设置启动,不过需要注意内核名称稍微有所调整(因为编译配置时修改了后缀名): .. literalinclude:: gentoo_genkernel/efibootmgr_set_mba13 :language: bash :caption: :ref:`mba13_early_2014` 设置efibootmgr,启动 ``genkernel`` 新编译的内核 报错: failed to compile the "prepare" target --------------------------------------------- 首次使用 ``genkernel all`` 遇到报错: .. literalinclude:: gentoo_genkernel/genkernel_error_prepare :caption: 报错信息 检查 ``/var/log/genkernel.log`` : .. literalinclude:: gentoo_genkernel/genkernel.log :caption: ``genkernel.log`` 错误 参考 `make[1]: *** No rule to make target `_ 原因是系统中安装了两个Kernel source: 之前 :ref:`install_gentoo_on_mbp` 安装了 ``Distribution Kernel`` ,也就是 ``sys-kernel/gentoo-kernel`` ,然后我又安装了 ``sys-kernel/gentoo-sources`` ,所以执行: .. literalinclude:: gentoo_genkernel/eselect_kernel :caption: 执行 ``eselect kernel`` 检查系统中内核源代码 输出显示: .. literalinclude:: gentoo_genkernel/eselect_kernel_output :caption: 执行 ``eselect kernel`` 可以看到当前内核源代码是发行版内核 :emphasize-lines: 3 此时检查 ``ls -lh /usr/src/linux`` 可以看到引用的是 ``-dist`` 内核:: lrwxrwxrwx 1 root root 24 Dec 17 15:22 /usr/src/linux -> linux-6.1.67-gentoo-dist 解决方法是修改 ``eselect kernel`` ,然后删除掉发行版源代码内核 修改成 ``kernel-srouce`` : .. literalinclude:: gentoo_genkernel/eselect_kernel_set :caption: 设置成 ``kernel-source`` 源代码 现在再次检查 ``eselect kernel list`` 输出就可以看到切换到了标准内核: .. literalinclude:: gentoo_genkernel/eselect_kernel_output_1 :caption: 执行 ``eselect kernel`` 可以看到当前内核源代码切换到标准内核 :emphasize-lines: 2 :strike:`此时可以手工删除` 保留 ``/usr/src/linux-6.1.67-gentoo-dist`` (只要安装了 ``sys-kernel/gentoo-kernel`` 这个目录即使手工删除也会在 :ref:`upgrade_gentoo` 时重新编译 ``gentoo-kerenl`` 发行版kernel,再次生成) 升级内核 ============ 我在部署初期Gentoo提供的内核是 6.1.67 ,但是近期升级提供了 6.6.9 ,我将原先 ``/usr/src/linux-6.1.67-gentoo`` 目录下 ``.config`` 复制到新的 ``/usr/src/linux-6.6.9-gentoo`` 目录下(以便减少重新配置项),然后执行 ``genkernel all`` 。 调用 ``make menuconfig`` 没有问题,正常的交互界面,稍作修改后,我保存退出。此时 ``genkernel`` 开始执行下一步时候报错: .. literalinclude:: gentoo_genkernel/miss_config_microcode_amd_err :caption: ``genkernel`` 报错显示缺少 ``CONFIG_MICROCODE_AMD`` 配置项 检查 ``/var/log/genkernel.log`` 有报错详情: .. literalinclude:: gentoo_genkernel/genkernel_microcode.log :caption: ``genkernel.log`` 日志中有关 ``MICROCODE`` 错误 :emphasize-lines: 21,22,34 - 这个问题在以下帖子中讨论: - `solved! genkernel force CONFIG_MICROCODE=AMD as well `_ - `Need help with genkernel (Microcode option for Intel) `_ - `Bug 913659 - genkernel needs adaptation to microcode changes in linux-6.6 (Why genkernel forces CONFIG_MICROCODE AND INTEL AND AMD microcode loading option?) `_ 原因是 ``CONFIG_MICROCODE_AMD`` 和 ``CONFIG_MICROCODE_INTEL`` 已经从内核中移除 解决方法 - 传递 ``--microcode=none`` 参数给 ``genkernel`` : .. literalinclude:: gentoo_genkernel/genkernel_microcode_none :caption: ``genkernel --micorcode=none`` - **或者** 修订 ``/etc/genkernel.conf`` 配置: .. literalinclude:: gentoo_genkernel/genkernel_microcode_none.conf :caption: 配置 ``/etc/genkernel.conf`` 设置 MICROCODE="none" :emphasize-lines: 4 .. _genkernel_initramfs: ``genkernel`` 生成 :ref:`initramfs` ======================================= 使用 ``genkernel`` 还可以用来构建 :ref:`initramfs` : .. literalinclude:: gentoo_genkernel/genkernel_initramfs :caption: 使用 ``genkernel`` 工具构建 :ref:`initramfs` 参考 ====== - `gentoo linux wiki: genkernel `_ - `Installation: Genkernel command not found `_