以用户身份解压、修改、打包initrd

以用户身份解压、修改、打包initrd

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.txtDocumentation/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

出现这些错误是因为您的用户没有创建节点的权限。只有 root 可以创建除 fifo 和套接字之外的节点(请参阅姆诺德下的文档EPERM

当您再次重新打包 initrd 时,那些特殊文件将不会在其中。要重新打包 initrd,有一个选项称为--owner可用于设置所有文件的所有者。,只有 root 可以使用此选项。

我看到的唯一方法是将 initrd 复制到另一个具有 root 访问权限的系统并在那里执行操作。之后将其复制回来。

答案4

感谢您的回答,它们很有用,但我找到了自己的解决方案。

重新创建 initrd 映像可以使用 fakeroot-ng 来完成(也可能使用 fakeroot)。

该工具的基本思想是包装所有系统调用,因此在 fakeroot 环境中执行的所有程序都认为它们是由 root 运行的。

我在 fakeroot 环境中调用部分脚本 - 解压 initramfs,执行所有更改并再次打包。

所有权限均已正确设置,root 是所有文件的所有者。

fakeroot-ng 位于: http://fakeroot-ng.lingnu.com/index.php/Home_Page

相关内容