如何将额外文件编译到 Android ROM 的根目录中

如何将额外文件编译到 Android ROM 的根目录中

我正在基于 Cyanogenmod ROM 的内核源代码构建自定义 Android 内核。我想将文件夹和文件添加到操作系统的根文件夹中 ( /)。例如,编译内核后,我希望创建一个名为toto(absolute path = ) 的额外文件夹。/toto

我真的不知道必须编辑哪些文件以及如何完成这项工作。


注意:如果您是 Android 用户(不是 ROM 开发人员),想要将文件添加到您的rootfs,请参阅相关的 Android.SE 问题反而。

答案1

在 Android 上,就像在许多基于 Linux 的系统上一样,内核首先安装一个初始化文件系统/。 initramfs 存储在 RAM 中;它是从 CPIO 存档加载的,该存档与内核本身存储在一起(或者引导加载程序可以找到它的其他地方)。

大多数桌面 Linux 系统都有一个小型 initramfs,其中包含足够的程序和配置文件来挂载真正的根文件系统,然后将其挂载到 上/,替换 initramfs。 Android 与某些嵌入式 Linux 系统一样,永远保持 initramfs 的安装状态。 Android 的 initramfs 仅包含/init,adbd和一些配置文件。

对于 Cyanogenmod,您可以在中找到构建说明移植指南。您想要将更多文件复制到 ramdisk(Android 术语中的 initramfs 映像),因此您需要将它们添加PRODUCT_COPY_FILESdevice_*.mk为您的设备创建 makefile。

答案2

内核文档解释了如何将图像打包到内核本身中。从内核.org:

什么是 rootfs?

Rootfs是一个特殊实例ramfs(或者tmpfs,如果启用的话),即 始终存在于 2.6 系统中。无法卸载rootfs出于大致相同的原因,您无法终止 init 进程;内核不必使用特殊的代码来检查和处理空列表,而是更小、更简单地确保某些列表不会变空。

大多数系统只是挂载另一个文件系统rootfs并忽略它。 ramfs 的空实例占用的空间量是微小的。

如果配置_TMPFS已启用,rootfs将使用tmpfs代替ramfs默认情况下。强迫ramfs,添加"rootfstype=ramfs"到内核​​命令行。

什么是 initramfs?

所有 2.6 Linux 内核包含一个 gzip 压缩的"cpio"格式存档,即rootfs内核启动时解压进去。 解压后,内核检查是否rootfs包含一个文件"init",如果是这样,它将执行为PID 1。 如果找到的话,这个init该进程负责使系统继续运行,包括定位和安装真正的根设备(如果有的话)。 如果rootfs不包含init嵌入后的程序cpio归档文件被提取到其中,内核将通过旧代码来定位并挂载根分区,然后执行某些变体/sbin/init出于那个。

所有这些在几个方面与旧的 initrd 不同:

  • 旧的 initrd 始终是一个单独的文件,而 initramfs 存档链接到 Linux 内核映像中。 (目录 linux-*/usr 专门用于在构建过程中生成此存档。)

  • 旧的 initrd 文件是一个 gzip 压缩的文件系统映像(采用某些文件格式,例如 ext2,需要内核内置的驱动程序),而新的 initramfs 存档是一个 gzip 压缩的 cpio 存档(与 tar 类似,只是更简单,请参阅 cpio(1))和文档/early-userspace/buffer-format.txt)。内核的cpio提取代码不仅非常小,而且是在引导过程中可以丢弃的__init文本和数据。

  • 旧的 initrd(称为 /initrd,而不是 /init)运行的程序进行了一些设置,然后返回到内核,而 initramfs 中的 init 程序预计不会返回到内核。 (如果 /init 需要移交控制权,它可以使用新的根设备覆盖 / 并执行另一个 init 程序。请参阅下面的 switch_root 实用程序。)

  • 当切换另一个根设备时,initrd 会pivot_root,然后卸载ramdisk。但initramfs 是rootfs:您既不能pivot_root rootfs,也不能卸载它。 相反,删除 rootfs 中的所有内容以释放空间(find -xdev / -exec rm '{}' ';'),使用新根覆盖 rootfs(cd /newmount; mount --move . /; chroot .),将 stdin/stdout/stderr 连接到新的 /dev/console,并执行新的 init。

由于这是一个非常挑剔的过程(并且涉及在运行命令之前删除命令),因此 klibc 包引入了一个帮助程序(utils/run_init.c)来为您完成所有这些工作。大多数其他软件包(例如 busybox)已将此命令命名为“switch_root”。

填充 initramfs:

2.6内核构建过程始终创建一个 gzipped cpio 格式的 initramfs 存档并将其链接到生成的内核二进制文件中。 默认情况下,该存档为空(在 x86 上占用 134 字节)。

配置选项配置_INITRAMFS_SOURCE(在常规设置inmenuconfig,和 live in usr/Kconfig) 可用于指定 initramfs存档的来源,这将自动合并到生成的二进制文件中。 该选项可以指向 *现存的gzipped cpio* 存档,a目录包含要存档的文件,或文本文件规范如下例:

 dir /dev 755 0 0
 nod /dev/console 644 0 0 c 5 1
 nod /dev/loop0 644 0 0 b 7 0
 dir /bin 755 1000 1000
 slink /bin/sh busybox 777 0 0
 file /bin/busybox initramfs/busybox 755 0 0
 dir /proc 755 0 0
 dir /sys 755 0 0
 dir /mnt 755 0 0
 file /init initramfs/init.sh 755 0 0

跑步usr/gen_init_cpio”(内核构建之后)获取记录上述文件格式的使用消息。

配置文件的优点之一是root无需访问即可在新存档中设置权限或创建设备节点。

(笔记这两个示例“文件”条目期望在-2.6.* 目录下名为“”的目录中找到名为“ init.sh”和“ ”的文件。看busyboxinitramfslinux文档/早期用户空间/自述文件更多细节。)

内核做了不是依赖外部cpio工具。如果您指定一个目录而不是配置文件,内核的构建基础结构将从该目录创建一个配置文件usr/Makefile呼叫scripts/gen_initramfs_list.sh),并继续使用配置文件打包该目录(通过将其输入到usr/gen_init_cpio,它是从 中创建的usr/gen_init_cpio.c)。 内核的构建时cpio创建代码是完全独立的,并且内核的引导时提取器也是(显然)独立的。

相关内容