Linux 软件包包含 Linux 内核。
编译内核包括以下步骤——配置、编译和安装。阅读内核源码树中的 README
可以获得替代本手册配置的方法。
运行以下命令准备编译:
make mrproper
这将保证内核树的绝对干净。内核小组建议在每次编译之前都执行此命令,无用的代码将会在解压后删除。
通过菜单界面配置内核。配置内核的一般信息请查看:http://www.linuxfromscratch.org/hints/downloads/files/kernel-configuration.txt。 BLFS 包含有一些内核的特殊配置,可以查看:http://www.linuxfromscratch.org/blfs/view/9.0/longindex.html#kernel-config-index。 内核配置和编译的附加信息可查看:http://www.kroah.com/lkn/。
配置内核的一个好的起点是运行 make defconfig。这样会参考你的机器架构生成一份基本能用的基础配置。
注意要确保启用/禁用/设置下面这些特性,否则系统也许不能正常工作甚至根本无法启动:
General setup --> [ ] Enable deprecated sysfs features to support old userspace tools [CONFIG_SYSFS_DEPRECATED] [ ] Enable deprecated sysfs features by default [CONFIG_SYSFS_DEPRECATED_V2] [*] open by fhandle syscalls [CONFIG_FHANDLE] [ ] Auditing support [CONFIG_AUDIT] [*] Control Group support [CONFIG_CGROUPS] Processor type and features ---> [*] Enable seccomp to safely compute untrusted bytecode [CONFIG_SECCOMP] Networking support ---> Networking options ---> <*> The IPv6 protocol [CONFIG_IPV6] Device Drivers ---> Generic Driver Options ---> [ ] Support for uevent helper [CONFIG_UEVENT_HELPER] [*] Maintain a devtmpfs filesystem to mount at /dev [CONFIG_DEVTMPFS] [ ] Fallback user-helper invocation for firmware loading [CONFIG_FW_LOADER_USER_HELPER] Firmware Drivers ---> [*] Export DMI identification via sysfs to userspace [CONFIG_DMIID] File systems ---> [*] Inotify support for userspace [CONFIG_INOTIFY_USER] <*> Kernel automounter version 4 support (also supports v3) [CONFIG_AUTOFS4_FS] Pseudo filesystems ---> [*] Tmpfs POSIX Access Control Lists [CONFIG_TMPFS_POSIX_ACL] [*] Tmpfs extended attributes [CONFIG_TMPFS_XATTR] Kernel hacking ---> Choose kernel unwinder (Frame pointer unwinder) ---> [CONFIG_UNWINDER_FRAME_POINTER]
尽管「The IPv6 Protocol」不是必须打开,但是 systemd 开发人员强烈推荐打开。
如果你主机的硬件用的是 UEFI,那么上面的‘make defconfig’应该会自动添加一些 EFI 相关的内核选项。
为了让你的 LFS 内核,在你的主机是 UEFI 引导环境的情况下,能够被引导,你的内核必须要有这项:
Processor type and features ---> [*] EFI stub support [CONFIG_EFI_STUB]
文件 lfs-uefi.txt 中包含了管理 UEFI 环境的完整描述,参见 http://www.linuxfromscratch.org/hints/downloads/files/lfs-uefi.txt。
上述配置项的一些原理说明:
Support for
uevent helper
打开这个选项会影响 udev/Eudev 设备管理。
Maintain a
devtmpfs
这个选项允许内核在 udev 运行之前就创建自动设备节点。之后 udev 在这个基础上运行,管理权限以及增加符号链接。对于所有 udev/Eudev 用户,这个配置项是必须的。
make menuconfig
可选 make 环境变量的含义:
LANG=<host_LANG_value>
LC_ALL=
建立与宿主系统相同的地域设定。在 UTF-8 linux 文本命令行上逐行绘制适宜的 menuconfig ncurses 接口时可能需要这项配置。
要使用的话,请我务必使用宿主系统中的变量 $LANG
去代替
<host_LANG_value>
。你也可以用宿主系统中的
$LC_ALL
或 $LC_CTYPE
来代替。
另外,make oldconfig
在某些情况下可能更合适。查看 README
文件了解更多信息。
想偷懒的话,可以拷贝宿主系统的内核配置文件 .config
(如果有的话)到解压后的 linux-5.2.8
目录下来跳过内核配置。不过,我们不建议这样做。最好是探索一下整个内核配置菜单,从最开始配置内核。
编译内核映像和模块:
make
如果使用内核模块,需要 /etc/modprobe.d
文件里的模块配置。关于模块和内核配置的信息可以查看 第 7.3 节
「设备与模块管理概述」 以及 linux-5.2.8/Documentation
目录下的内核文档。还有,modprobe.d(5)
也可以看一下。
如果内核配置里用到,需要安装模块:
make modules_install
在内核编译完成后,还需要一个额外步骤来完成安装。有些文件需要拷贝到 /boot
目录下。
如果宿主系统拥有单独的 /boot 分区,那么文件就应该复制到那里。简单的解决方法就是在执行前将 /boot 绑定到宿主的 /mnt/lfs/boot。以宿主系统中的 root 用户运行:
mount --bind /boot /mnt/lfs/boot
内核映像文件所在的实际目录根据主机系统架构可能会不一样。下面的文件名你也可以改成你喜欢的,不过开头最好是 vmlinuz 才可以兼容下一节要讲的配置引导过程的自动设定。下面的命令假设主机是 x86 架构:
cp -iv arch/x86/boot/bzImage /boot/vmlinuz-5.2.8-lfs-9.0-systemd
System.map
是内核的符号文件。它映射了每一个内核 API
函数的入口,以及内核运行时的数据结构地址。是调查内核问题时的资源。运行下面的命令安装映射文件:
cp -iv System.map /boot/System.map-5.2.8
在之前命令 make menuconfig
里生成的内核配置文件 .config
包含了当前编译的内核的所有配置。最好能保存下来留作参考:
cp -iv .config /boot/config-5.2.8
安装 Linux 内核文档:
install -d /usr/share/doc/linux-5.2.8 cp -r Documentation/* /usr/share/doc/linux-5.2.8
需要注意一下内核源代码目录下的文件属主并不是 root。在以 root 用户解压包的时候(我们在 chroot 环境里做的),解压出来的文件会拥有生成这个包的电脑里用户和组。在安装其他包的时候这并不是问题,因为它们的源代码在安装完后就删除了。不过,Linux 内核的源代码经常会保留比较长时间。这样的话,就有可能会把软件包作者的用户 ID 对应到本机的某个用户上。从而这个用户就会拥有内核源代码的写权限。
在很多情况下,内核的配置信息需要在稍后安装来自于 BLFS 的软件包后更新。这和其他的软件包不同,在安装完成编译好的内核后不需要将内核源码树删除。
如果想要保留内核的源码树,在 linux-5.2.8
下运行
chown -R 0:0
来确保所有文件的所有者都 root。
一些内核文档里建议创建符号链接 /usr/src/linux
指向内核源代码目录。这是 2.6 及以前版本内核的特定要求,而在 LFS 系统里一定不要创建这个链接,因为这样的话,在你的基础 LFS
系统完成后安装某些软件包时可能引起问题。
系统 include
目录(/usr/include
)下的头文件应该总是和编译 Glibc 时用到的头文件保持一致。就是在 第 6.7 节 「Linux-5.2.8 API 头文件」
里整理过的头文件。因此,它们不要替换成原始内核头文件或任何清理过的内核头文件。
虽然大多数情况下,Linux 模块会被自动加载,但是有时候需要特别指定加载顺序。modprobe 或 insmod 在加载模块时会读取 /etc/modprobe.d/usb.conf
。如果将 USB
设备(ehci_hcd、ohci_hcd 和 uhci_hcd)
编译为模块,则需要此文件,这样它们就会以正确的顺序加载。ehci_hcd 需要在 ohci_hcd 和 uhci_hcd
之前加载,否则在系统启动过程中将会输出警告。
运行以下命令建立 /etc/modprobe.d/usb.conf
文件:
install -v -m755 -d /etc/modprobe.d
cat > /etc/modprobe.d/usb.conf << "EOF"
# Begin /etc/modprobe.d/usb.conf
install ohci_hcd /sbin/modprobe ehci_hcd ; /sbin/modprobe -i ohci_hcd ; true
install uhci_hcd /sbin/modprobe ehci_hcd ; /sbin/modprobe -i uhci_hcd ; true
# End /etc/modprobe.d/usb.conf
EOF