我正在开发基于 ARM 的嵌入式系统,该系统使用基于内核 2.6.31 的定制 Debian Linux。在最终系统中,根文件系统以 squashfs 的形式存储在闪存上。现在,文件夹 /dev 由 udev 创建,但由于不需要热插拔功能,并且启动时间至关重要,因此我想删除 udev 并“硬编码”/dev 文件夹(阅读这里,第 5 页)。因为我仍然需要更改设备的参数(使用 ioctl /sysfs),所以在这种情况下这对我来说不起作用。所以我想到在 /dev 上安装一个 tmpfs 并在那里更改参数。这可能吗?怎么做最好?我的方法是:
- 从 RFS 中删除 /dev
- 创建包含基本设备的 tar
- 挂载 tmpfs /dev
- 将 tar 文件解压到 /dev
- 更改参数
这可行吗?你发现有什么问题吗?
我发现,你可以在已经挂载的挂载点上进行挂载,那么在挂载新文件系统时是否可以只获取数据?如果这样的话,那就非常方便了!
谢谢
更新:我刚刚尝试了一下,但卡在了某个地方。我将所有设备打包到 devices.tar 中,将其打包到我的 squashfs 的 /usr 中,并将以下几行添加到 mountkernfs.sh 中,该文件在 INIT 之后立即执行。
#mount /dev on tmpfs
echo -n "Mounting /dev on tmpfs..."
mount -o size=5M,mode=0755 -t tmpfs tmpfs /dev
mknod -m 600 /dev/console c 5 1
mknod -m 600 /dev/null c 1 3
echo "done."
echo -n "Populating /dev..."
tar -xf /usr/devices.tar -C /dev
echo "done."
这在 NFS 版本上运行良好,如果我将 printf 放在代码中,我可以看到它在执行,如果我注释掉提取部分,它会抱怨缺少设备。
启动正常
mmc0: new high speed SDHC card at address 0007 mmcblk0: mmc0:0007 SD04G 3.67 GiB mmcblk0: p1 IP-Config: Unable to set interface netmask (-22). Looking up port of RPC 100003/2 on 192.168.1.234 Looking up port of RPC 100005/1 on 192.168.1.234 VFS: Mounted root (nfs filesystem) on device 0:14. Freeing init memory: 136K INIT: version 2.86 booting Mounting /dev on tmpfs...done. Populating /dev...done. Initializing /var...done. Setting the system clock. System Clock set to: Thu Sep 13 11:26:23 UTC 2012. INIT: Entering runlevel: 2 UBI: attaching mtd8 to ubi0
注释掉 tar 的提取
mmc0: new high speed SDHC card at address 0007 mmcblk0: mmc0:0007 SD04G 3.67 GiB mmcblk0: p1 IP-Config: Unable to set interface netmask (-22). Looking up port of RPC 100003/2 on 192.168.1.234 Looking up port of RPC 100005/1 on 192.168.1.234 VFS: Mounted root (nfs filesystem) on device 0:14. Freeing init memory: 136K INIT: version 2.86 booting Mounting /dev on tmpfs...done. Populating /dev...done. Initializing /var...done. Setting the system clock. Cannot access the Hardware Clock via any known method. Use the --debug option to see the details of our search for an access method. Unable to set System Clock to: Thu Sep 13 12:24:00 UTC 2012 ... (warning). INIT: Entering runlevel: 2 libubi: error!: cannot open "/dev/ubi_ctrl"
到目前为止一切顺利。但如果我将整个故事打包到 squashfs 中并从那里启动,它就会表现得很奇怪。它在启动时告诉我无法打开初始控制台,并且在安装 UBIFS 设备时抛出错误,但最终还是提供了登录。除此之外,我的 echo 不会被执行。如果我登录,/dev 会按预期安装为 TMPFS,并且所有设备都驻留在其中。当我重新执行“mount”命令以安装 UBIFS 分区时,它会毫无问题地执行并且可用。
来自 squashfs
VFS: Mounted root (squashfs filesystem) readonly on device 31:15. Freeing init memory: 136K Warning: unable to open an initial console. mmc0: new high speed SDHC card at address 0007 mmcblk0: mmc0:0007 SD04G 3.67 GiB mmcblk0: p1 UBIFS error (pid 484): ubifs_get_sb: cannot open "ubi1_0", error -19
此外,其余引导脚本的一部分仍在执行,但不是全部。有人知道原因吗?另一个问题是,5MB 对 /dev 来说是否足够/太多?
答案1
正如您所发现的,忘记创建 /proc 文件夹和 /dev/console 设备是手动创建 boot-ramfs 时的两个常见陷阱。
至于 /dev 的大小,我认为半兆字节就足够了。就你的情况而言,由于系统启动后设备数量基本保持不变,因此可以安全地查看 /dev 占用的空间大小,并将文件系统设置为该大小加上百分之五到十分之一作为文件系统开销(文件和文件夹节点)。