Linux:如何为RAMFS/TMPFS启用就地执行(XIP)

All*_*lan 9 linux linux-kernel embedded-linux

我正在研究一个嵌入式系统,在这个系统中,该过程rootfs是在一个tmpfs分区中构建的init.在之后rootfs完成,它会做一个支点根,并开始设在产卵过程rootfs.

但它似乎XIP不适用于我们tmpfs,因此所有应用程序都被加载到ram两次(在tmpfs加载时再次加入ram).

这真的可以吗?

我在https://ez.analog.com/thread/45262找到了一个旧的讨论主题,它描述了我所看到的相同问题.

如何为位于内存中的文件系统实现XIP?

小智 1

你试图做的事情应该确实是可能的(尽管我自己还没有尝试过)。问题很简单,就是你没有以正确的方式去做。如果您使用块 RAM 设备(“brd”),您可以创建一个块设备,它实际上是作为块设备呈现的 RAM。要在您的内核上启用此功能(抱歉您没有说出您拥有哪个内核,所以我将使用内核 4.14),您需要在内核配置中启用 CONFIG_BLK_DEV_RAM 以及 CONFIG_BLK_DEV_RAM_DAX。它们都位于“设备驱动程序”->“块设备”下。然后,您创建这样一个 RAM 支持的块设备,然后在其上创建例如 ext2 或 ext4 或 XFS 文件系统,然后将 rootfs 准备到该文件系统中,然后将 root 转入其中。现在,您正在 RAM 支持的文件系统中执行,该系统具有 XIP(现已被 DAX 取代)功能,因此执行应用程序现在至少在理论上应该可以正常工作,而无需创建数据副本并简单地从块的 RAM 页中运行它内存设备。

请注意,这种方法有局限性,例如内核模块本身仍将被复制到 RAM 中,get_user_pages() 可能不起作用,O_DIRECT 可能不起作用,RDMA、sendfile() 和 splice() 也不起作用。

一些需要关注的相关事项包括:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/block/Kconfig?h=v3.19#n359

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/block/Kconfig?h=v3.19#n396

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/blockdev/ramdisk.txt?h=v3.19

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/xip.txt?h=v3.19

注意,自 4.0 内核以来,XIP 被 DAX 取代,因此可以看到:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/dax.txt?h=4.14

另请注意,内核 4.15 的块 RAM 驱动程序中删除了对 DAX 的支持,因此一旦迁移到内核 4.15 及更高版本,您将无法再执行此操作...请参阅提交 7a862fbbdec665190c5ef298c0c6ec9f3915cf45 了解删除该功能背后的原因

我希望这足以让您走上正轨,并且对自 4.15 内核以来该功能已被删除的坏消息表示抱歉...