Skip to content

Instantly share code, notes, and snippets.

@n3rdopolis
Created April 29, 2023 01:42
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n3rdopolis/95a916ab07066290ee4abc7a84f98098 to your computer and use it in GitHub Desktop.
Save n3rdopolis/95a916ab07066290ee4abc7a84f98098 to your computer and use it in GitHub Desktop.
Build a Linux kernel with a initrd, to test it and its modules in QEMU with a test script
#! /bin/bash
mkdir -p /var/cache/kerneltest
#Make a file system image for the VM, and mount it.
if [[ -e /var/cache/kerneltest/fs.img ]]
then
rm /var/cache/kerneltest/fs.img
fi
truncate -s 2G /var/cache/kerneltest/fs.img
mkfs.ext4 /var/cache/kerneltest/fs.img
mkdir -p /var/cache/kerneltest/fsmount
mount -o loop /var/cache/kerneltest/fs.img /var/cache/kerneltest/fsmount
#Install a minimal Debian system on the file system
debootstrap --arch amd64 bookworm /var/cache/kerneltest/fsmount http://httpredir.debian.org/debian
#Download linux from git.
if [[ ! -e /var/cache/kerneltest/linux ]]
then
git clone https://github.com/torvalds/linux /var/cache/kerneltest/linux
fi
#checkout a version
env -C /var/cache/kerneltest/linux -- git checkout v6.2
#Configure the kernel, Make smaller modules. Building with Debian/Ubuntu's default SYSTEM_TRUSTED_KEYS and SYSTEM_REVOCATION_KEYS causes build errors
cat /boot/config-$(uname -r) > /var/cache/kerneltest/linux/.config
env -C /var/cache/kerneltest/linux -- scripts/config --disable SYSTEM_TRUSTED_KEYS
env -C /var/cache/kerneltest/linux -- scripts/config --disable SYSTEM_REVOCATION_KEYS
env -C /var/cache/kerneltest/linux -- ./scripts/config -d CONFIG_DEBUG_INFO
env -C /var/cache/kerneltest/linux -- ./scripts/config -d CONFIG_DEBUG_INFO_BTF
env -C /var/cache/kerneltest/linux -- ./scripts/config -d CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT
env -C /var/cache/kerneltest/linux -- make olddefconfig
#Compile the kernel, install the moudles into the file system
env -C /var/cache/kerneltest/linux -- make -j$(nproc)
env -C /var/cache/kerneltest/linux -- make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=/var/cache/kerneltest/fsmount modules_install -j$(nproc)
#Make an initrd with the kernel modules
KernelVersion=$(env -C /var/cache/kerneltest/linux -- make kernelversion)
chroot /var/cache/kerneltest/fsmount/ apt-get install initramfs-tools -y
cp /var/cache/kerneltest/linux/.config /var/cache/kerneltest/fsmount/boot/config-$KernelVersion
chroot /var/cache/kerneltest/fsmount/ update-initramfs -k $KernelVersion -c
cp /var/cache/kerneltest/fsmount/boot/initrd.img-$KernelVersion /var/cache/kerneltest/linux
#Make a test script at /testscript
#do a test, get a result, echo the return code to /dev/ttyS1 echo logging info to /dev/ttyS0, shut down the VM.
cat <<'EOF' > /var/cache/kerneltest/fsmount/testscript
#! /bin/bash
example=$(($RANDOM %2))
if [[ $example == 0 ]]
then
true
else
false
fi
echo $? > /dev/ttyS1
echo "log info" > /dev/ttyS0
echo o > /proc/sysrq-trigger
sleep inf
EOF
chmod +x /var/cache/kerneltest/fsmount/testscript
#Set the test to run on the serial console upon bootup of the VM
chroot /var/cache/kerneltest/fsmount/ systemctl enable getty@ttyS0.service
mkdir -p /var/cache/kerneltest/fsmount/etc/systemd/system/getty@ttyS0.service.d
echo "[Service]" > /var/cache/kerneltest/fsmount/etc/systemd/system/getty@ttyS0.service.d/override.conf
echo "ExecStart=" >> /var/cache/kerneltest/fsmount/etc/systemd/system/getty@ttyS0.service.d/override.conf
echo "ExecStart=-/testscript" >> /var/cache/kerneltest/fsmount/etc/systemd/system/getty@ttyS0.service.d/override.conf
#Give a diagnostic root shell instead of a login prompt
mkdir -p /var/cache/kerneltest/fsmount/etc/systemd/system/getty@tty1.service.d
echo "[Service]" > /var/cache/kerneltest/fsmount/etc/systemd/system/getty@tty1.service.d/override.conf
echo "ExecStart=" >> /var/cache/kerneltest/fsmount/etc/systemd/system/getty@tty1.service.d/override.conf
echo "ExecStart=-/sbin/agetty -o '-p -f -- \\u' --autologin root --keep-baud 115200,57600,38400,9600 %I $TERM" >> /var/cache/kerneltest/fsmount/etc/systemd/system/getty@tty1.service.d/override.conf
#Do more customisations here
#chroot /var/cache/kerneltest/fsmount/ SOMECOMMAND --args
#unmount the file system
umount /var/cache/kerneltest/fsmount
#run the VM test, the return code is in /var/cache/kerneltest/testresult logs from te test are in /var/cache/kerneltest/testlog the kernel log is in /var/cache/kerneltest/consolelog
qemu-system-x86_64 --enable-kvm -m 512 -kernel /var/cache/kerneltest/linux/arch/x86_64/boot/bzImage -initrd /var/cache/kerneltest/linux/initrd.img-$KernelVersion -append "root=/dev/sda rw console=ttyS2" -drive file=/var/cache/kerneltest/fs.img,format=raw,index=0,media=disk -chardev stdio,id=char0,mux=on -serial chardev:char0 -mon chardev=char0 -chardev file,id=char1,path=/var/cache/kerneltest/testresult -serial chardev:char1 -chardev file,id=char2,path=/var/cache/kerneltest/consolelog -serial chardev:char2 > /var/cache/kerneltest/testlog
clear
ErrorResult=$(cat /var/cache/kerneltest/testresult)
echo "VM Test exited with $ErrorResult"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment