.. Setting up kexec ================ Prerequisites ------------- To be able to use kexec and initramfs images, we have to make sure the following options have been enabled in the kernel config: .. code:: :lang: text CONFIG_BLK_DEV_INITRD=y CONFIG_RD_GZIP=y CONFIG_RD_BZIP2=y CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_RD_LZ4=y CONFIG_KEXEC=y Building an initramfs --------------------- Let's first create the general structure of our initramfs: .. code:: :lang: text mkdir -p /usr/src/initramfs/{bin,dev,etc,lib,lib64,mnt,proc,root,sbin,sys} Rather than compiling a lot of the common utilities that can be found in e.g. coreutils, we compile a static version of busybox to install within in our initramfs: .. code:: :lang: text USE="static" emerge busybox cp /usr/bin/busybox /usr/src/initramfs/bin/busybox In addition to busybox, we will also need kexec-tools to boot our kernel: .. code:: :lang: text USE="static" emerge kexec-tools cp /usr/sbin/kexec /usr/src/initramfs/sbin/kexec If we run ldd on /usr/sbin/kexec, we can also figure out the dependencies that it will need to run: .. code:: :lang: text ldd /usr/sbin/kexec cp -r /lib/{libc.so.6,libz.so.1,ld-linux-armhf.so.3} /usr/src/initramfs/lib In /usr/src/initramfs/init, we set up the following init script: .. code:: :lang: text #!/bin/busybox sh mount -t proc none /proc mount -t sysfs none /sys mount -t devtmpfs none busybox sh umount /dev exec switch root /mnt/root /sbin/init The above script will drop us in a busybox shell session before resuming to switch to the mounted rootfs at /mnt/root. Also, do make sure that is executable: .. code:: :lang: text chmod +x /usr/src/initramfs/init Once everything has set up, we can pack it all into a initramfs as follows: .. code:: :lang: text cd /usr/src/initramfs find . -print0 | cpio --null -ov --format=newc | gzip -9 > ~/initramfs.cpio.gz Booting a kernel ---------------- .. code:: :lang: text cd /usr/src/linux kexec --dtb=arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dtb --ramdisk=initramfs.cpio.gz --command-line="console=tty1 rootfs=/dev/mmcblk2p2 rootfstype=ext4 rootwait rw" arch/arm/boot/zImage Using kexec-tools to boot a uImage also works. Booting u-boot -------------- First, we have to clone the u-boot repository and build u-boot: .. code:: :lang: text git clone git://git.denx.de/u-boot.git --depth=1 -b v2017.01 cd u-boot make A20-OLinuXino-Lime2_defconfig make Once we have built u-boot, we have to pack it up as a uImage, so that kexec can boot it. However, before we can pack it up, we have to figure out the load address and the entry address for the board that we are trying to target. For instance, for the Allwinner boards, we can find the load address as follows: .. code:: :lang: text grep CONFIG_SYS_LOAD_ADDR include/configs/sunxi-common.h grep CONFIG_SYS_TEXT_BASE include/configs/sunxi-common.h In this case, we'll find that the load address and text base are either configured to be ``0x22000000`` and ``0x2a000000`` or ``0x42000000`` and ``0x4a000000`` respectively. Closer inspection shows that the Allwinner A20 (sun7i) uses the latter two. After we have found the load address and text base, we can pack up u-boot: .. code:: :lang: text mkimage -A arm -O linux -T kernel -C none -a 0x42000000 -e 0x4a000000 -d u-boot-dtb.bin u-boot.img TODO: this boots up to the point where u-boot display a bit of information and then just hangs. References ---------- * https://wiki.gentoo.org/wiki/Custom_Initramfs * https://blogs.s-osg.org/use-mainline-u-boot-non-signed-kernels-exynos-chromebooks/ * https://www.riscosopen.org/forum/forums/5/topics/350 * https://github.com/c0d3z3r0/rockboot * https://prabagaranvt.blogspot.nl/2012/09/kexec.html * http://elinux.org/images/2/2f/ELC-2010-Damm-Kexec.pdf