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

本文记录了从tinyconfig开始构建一个可引导的Linux内核的过程。通过逐步配置和调试,解决了console显示、root文件系统挂载、驱动加载等问题,并最终实现了系统的正常启动。

本文继续先前的 “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 文件系统而崩溃, 但崩溃前的日志提示:

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

百度就是个垃圾, 根据 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/ 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值