Skip to content

Instantly share code, notes, and snippets.

@smoser
Last active August 2, 2022 18:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smoser/a955b8b5fcf1f47b6c32c4f3a0ec9287 to your computer and use it in GitHub Desktop.
Save smoser/a955b8b5fcf1f47b6c32c4f3a0ec9287 to your computer and use it in GitHub Desktop.
test kernel and initrd boot with cirros

Minimal initramfs

If you are playing around with qemu, sometimes it is useful to have a kernel and initrd easily available to play with. Cirros provides kernel and initramfs that can be used for this purpose.

This init script here provides a initramfs /init that will do nothing but write the kernel command line and then power the system off. You can adjust it to your needs.

The get-krd script will:

  • download cirros kernel to 'kernel' and initramfs to 'initramfs.dist'
  • create 'initramfs' with init as the /init by appending to the cpio archive.

You can use this basically like below, the kernel and initramfs boot, the provided init which executes echo o >/proc/sysrq-trigger and powers off the system.

$ ./get-krd .
using cached ./kernel
using cached ./initramfs.dist
created ./initramfs with 'init' from /tmp/testing

$ ls -l kernel initramfs
-rw-rw-r-- 1 smoser smoser 6581017 Mar 14 15:12 initramfs
-rw-rw-r-- 1 smoser smoser 9144704 Dec  7 02:53 kernel

$ time qemu-system-x86_64 -enable-kvm -m 1024 -nographic \
    -kernel ./kernel -initrd ./initramfs \
    -append "console=ttyS0 this is my cmdline"
Booting from ROM...
[    0.000000] Linux version 5.3.0-26-generic (buildd@lgw01-amd64-039) (gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1)) #28~18.04.1-Ubuntu SMP Wed Dec 18 16:40:14 UTC 2019 (Ubuntu 5.3.0-26.28~18.04.1-generic 5.3.13)
[    0.000000] Command line: console=ttyS0 this is my cmdline
[    0.000000] KERNEL supported cpus:
[    0.000000]   Intel GenuineIntel
[    0.000000]   AMD AuthenticAMD
[    0.000000]   Hygon HygonGenuine
[    0.000000]   Centaur CentaurHauls
[    0.000000]   zhaoxin   Shanghai
[    0.000000] x86/fpu: x87 FPU will use FXSAVE
...
[    0.000000] BIOS-provided physical RAM map:
[    0.987858] x86/mm: Checked W+X mappings: passed, no W+X pages found.
[    0.988673] Run /init as init process
==== MINI INITRAMFS INIT ====
KERNEL COMMAND LINE: console=ttyS0 this is my cmdline
[    0.993539] sysrq: Power Off
[    0.994119] reboot: Power down

real  0m1.339s
user  0m0.685s
sys   0m0.472s
#!/bin/bash
CIRROS_VERSION=${CIRROS_VERSION:-0.5.2}
CIRROS_ARCH=${CIRROS_ARCH:-x86_64}
CIRROS_MIRROR="http://download.cirros-cloud.net/"
set -o pipefail
Usage() {
cat <<EOF
Usage: ${0##*/} [outd]
downloads cirros kernel at ${CIRROS_VERSION}.
if not provided, 'outd' defaults to '.'.
creates:
outd/kernel a cirros kernel
outd/initramfs.dist an unmodified cirros initramfs
outd/initramfs an updated initramfs with 'init' from .
EOF
}
mkcpio() {
local tmpf="" rc=0
tmpf=$(mktemp "${TMPDIR:-/tmp}/${0##*/}.XXXXXX") || {
stderr "failed to create tmp file"
return 1
}
(for f in "$@"; do echo "$f"; done |
cpio --create --owner=+0:+0 -H newc ) 2>"$tmpf"
rc=$?
[ $rc -eq 0 ] || {
stderr "failed cpio create newc:"
cat "$tmpf" 1>&2
}
rm -f "$tmpf"
return $rc
}
fail() { stderr "$@"; exit 1; }
stderr() { echo "$@" 1>&2; }
[ "$1" = "-h" -o "$1" = "--help" ] && { Usage; exit 0; }
[ $# -gt 1 ] && { Usage 1>&2; stderr "got $# args."; exit 1; }
outd=${1:-.}
[ -d "$outd" ] || mkdir -p "$outd" || fail "failed to create $outd"
startd="$PWD"
cd "$outd" || fail "could not cd '$outd'"
burl="${CIRROS_MIRROR}/${CIRROS_VERSION}"
for toks in kernel initramfs:initramfs.dist; do
rname=${toks%:*}
lname=${toks#*:}
cname="cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-$rname"
[ -f "$lname" ] && {
stderr "using cached $outd/$lname"
continue;
}
wget "$burl/$cname" -O "$lname.tmp" &&
mv "$lname.tmp" "$lname" || {
rm -f "$lname.tmp"
fail "failed to download $lname from $burl/$cname"
}
done
if [ -f "$startd/init" ]; then
[ -x "$startd/init" ] || chmod 755 "$startd/init" ||
fail "failed to make $startd/init executable"
( zcat initramfs.dist && cd "$startd" && mkcpio init ) |
gzip -c > initramfs.tmp &&
mv "initramfs.tmp" "initramfs" || {
rm -f "initramfs.tmp"
fail "failed to create initramfs"
}
stderr "created $outd/initramfs with 'init' from $startd"
else
stderr "no 'init' in $startd, not creating initramfs"
fi
exit
#!/bin/sh
# vi: ts=4 expandtab
msg() {
local d="" written=false
for d in /dev/ttyS0 /dev/tty1; do
[ -c "$d" ] || continue
echo "$@" >"$d" 2>&1 && written=true;
done
[ "$written" = "true" ] && return 0
echo "$@"
}
panic() {
msg "FATAL:" "$@"
}
msg "==== MINI INITRAMFS INIT ===="
mkdir -p /proc /dev /tmp /sys
mount -t devtmpfs /dev /dev ||
panic "failed mount devtmpfs"
mount -t proc /proc /proc ||
panic "failed mount proc"
mount -t sysfs /sys /sys ||
panic "failed mount /sys"
echo "6 4 1 7" >/proc/sys/kernel/printk
read cmdline < /proc/cmdline ||
panic "failed to read cmdline"
msg "KERNEL COMMAND LINE:" "$cmdline"
echo o >/proc/sysrq-trigger
read || panic "Read returned $?"
panic "Read returned success; What to do now?"
exit 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment