đź’» Kernel dev light setup
Summary
This explains my steps into creating a “lightweight” Linux kernel development environment using qemu.
Setup base system
Create the installation image
qemu-img create -f qcow2 <image-name>.qcow2 <size>
Install an Operating system of choice ( I use debian for this )
qemu-system-x86_64 -cpu host \
-vga virtio \
-enable-kvm \
-usb -device usb-tablet \
-hda <qemu image> -boot d \
-cdrom <debian iso file> \
-serial stdio -m <ram> \
-smp <cpu>
Perform os installation then reboot using this command
qemu-system-x86_64 -nic user,hostfwd=tcp::1234-:22 \
-cpu host \
-vga virtio \
-enable-kvm \
-usb -device usb-tablet \
-hda <qemu image> -boot d \
-serial stdio \
-m <ram> -smp <cpu>
Prepare the system
On the graphical output do this
su
<input root password>
apt install ssh
You can now ssh into the vm to setup the required packages
ssh -p 1234 <username>@localhost
apt update
apt install build-essential \
neovim \
libncurses-dev \
libssl-dev \
bc \
libelf-dev \
git \
flex \
bison \
fakeroot \
libperl-dev \
qt5-qmake \
qtbase5-dev \
rsync
Build a new kernel
Now download the Linux sources
Execute as user
git clone --depth 1 https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git -b <kernel_version>
cd linux
Next is to build a kernel compatible with your vm
make mrproper && make localmodconfig
Compile it
make -j$(nrpoc)
Executed as root
make modules_install && make install
Ensure you have access to sbin to update grub in order to boot onto the new kernel.
echo "export PATH=/usr/sbin:$PATH" >> ~/.bashrc
source ~/.bashrc
Writing the export in the shell profile allow to not worry about exporting it again later
update-grub or grub-update
Now you’re done, reboot to start with the new kernel !
Compacting the qcow2 image
First off, install zerofree on the host
On the host
# Load nbd kernel module
sudo modprobe nbd max_part=8
# Connect the QCOW2 image to a /dev/nbd device
sudo qemu-nbd --connect=/dev/nbd0 working-image.qcow2
# Create partition mappings
sudo kpartx -av /dev/nbd0
# Identify partition mappings
sudo blkid /dev/mapper/nbd0p*
# Check and clear partition if needed
sudo e2fsck -f /dev/mapper/nbd0p1
# Ensure the partition isn't mounted
mount | grep /dev/mapper/nbd0p1 # should be empty
# Apply zerofree
sudo zerofree /dev/mapper/nbd0p1
# Cleanup mounts
sudo kpartx -dv /dev/nbd0
sudo qemu-nbd --disconnect /dev/nbd0
Now your image should be as minimal as possible !
Qemu keyboard emulation
To emulate a keyboard with qemu, you can add this flag to the launch command
qemu ... --monitor stdio ...
This will enable the qemu monitor on the current terminal
To trigger a keyboard plugged in
device_add usb-kbd,id=keyboard1
To trigger a keyboard removed
device_del keyboard1
Retrospective
Since then, I have tried many other methods, and even though qemu is practical, I rather used a more commonly use method like a dockerfile ( used in this project ). At the time this post was made, I was still studying at a school where there were no best practices and hand-holding.