Is there a way to add kexec functionality to busybox initrd?

1k views Asked by At

I have 3 MB of SPI flash on my board and I am able to pack the bzImage, busybox initrd and coreboot ROM into this SPI flash. I am also able to boot to the shell , all using the ROM kernel-as-bootloader.

I have bigger kernel on the USB device. I am also able to detect the USB and mount it. But the problem is busybox does not seem to have kexec utility. I cannot use any other initrd package because my cpio (uncompressed) size should not go beyond 1.4 MB due to memory constraints. U-root has kexec support but the minimal image size easily reaches 3MB or at least, I couldn't find a way to built it lesser than that size.

Hence, is there a way to add kexec support to busybox (compile static binary and copy to initrd? ) or any other initrd package that can suffice the need within 1.4MB size?

EDIT

This post suggests that there may be kexec support available in busybox, but I couldn't find any trace of it. In fact the request to add kexec-tools to busybox was done over a decade ago. But when I did grep in the busybox, I saw no traces of it.

2

There are 2 answers

5
Arnout On

The kexec binary from kexec-tools takes about 300KB (x86_64 with -Os). Even if it would be added to busybox, it wouldn't get much smaller than that because it does need to do fairly complicated things that are not done anywhere else in busybox.

If you don't have even 300KB left, then you should probably remove configuration options from busybox itself to save space. With uClibc, you can also remove some options you don't need, like wchar and threading. Make sure you use static linking, it saves a little bit of space.

The following Buildroot defconfig generates an initramfs of exactly 1.4MB.

BR2_x86_64=y
BR2_x86_corei7=y
BR2_STATIC_LIBS=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TOOLCHAIN_EXTERNAL_DOWNLOAD=y
BR2_TOOLCHAIN_EXTERNAL_URL="https://toolchains.bootlin.com/downloads/releases/toolchains/x86-64-core-i7/tarballs/x86-64-core-i7--uclibc--stable-2018.11-1.tar.bz2"
BR2_TOOLCHAIN_EXTERNAL_GCC_7=y
BR2_TOOLCHAIN_EXTERNAL_HEADERS_4_1=y
BR2_TOOLCHAIN_EXTERNAL_LOCALE=y
BR2_PACKAGE_KEXEC=y
BR2_PACKAGE_KEXEC_ZLIB=y
BR2_TARGET_ROOTFS_CPIO=y
# BR2_TARGET_ROOTFS_TAR is not set
0
netzego On

We could build a version of kexec for busybox which results in a 220K static linked binary like so:

  1. Use musl
  2. Strip the binary with strip (Maybe it could reduce the size even more?)
  3. Disable unused features via ./configure --without-<FEATURE>
KEXEC_VERSION=2.0.24
KEXEC=kexec-tools-$KEXEC_VERSION

curl -LO https://mirrors.edge.kernel.org/pub/linux/utils/kernel/kexec/$KEXEC.tar.xz
tar xf $KEXEC.tar.xz
cd $KEXEC

CC=musl-gcc LDFLAGS=-static ./configure \
  --without-lzma \
  --without-xen \
  --sbindir=/bin
make
strip build/sbin/kexec

file buils/sbin/kexec  # -> [...] statically linked, stripped
du -h build/sbin/kexec # -> 220K [...]

Still not great, but yeah.. Let us know if you could shrink it even more :-)