编译一个用于 VMworkstation 的精简内核

xiaoxiao2021-02-28  121

本文继续先前的 “Linux 内核编译实验 170606”. 由于从 genkernel 生成的内核裁剪时幅度过大, 导致先前的内核不可用, 干脆尝试自简到繁, 从 tinyconfig 构筑一个可用内核.

目标#1: 从 tinyconfig 开始生成一个可引导的内核.

首先生成一个最小内核配置, make tinyconfig, 对 “Genral Setup” 进行简单配置:

未启用 initrd/initramfs, 因为懒得去搞一个 initramfs 了.

编译并尝试引导:

make bzImange install grub-mkconfig -o /boot/grub/grub.cfg reboot

选择内核后无响应, 屏幕漆黑. 由于没有任何输出, 应该是 console 的问题, 检查后启用以下配置项:

Device Drivers ---> Character devices ---> [*] Enable TTY [*] Virtual terminal [*] Enable character translations in console [*] Support for console on virtual terminal [ ] Support for binding and unbinding console drivers [*] Unix98 PTY support [ ] Legacy (BSD) PTY support

重启后出现了内核启动的显示, 最后 kernel 因找不到 rootfs 而 panic. 根据上次实验的 udevadm 输出, 加入 mptspi 驱动, SCSI 驱动, PCI 总线和 block 设备. (SCSI 控制器驱动用 lspci 查找)

重启后, 内核继续因为找不到 root 文件系统而崩溃, 但崩溃前的日志提示:

内核在 grub 参数的提醒下, 继续使用 UUID 寻找 root 分区, 并出现以下错误提示: VFS: Connot open root device "UUID=......" or unknown-block(0,0): error -6 内核已经能够找到硬盘, 并读取正确的分区表.

百度就是个垃圾, 根据 bing.com 的搜索结果, 有个帖子提到了同样的问题.

You have to have an initramfs (initrd) image, that was built by genkernel, loaded in order to get this support. The kernel itself does not, (and won’t according to the kernel devs), support this syntax.

发现应该是这么回事. 内核加载完 initramfs 后, 会执行 /init, 而真正的根文件系统是由这个 init 脚本挂载的. grub2 启动项中的 root=UUID=……, 实际是这个 init 脚本调用 blkid 程序后解析为真正的设备文件名.

blkid -o device -l -t UUID="uuid_of_root_fs"

使用 root=/dev/sda4 就能够正常进入操作系统了. 查看 grub2 的文档, 在 /etc/default/grub 文件中加入:

echo -e "\nGRUB_DISABLE_LINUX_UUID=true" >> /etc/default/grub

运行命令 grub-mkconfig -o /boot/grub/grub.cfg 就不会再使用 UUID 来查找文件系统了. 这样的话有以下问题:

使用设备名来指定根文件系统最大问题是万一磁盘设备名改变了怎么办? udev 在发现磁盘设备上是不是能保证设备名不发生改变? 是不是可以使用卷标来指定文件系统? 根据 blkid 的输出猜测, 使用 root=LABLE=...... 同样是依靠 initramfs 中的 init 来找到指定硬盘.

现在内核已经可以启动到 console 登录界面, 但是 OpenRC 并没有运行, 包括 /etc/init.d/root 在内的众多脚本都没有运行, root 文件系统还是只读状态.

手动切换运行级别, 即 init 1 然后 init 3, 发现报错提示 flock 系统调用未找到, 启用相关的 “FILE_LOCKING” 参数.

* Call to flock failed: Function not implemented

使用以下命令, 使 grub 在内核引导参数中加入告知 root 文件系统类型的参数, 以解决内核尝试以 ext2 和 ext3 挂载根文件系统的问题. (可以在 dmesg 中看到)

EXT4-FS (sda4): couldn't mount as ext3 due to feature incompatibility echo -e "GRUB_CMDLINE_LINUX=\"rootfstype=ext4\""

重启后, OpenRC 能够运行, 但 dmesg 中还存在报错, 启用内核参数 “INOTIFY_USER”.

udevd[992]: inotify_init failed: Function not implemented

系统网卡是, pcnet32:

02:01.0 Ethernet controller: Advanced Micro Devices, Inc. [AMD] 79c970 [PCnet32 LANCE] (rev 10)

在内核配置中启用这个驱动.

Device Drivers ---> Network device support ---> Ethernet driver support ---> [*] AMD devices <M> AMD PCnet32 PCI support

启动后发现 dmesg 还有报错:

modprobe: ERROR: could not insert 'pcnet32': exec format error

忘记复制 modules 了, 其实是不敢复制, 怕影响原来 genkernel 的可用内核. make modules modules_install 编译并安装模块.

启动后看 dmesg 没有明显的错误, 2.4 秒就启动完了.


mount -o remount,rw / rc-service -l rc-update show -v My opinion about mpt-status Despite it seems that no real upstream development exists for this tool, it works fine and is reliable. We experienced several disks failure on MPT SAS controllers and mpt-status always reported the failure and status changes. However don't expected verbose output. Homepage: ​http://www.drugphish.ch/~ratz/mpt-status/
转载请注明原文地址: https://www.6miu.com/read-84129.html

最新回复(0)