继成功利用initrd.img机制完善简单文件系统并实现shell直接启动后,本次实验的目标是扩展文件系统功能,以实现更高级的操作和系统集成。具体任务如下:

  1. 手工加载驱动程序(V0.55) :深入了解和实践Linux系统中的驱动管理机制,手工加载必要的硬件驱动,以保证系统与硬件的正确交互。
  2. 实现硬盘上标准Linux系统挂载:扩展文件系统以访问和使用硬盘上现有的标准Linux系统文件,增强系统的兼容性和实用性。
  3. 动态设备节点管理(udevd,V0.6) :通过引入udev实现设备节点的自动识别和加载,优化系统的配置过程。

实验过程

首先使用root权限,进入系统文件

su
cd myfilesystem

先把一些必要的指令移动过去

cp /bin/ls /bin/mkdir /bin/cat /bin/mount /bin/udevadm  /bin/login  /bin/mknod bin/
mkdir sbin
cp /sbin/modprobe /sbin/reboot sbin

然后把这些指令需要的链接库移动过去

cp /lib/x86_64-linux-gnu/libselinux.so.1 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libpcre2-8.so.0 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libmount.so.1 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libblkid.so.1 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libkmod.so.2 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libacl.so.1 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libcap.so.2 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libzstd.so.1 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/liblzma.so.5 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libcrypto.so.3 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libpam.so.0 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libpam_misc.so.0 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libaudit.so.1 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libcap-ng.so.0 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/liblz4.so.1 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libgcrypt.so.20 lib/x86_64-linux-gnu
cp /lib/x86_64-linux-gnu/libgpg-error.so.0 lib/x86_64-linux-gnu

接下来我们要复制一些必要的驱动过来,先把/lib/modules/6.5.0-26-generic/modules.* 全部移动过来,这些是一些必要的文件,包括各种模块的依赖关系和信息。

mkdir lib/modules/
mkdir lib/modules/6.5.0-26-generic/
cp /lib/modules/6.5.0-26-generic/modules.* lib/modules/6.5.0-26-generic/

接下来,为了能够正确加载硬盘,我们需要mptspi驱动程序,它用于支持基于 LSI Logic Fusion-MPT 架构的 SCSI 并行接口控制器。它的位置在/lib/modules/6.5.0-26-generic/kernel/drivers/message下面,我们把它和一些必要文件拷贝过来

mkdir lib/modules/6.5.0-26-generic/kernel
mkdir lib/modules/6.5.0-26-generic/kernel/drivers
cp /lib/modules/6.5.0-26-generic/kernel/drivers/message/ lib/modules/6.5.0-26-generic/kernel/drivers/ -r
cp /lib/modules/6.5.0-26-generic/kernel/drivers/scsi/ lib/modules/6.5.0-26-generic/kernel/drivers/ -r
cp /lib/modules/6.5.0-26-generic/kernel/drivers/ata/ lib/modules/6.5.0-26-generic/kernel/drivers/ -r
cp /lib/modules/6.5.0-26-generic/kernel/drivers/block/ lib/modules/6.5.0-26-generic/kernel/drivers/ -r

接下来我们要在init中加载驱动,同时为了能够看到各种设备,硬盘信息,我们还需要把一些系统文件进行挂载。同时,由于我们没有udev,我们需要手动创建块设备文件,通过mknod可以进行创建,最后,我们将创建的设备文件挂载到我们的文件上。

mkdir mnt
mkdir mnt/hd
vim init
#!/bin/sh
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev
modprobe mptspi
mknod /dev/sda3 b 8 3
mount /dev/sda3 /mnt/hd
exec /bin/bash

接下来,我们打包文件并更新grub

find . | cpio -o -H newc | gzip > /boot/my-initrd.img
update-grub

现在,我们重启进入我们的小系统就可以从/mnt/hd看见我们的硬盘了。

接下来,我们要把udev移植到我们的小系统里面,我们先把udev和它的相关规则迁移过来。

mkdir lib/systemd
cp /lib/systemd/systemd-udevd  lib/systemd/
cp /bin/udevadm  bin/
mkdir lib/udev/
cp /lib/udev/rules.d lib/udev/rules.d -r

现在我们修改init,让系统启动udev,同时我们不再需要手动挂载节点

#!/bin/sh 
mount -t proc none /proc
mount -t sysfs none /sys
mount -t devtmpfs none /dev
modprobe mptspi
/lib/systemd/systemd-udevd 
udevadm trigger --action=add
udevadm settle || true
mount /dev/sda3 /mnt/hd
exec /bin/bash

最后,我们打包并更新,完成了udev的安装使用。