If using raw QEMU to boot the VM image with the custom kernel, you can specify the -kernel
command argument to point to the custom kernel image:
cd linux-5.4.86
qemu-system-x86_64 -kernel arch/x86/boot/bzImage -hda ../my-linux.img \
-append "root=/dev/sda console=ttyS0" -m 4G --nographic
Debian GNU/Linux 10 razor5 ttyS0
razor5 login: root
Password:
Linux razor5 5.4.86 #1 SMP Mon Jan 4 12:34:19 EST 2021 x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@razor5:~#
When using libvirt
to manage the VM, the VM by default boots with the virtual disk's kernel. Testing an updated kernel involves scp
or sharing the kernel image to the VM and installing the kernel in the guest. For frequently testing kernel changes, a more efficient way is to
use the direct kernel boot option with the kernel image file on the host.
virsh edit obiwan-dev
Change the <os>
tag to be like the following:
<os>
<type arch='x86_64' machine='pc-i440fx-bionic'>hvm</type>
<kernel>/path/to/kernel/arch/x86/boot/bzImage</kernel>
<cmdline>console=ttyS0 root=/dev/vda1 rw</cmdline>
<boot dev='hd'/>
</os>
Then later with virsh start obiwan-dev
, the VM will always boot with the latest bzImage
compiled in the host.
KVM can significantly accelerate the boot time. libvirt
probes the presence of KVM and enables it in the VM profile if it's available. Thus, no additional configuration needs to be done. For raw QEMU, you need to add the --enable-kvm
option:
sudo qemu-system-x86_64 -kernel arch/x86/boot/bzImage -hda ../my-linux.img \
-append "root=/dev/sda console=ttyS0" --enable-kvm -m 4G --nographic
If you do not want to risk using sudo
every time running QEMU, here is a way to run as normal user.
KVM only requires access to /dev/kvm
, which has owner root:kvm
and file mode 660
. Add a normal user to the kvm
group:
sudo usermod -a -G kvm `whoami`
User group modification takes effect after logging out and logging in again.
It is recommended to install the custom kernel into the VM at least once as well. To do that, you need to build the kernel into distribution packages. Then copy the package files into the VM either through shared folder or scp.
Once in the VM, install the package files:
sudo dpkg -i linux-headers-5.4.0_5.4.0-1_amd64.deb
sudo dpkg -i linux-image-5.4.0_5.4.0-1_amd64.deb
sudo dpkg -i linux-libc-dev_5.4.0-1_amd64.deb
Note: there might be a .deb package for a debug image, e.g., linux-image-5.4.0-dbg_5.4.0-1_amd64.deb
, which is quite big. Do NOT install that package.
Reboot the VM. Now without specifying the custom kernel in the boot option, you should still see the new kernel version:
uname -a
Note after you install the custom kernel, you will likely encounter a loss of VM network after you reboot the VM. Refer to the troubleshooting page for how to resolve the issue.
To automatically select the custom kernel during booting:
- Find the custom kernel menu entry:
grep -e "menuentry " -e submenu -e linux /boot/grub/grub.cfg
For example, if the output is
...
submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-8b9e1980-828f-418f-ae44-80689ca8bd2f' {
menuentry 'Ubuntu, with Linux 5.4.0-100-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-100-generic-advanced-8b9e1980-828f-418f-ae44-80689ca8bd2f' {
gfxmode $linux_gfx_mode
linux /boot/vmlinuz-5.4.0-100-generic root=UUID=8b9e1980-828f-418f-ae44-80689ca8bd2f ro console=ttyS1,115200
menuentry 'Ubuntu, with Linux 5.4.0-100-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-100-generic-recovery-8b9e1980-828f-418f-ae44-80689ca8bd2f' {
linux /boot/vmlinuz-5.4.0-100-generic root=UUID=8b9e1980-828f-418f-ae44-80689ca8bd2f ro recovery nomodeset dis_ucode_ldr console=ttyS1,115200
menuentry 'Ubuntu, with Linux 5.4.0' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-advanced-8b9e1980-828f-418f-ae44-80689ca8bd2f' {
gfxmode $linux_gfx_mode
linux /boot/vmlinuz-5.4.0 root=UUID=8b9e1980-828f-418f-ae44-80689ca8bd2f ro console=ttyS1,115200
menuentry 'Ubuntu, with Linux 5.4.0 (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-5.4.0-recovery-8b9e1980-828f-418f-ae44-80689ca8bd2f' {
linux /boot/vmlinuz-5.4.0 root=UUID=8b9e1980-828f-418f-ae44-80689ca8bd2f ro recovery nomodeset dis_ucode_ldr
...
Assume our custom kernel is 'Ubuntu, with Linux 5.4.0', which is the 3rd menuentry
under the submenu
.
-
Change the
GRUB_DEFAULT=0
line in the/etc/default/grub
file. If the custom kernel is theNth
menuentry
undersubmenu
, change it toGRUB_DEFAULT="1>$N-1$"
. For example, for a 3rdmenuentry
, change it toGRUB_DEFAULT="1>2"
. -
Update grub script and reboot:
sudo update-grub
sudo reboot