initrd
我在以用户身份重建图像时遇到问题。首先,当我尝试“解压”原始initrd
图像时:
cpio -idm < initrd-base
cpio: dev/tty8: Cannot mknod: Operation not permitted
cpio: dev/tty3: Cannot mknod: Operation not permitted
cpio: dev/zero: Cannot mknod: Operation not permitted
cpio: dev/loop0: Cannot mknod: Operation not permitted
cpio: dev/loop4: Cannot mknod: Operation not permitted
cpio: dev/loop7: Cannot mknod: Operation not permitted
cpio: dev/loop5: Cannot mknod: Operation not permitted
cpio: dev/loop2: Cannot mknod: Operation not permitted
cpio: dev/tty9: Cannot mknod: Operation not permitted
cpio: dev/tty4: Cannot mknod: Operation not permitted
cpio: dev/null: Cannot mknod: Operation not permitted
cpio: dev/loop6: Cannot mknod: Operation not permitted
cpio: dev/loop1: Cannot mknod: Operation not permitted
cpio: dev/console: Cannot mknod: Operation not permitted
cpio: dev/loop3: Cannot mknod: Operation not permitted
cpio: dev/tty1: Cannot mknod: Operation not permitted
133336 blocks
我怎样才能摆脱这些警告?
其次 - 我不确定如何处理文件所有权。解压后,似乎一切都属于当前用户。
initrd
重新包装后会怎样?我不想改变标准访问权限。
答案1
由于您使用的是 cpio,因此您实际上是在制作初始化文件系统,不是一个初始化程序。 initrd 将存储为文件系统映像,而不是 cpio 存档。 initrd 和 initramfs 在 Linux 引导过程中具有类似的作用,提供一些在真正的根文件系统之前可用的文件(并且用于挂载真正的根文件系统);它们在底层以相当不同的方式处理,但这与这里无关。 Initrd 比较旧,并且在某种程度上已被弃用,取而代之的是 initramfs。许多构建系统仍然使用该文件名,initrd
即使它们已将内容切换到 initramfs。
根映像通常包含需要特定权限的设备节点和文件。该cpio
命令只能根据文件系统中存在的文件生成存档,并且您需要 root 权限才能创建属于 root 的设备节点或文件。内核源代码包含一个工具usr/gen_init_cpio
和一个包装器脚本scripts/gen_initramfs_list.sh
,专门用于生成 initramfs,而无需在文件系统上创建所有文件,从而无需任何权限即可生成 initramfs。这些程序记录在内核源代码树中,位于Documentation/filesystems/ramfs-rootfs-initramfs.txt
和Documentation/early-userspace/README
。
ramfs-rootfs-initramfs.txt
“填充 initramfs”部分描述了构建 initramfs 的正常方法。您编写一个文本文件,其中包含要创建的路径列表及其类型(目录、常规、设备节点等)、权限和其他属性。对于常规文件,您可以指定包含内容的本地文件的名称。然后运行usr/gen_init_cpio
这个文件。构建内核时,如果将该选项设置为文件名,则会通过调用该文件来CONFIG_INITRAMFS_SOURCE
生成 initramfs 。usr/gen_init_cpio
如果您已有 initramfs 映像并想要修改它,请使用cpio -tv
列出它,并基于该映像重建 ramfs 描述文件。如果可能,从原始内核源获取 initramfs 描述文件,以节省您的工作。仅提取某个目录中常规文件的内容。然后修改常规文件和ramfs描述文件,最后运行usr/gen_init_cpio
生成新的initramfs。
答案2
如果您需要解压 initramfs 并稍后重新打包,您可以使用 -s/-i 选项将 fakeroot 环境存储在文件中。
$ mkdir initrd
$ cd initrd
$ zcat ../initrd.gz | fakeroot -s ../initrd.fakeroot cpio -i
现在你有了 fakeroot 环境的文件,其中包含类似的内容:
…
dev=fe05,ino=20326044,mode=120777,uid=0,gid=0,nlink=1,rdev=0 dev=铁05,伊诺=20326045,mode=20664,uid=0,gid=0,nlink=1,rdev=1281 dev=fe05,ino=20326046,mode=20664,uid=0,gid=0,nlink=1,rdev=259 dev=fe05 ,ino=20326047,mode=100644,uid=0,gid=0,nlink=1,rdev=0
…
查看您的文件:
$ stat dev/console
File: 'dev/console'
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: fe05h/65029d Inode: 20326045 Links: 1
我没有深入挖掘,但似乎你可以通过以下方式创建必要的节点
$ touch <file>
$ stat <file>
$ # put info about file into your fakeroot environment with your own params
要构建 initramfs 你只需运行
$ find | fakeroot -i ../initrd.fakeroot cpio -o -H newc | gzip -c > ../initrd.gz
答案3
答案4
感谢您的回答,它们很有用,但我找到了自己的解决方案。
重新创建 initrd 映像可以使用 fakeroot-ng 来完成(也可能使用 fakeroot)。
该工具的基本思想是包装所有系统调用,因此在 fakeroot 环境中执行的所有程序都认为它们是由 root 运行的。
我在 fakeroot 环境中调用部分脚本 - 解压 initramfs,执行所有更改并再次打包。
所有权限均已正确设置,root 是所有文件的所有者。
fakeroot-ng 位于: http://fakeroot-ng.lingnu.com/index.php/Home_Page