From b3868a3b009f2ab44fa6d3db3d174930b3cf7b69 Mon Sep 17 00:00:00 2001 From: Ciro Santilli Date: Tue, 13 Feb 2018 15:40:54 +0000 Subject: [PATCH] initrd --- README.adoc | 57 ++++++++++++++++++++++++++++++++++++++- buildroot_config_fragment | 1 + kernel_config_fragment | 4 +++ run | 24 ++++++++++++----- 4 files changed, 79 insertions(+), 7 deletions(-) diff --git a/README.adoc b/README.adoc index 12b7e16..824f5d2 100644 --- a/README.adoc +++ b/README.adoc @@ -892,7 +892,7 @@ ____ + `-M virt` has some limitations, e.g. I could not pass `-drive if=scsi` as for `arm`, and so <> fails. + -* uses initramfs. This glues the rootfs as an initrd directly to the kernel image, so the only argument that QEMU needs is the `-kernel`, and no disk! Pretty cool. +* uses <>, so thre is no filesystem persistency. So, as long as you keep those points in mind, our `-a aarch64` offers an interesting different setup to play with. @@ -1495,6 +1495,61 @@ Aborted (core dumped) If we checkout to the ancient kernel `v2.6.22.9`, it fails to compile with modern GNU make 4.1: https://stackoverflow.com/questions/35002691/makefile-make-clean-why-getting-mixed-implicit-and-normal-rules-deprecated-s lol +=== initrd + +The kernel can boot from an CPIO file, which is a directory serialization format much like tar: https://superuser.com/questions/343915/tar-vs-cpio-what-is-the-difference + +The bootloader, which for us is QEMU itself, is then configured to put that CPIO into memory, and tell the kernel that it is there. + +With this setup, you don't even need to give a root filesystem to the kernel, it just does everything in memory in a ramfs. + +Try it out with: + +.... +./run -i +.... + +Notice how it boots fine, even though `-drive` is not given. + +Also as expected, there is no filesystem persistency, since we are doing everything in memory: + +.... +date >f +poweroff +cat f +# can't open 'f': No such file or directory +.... + +The main ingredients to get this working are: + +* `BR2_TARGET_ROOTFS_CPIO=y`: make Buildroot generate `output/images/rootfs.cpio` in addition to the other images. ++ +It is also possible to compress that image with other options. +* `qemu -initrd`: make QEMU put the image into memory and tell the kernel about it. +* `CONFIG_BLK_DEV_INITRD=y`: Compile the kernel with initrd support ++ +Buildroot forces that option when `BR2_TARGET_ROOTFS_CPIO=y` is given + +https://unix.stackexchange.com/questions/89923/how-does-linux-load-the-initrd-image asks how the mechanism works in more detail. + +==== initramfs + +initramfs is just like initrd, but you also glue the image directly to the kernel image itself. + +So the only argument that QEMU needs is the `-kernel`, no `-drive` not even `-initrd`! Pretty cool. + +Try it out with: + +.... +./run -a aarch64 +.... + +since our <> setup uses it by default. + +In the background, it uses `BR2_TARGET_ROOTFS_INITRAMFS`, and this makes the kernel config option `CONFIG_INITRAMFS_SOURCE` point to the CPIO that will be embedded in the kernel image. + +http://nairobi-embedded.org/initramfs_tutorial.html shows a full manual setup. + === ftrace Trace a single function: diff --git a/buildroot_config_fragment b/buildroot_config_fragment index 8cc8448..c8cf4cc 100644 --- a/buildroot_config_fragment +++ b/buildroot_config_fragment @@ -7,6 +7,7 @@ BR2_ROOTFS_OVERLAY="../rootfs_overlay" BR2_ROOTFS_POST_BUILD_SCRIPT="../rootfs_post_build_script" BR2_ROOTFS_POST_IMAGE_SCRIPT="../rootfs_post_image_script" BR2_ROOTFS_USERS_TABLES="../user_table" +BR2_TARGET_ROOTFS_CPIO=y # Host GDB BR2_GDB_VERSION="7.11.1" diff --git a/kernel_config_fragment b/kernel_config_fragment index 1a0ada4..6f21f54 100644 --- a/kernel_config_fragment +++ b/kernel_config_fragment @@ -1,7 +1,11 @@ # Changes to this file are automatically trigger kernel reconfigures # even without using the linux-reconfigure target. +# +# Beware that buildroot can override some of the configurations we make, e.g. +# it forces CONFIG_BLK_DEV_INITRD=y when BR2_TARGET_ROOTFS_CPIO is on. CONFIG_MODULE_SRCVERSION_ALL=y +CONFIG_BLK_DEV_INITRD=y # GDB debugging. CONFIG_DEBUG_FS=y diff --git a/run b/run index 00313a2..d03069a 100755 --- a/run +++ b/run @@ -13,7 +13,9 @@ nographic=false # Turned on by default since v4.12 extra_append='nokaslr norandmaps printk.devkmsg=on printk.time=y' extra_flags='' -while getopts a:de:knqt:x OPT; do +initrd=false +root='' +while getopts a:de:iknqt:x OPT; do case "$OPT" in a) arch="$OPTARG" @@ -31,6 +33,9 @@ while getopts a:de:knqt:x OPT; do extra_flags="$extra_flags -serial tcp::1234,server,nowait" kgdb=true ;; + i) + initrd=true + ;; n) extra_append="$extra_append console=ttyS0" extra_flags="$extra_flags -nographic" @@ -60,13 +65,18 @@ case "$arch" in if $kgdb; then extra_append="$extra_append kgdboc=ttyS0,115200" fi + if $initrd; then + extra_flags="$extra_flags -initrd '${images_dir}/rootfs.cpio'" + else + root='root=/dev/vda' + extra_flags="$extra_flags -drive file='${images_dir}/rootfs.ext2,if=virtio,format=raw'" + fi cmd="$qemu_common \ -M pc \ --append 'root=/dev/vda nopat $extra_append' \ --device lkmc_pci_min \ +-append '$root nopat $extra_append' \ -device edu \ +-device lkmc_pci_min \ -device virtio-net-pci,netdev=net0 \ --drive file=${images_dir}/rootfs.ext2.qcow2,if=virtio,format=qcow2 \ -kernel ${images_dir}/bzImage \ $extra_flags \ " @@ -77,14 +87,16 @@ $extra_flags \ fi cmd="$qemu_common \ -M versatilepb \ --append 'root=/dev/sda $extra_append' \ +-append '$extra_append' \ -device rtl8139,netdev=net0 \ --drive file=${images_dir}/rootfs.ext2.qcow2,if=scsi,format=qcow2 \ +-initrd ${images_dir}/rootfs.cpio \ -dtb ${images_dir}/versatile-pb.dtb \ -kernel ${images_dir}/zImage \ -serial stdio \ $extra_flags \ " +#-append 'root=/dev/sda $extra_append' \ +#-drive file=${images_dir}/rootfs.ext2.qcow2,if=scsi,format=qcow2 \ ;; aarch64) if $kgdb; then