消除 initrd 中 X11 库的包含

消除 initrd 中 X11 库的包含

我在 TS412 (QNAP) 上运行 Debian Bookworm;它将内核和 initrd 存储在闪存中。它总共有 16MB 闪存。因此,即使在调整 MD 分区之后,我能得到的最好的也是 12MB initrd 。我正在使用 xz 压缩。但即便如此,最初的 initrd 也有 12.5MB。我知道常见的解决方法是减少模块,但它们不是真正的问题。

2984    .../usr/lib/modules
6036    .../usr/share
18824   .../usr/lib/arm-linux-gnueabi

在arm-linux-gnueabi中查看它有像libX11这样的东西...这台机器甚至没有控制台(即使获得串行线也很困难)它当然不需要“X”。

因此,我完全删除了很多软件包(apt-get remove ...),实际上比我应该删除的要多。但结果是一个小得多的 initrd(大约 5MB IIRC),它启动和运行得很好。

问题是,如果我 ssh 到盒子上并运行 emacs(1) ,那么将 GUI 版本投影回我的普通桌面(有大量内存和大显示器等)会很好,但这需要安装TS412 上的 X 客户端库。

现在我不明白为什么仅仅因为我安装了带有 X 客户端库的软件包,就需要在 initrd 上保留一个副本,而在启动过程中不需要它们。有没有办法限制其他东西进入 initrd,而不仅仅是模块(这不是罪魁祸首)

我已经尝试过在文档中搜索限制 initrd 的指南。

答案1

可能有一个旨在在启动期间显示图形信息的二进制文件,该二进制文件将拉取它所依赖的库初始化文件系统文件。

大多数架构上都有这样的二进制文件,包括armellabel.soplymouth-label作为插件普利茅斯为了在启动期间有带有文本的图形显示。该插件依赖于各种X11库,用于渲染文本。当这个插件添加到初始化文件系统它还添加了它所依赖的所有库,以便可以在引导阶段使用它。这是由包的依赖项通告的:plymouth-label取决于libcairo2它本身依赖于各种 X11 库包,包括libx11-6 提供图书馆libX11.so.6

添加的 initramfs 钩子label.so/usr/share/initramfs-tools/hooks/plymouth:

PLUGIN_PATH="$(plymouth --get-splash-plugin-path)"

case "${THEME_NAME}" in
  text|details|tribar)
      PLUGINS="text.so details.so"
      ;;
  *)
      PLUGINS="text.so details.so label.so"
      ;;
esac

[...]

for PLUGIN in ${PLUGINS}
do
  if [ -f ${PLUGIN_PATH}/${PLUGIN} ]
  then
      copy_exec ${PLUGIN_PATH}/${PLUGIN}
  else
[...]

copy_exec是一个 shell 函数(由 提供initramfs-tools-core),除了复制二进制文件之外,它还会在需要时提取依赖项,依赖于ldd发现需要的内容。

因此,只有在普利茅斯使用非文本设置时才会拉动它......以便显示文本。

由于 QNAP 的主要目的不是视频,因此普利茅斯安装,尤其是应避免使用此插件,避免将 X11 库拉入初始化文件系统文件。

我看不出造成这种行为的任何其他原因。可能有其他类似的包出于类似的原因导致此行为。

答案2

遵循@AB有用回复的逻辑。我敲出了一对快速而肮脏的脚本来帮助跟踪依赖树。 (AB答案仍然是具体问题的答案)

graeme@qnap412u:/tmp/myinitrd$ xzcat /boot/initrd.img-6.1.0-13-marvell  | cpio -i
34382 blocks

graeme@qnap412u:/tmp/myinitrd$ ~/bin/genxrefs.sh /tmp/myinitrd/  > /tmp/refs
Doing /tmp/myinitrd/usr/lib/klibc-tUxlTFMpGlp_BpS5UnpMpyc8b3g.so
    not a dynamic executable
Doing /tmp/myinitrd/usr/lib/arm-linux-gnueabi/ld-linux.so.3
Doing /tmp/myinitrd/usr/lib/arm-linux-gnueabi/libkmod.so.2.4.0
..elided..

graeme@qnap412u:/tmp/myinitrd$ ~/bin/whoneeds.awk  libudev /tmp/refs 
libudev.so.1 is used by /tmp/myinitrd/usr/lib/arm-linux-gnueabi/libdevmapper.so.1.02.1

graeme@qnap412u:/tmp/myinitrd$ ~/bin/whoneeds.awk devmapper  /tmp/refs 
graeme@qnap412u:/tmp/myinitrd$ ~/bin/whoneeds.awk libatomic  /tmp/refs 
libatomic.so.1 is used by /tmp/myinitrd/usr/lib/arm-linux-gnueabi/libkmod.so.2.4.0
libatomic.so.1 is used by /tmp/myinitrd/usr/lib/arm-linux-gnueabi/libcrypto.so.3


graeme@qnap412u:/tmp/myinitrd$ cat ~/bin/genxrefs.sh
#! /bin/bash -ue

# This will fail if any names uses spaces or commas (at a pinch, we could use TAB)

INITDIR=$1

objs=$(find ${INITDIR} -type f -name '*.so.*' -o -path '*.so')

# This is going to mess up if anybody uses spaces in pathnames
for obj in ${objs}
do
    echo "Doing ${obj}" >&2
    ldd ${obj} | while read line
    do
    requires=${line%% =>*}
    requires=${requires%% *} # 1st word
    requires=$(basename ${requires})
    
    provided=${line#*=>}

    # Ugly , we use commas because, for example quoted strings are too hard in awk(1)
    
    echo "${obj},${requires},${provided}"
    done  
done
graeme@qnap412u:/tmp/myinitrd$ cat ~/bin/whoneeds.awk
#! /usr/bin/awk -f
BEGIN {
    # NB this version of awk does not appear to understand FPAT
    FS=","

    STRING=ARGV[1]
    ARGV[1]=""
}

{ if ( index($2, STRING) > 0 )
    print $2 " is used by " $1 }

相关内容