本文继续先前的 “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/