{"id":17911445,"url":"https://github.com/tklauser/kvm-boot","last_synced_at":"2026-01-28T07:10:04.006Z","repository":{"id":139858594,"uuid":"93033071","full_name":"tklauser/kvm-boot","owner":"tklauser","description":"kvm-boot scripts for Linux kernel developers","archived":false,"fork":false,"pushed_at":"2017-06-01T08:11:28.000Z","size":22,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-08T20:29:46.090Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Roff","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tklauser.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-06-01T08:10:56.000Z","updated_at":"2018-08-16T17:55:03.000Z","dependencies_parsed_at":null,"dependency_job_id":"111bc758-9cd9-4faf-b5c8-35c8dc0b11fd","html_url":"https://github.com/tklauser/kvm-boot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tklauser%2Fkvm-boot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tklauser%2Fkvm-boot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tklauser%2Fkvm-boot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tklauser%2Fkvm-boot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tklauser","download_url":"https://codeload.github.com/tklauser/kvm-boot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246952273,"owners_count":20859811,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-28T19:38:17.762Z","updated_at":"2026-01-28T07:09:58.984Z","avatar_url":"https://github.com/tklauser.png","language":"Roff","funding_links":[],"categories":[],"sub_categories":[],"readme":"kvm-boot\n========\n\nkvm-boot is for folks who work on Linux kernel development and want to test\nkernel compiles fast with an extremely lightweight and very easy to read simple\ntest script. It is currently x86_64 biased, however some initial tests have\nbeen done to make it work with other architectures.\n\nBuild\n-----\n\nThere are not build requirements. Its all shell.\n\nInstall\n-------\n\nJust run:\n\n\t$ make install\n\nSetup\n-----\n\n# Networking setup\n\nWhen you decide you need to spawn guests just run this prior to spawning guests:\n\n\t$ sudo ~/bin/setup-switch\n\nYou may need to edit the file to replace WIRELESS_DEV variable for whatever\nyour actual networking interface is.\n\nYou should see:\n\n\tSeting up switch on tap0\n\tnet.ipv4.ip_forward = 1\n\nThat should get your system setup for networking. It will allow your guests to\nrun using DHCP with full networking. Your hosts will have a functional access\nto the network so long as your host does too. Although this does use dnsmasq we\nprefer to specify all requirements on the command line instead of asking you to\nhave a custom configuraiton file or edit it. This strives for sensible defaults\nthat might work for most).\n\n# KVM use for users\n\nYou will want to enable use of kvm for users. Typically this can be done\nby letting the user be part of the kvm group. This will be important also\nfor networking purposes, in particular you will want the /var/run/qemu-vde.ctl\ndirectory owned by kvm group, and files created as well. Using the sticky\nbit should suffice.\n\nUsage\n-----\n\nThere are two main uses, direct kernel file boot:\n\n\t$ kvm-boot -k arch/x86/boot/bzImage\n\nRaw image boot:\n\n\t$ kvm-boot -b\n\nAdditionally if you are working on qemu development you can always use:\n\n\t$ kvm-boot -d # use $HOME/devel/qemu/x86_64-softmmu/qemu-system-x86_64\n\nRequirements\n------------\n\nYou should have installed on your development system where you will\nrun guests from:\n\n  * vde2\n  * dnsmasq\n  * iptables\n\nProject goals\n-------------\n\n# What we strive for\n\n  * We *want* a super easy-to-read simple script\n  * We *want* a distribution-agnostic solution\n  * We *want* _full_ solid network connectivity for the guest kernels\n  * We *want* network connectivity to be *super easy* to setup\n  * We *want* to allow for qemu-development in a simple way\n  * We *want* to rely on screen(1) /usr/bin/screen\n  * We *want* suspend to RAM / disk \u0026 resume to work on hypervisor host\n  * We *want* to avoid having to copy over linux sources over and over again\n\n# What we want to avoid\n\n  * We *do not* want to deal with complex initramfs setup\n  * We *do not* want to require root access for guest spawning\n  * We *do not* want to deal with the complex network bridge setup\n  * We *do not* want to deal with complex test infrastructure\n  * We *do not* want to deal with fancy GUI crap\n\nThe two methods to boot guests\n------------------------------\n\nWhen working on kernel development you typically have two ways to use KVM.\nThey each have their pros and cons. We support both.\n\n * Direct file: Passing qemu -kernel and -initrd for direct boot use\n * Disk images: using qcow2 disk image\n\nWe document each case further below.\n\n# Direct file\n\n\t$ kvm-boot -k arch/x86/boot/bzImage\n\nThis method allows you to compile kernel code on your local filesystem, and\njust boot into those kernels. Typically this does require initramfs setup,\nhowever, we provide initramfs inference support. Initramfs inferences support\nrelies on the *premise* that distributions have a proper /sbin/installkernel\nscript.\n\nOne of the tricky aspects of using this method is you need a kernel with\nproper support for your KVM guest. You milleage may vary.\n\n## The Linux kernel /sbin/installkernel\n\nThe Linux kernel gives you the option to have a scrip called /sbin/installkernel\nwhich will be used on the 'make install' target of the Linux kernel. Typically\nthis is where distributions shove in their initramfs setup. Most distributions\nrely on this script, and in fact is relied on by a slew of kernel developers to\ninstall ther compiled Linux kernel and modules without *ever* having to deal\nwith local distribution shenanigans.\n\nYou should always be able to compile and install a kernel as follows on any\nLinux distribution:\n\n\t$ make\n\t$ sudo make modules_install install\n\n## Relying on /sbin/installkernel\n\nWe take advantage of how Linux distributions use /sbin/installkernel to ensure\nproper initramfs setup for you for guest setup in a distribution agnostic way.\nThis does require you however to install a target kernel once.\n\n## Enable your target development as built-in\n\nRelying on /sbin/installkernel enables you to deploy an initramfs once, and\nprovided you do not need to rely on that initramfs for new code deltas\n(re-compile modules) you are testing you can boot a second time by only\ncompiling code locally without re-generating the initramfs.\n\nSince you might often be doing development with what typically is enabled as\nmodules you can can avoid the module catch-22 issue here by just enabling your\ndevelopment target and its dependencies to be compiled as built-in.\n\nIf you *really* want to be relying on modules you can consider the other method\nof development work flow with kvm-boot using raw images. An alternative for\nthe future is to consider eventual integration of optionally kicking off\n/sbin/installkernel as an option as a *regular user* during the Linux kernel\n'make' target, which would build the initramfs locally within the Linux kernel\nsource tree.\n\n## kvm-boot initramfs setup\n\nkvm-boot assumes you have your initramfs correctly built and installed by\nrelying on you installing the development kernel locally to your system *once*.\nSince kvm-boot is a distribution agnostic solution we assume the developer can\nalways (regardless of what distribution they are using) can simply always\ninstall kernels and modules you have compiled with:\n\n\t$ make -j 4 # compile kernel and modules\n\nAnd then install the kernel and initramfs as follows:\n\n\t$ sudo make modules_install install  # installs kernel and initramfs\n\nDistribution packaging solutions (rpm, deb) use this target and should rely\non /sbin/installkernel anyway. Intalling kernel/modules using distribution\npackage solutions should therefore always work as well. If relying on this\ndoes not work it should be considered a distribution bug.\n\n## Initramfs inference support\n\nCurrent initramfs inference is rather simple and relies on you specifying the\ntarget kernel you want to use, refer for parse_passed_kernel() for details.\n\n## Using the latest kernel\n\nBy default kvm-boot will look for the latest installed kernel / initramfs on\n/boot/ and use that. Otherwise you should specify the target kernel using -k. \nIf you want to be explicit about using the latest kernel found on /boot you\ncan always use:\n\n\t$ kvm-boot -l\n\n# Disk images\n\nUsing disk images is convenient to do away with all the above required setup.\nWe suppot qcow2 disk image format by default. You will first need to setup a\nbasic qemu image you can use for development purposes. You actually will want\nto setup at least two disk images eventually, one for the guest image, and\nanother for the Linux kernel sources which you can share accross images.\n\nTo start off with build a qcow2 disk image you can use to boot qemu from. We\nstart off with by using an ISO and a raw qcow2 file we will use as target\nraw image. For now we supply an example guest script which folks can simply\ncustomize as they see fit to enable them to install an ISO image of their\nchoice onto a qcow2 image.\n\n## qcow2 image setup\n\nYou want to setup at least 2 qcow2 disk images. One for the guest, another for\nthe Linux kernel sources.\n\n### qcow2 guest image setup\n\nYou will want to create a qcow2 image, 6 GiB typically works, as we will want\nto deploy our Linux kernel sources in another larger image. This should be\nenough to to also carry your /boot/, we'll practice to keep it small using\nthe script install-next-kernel.sh on the guest when installing kernels.\nThis assumes you are using linux-next.git for your development work flow.\n\n\t$ qemu-img create -f qcow2 /opt/qemu/some.img 6G\n\n### qcow2 Linux kernel development image\n\nYou'll want a secondary image you can use with much larger size so you can use\nit for stashing your linux kernel sources.\n\n\t$ qemu-img create -f qcow2 /opt/qemu/linux-next.qcow2 50G\n\nTo copy over the linux sources you can do from the host:\n\n\t$ sudo modprobe nbd max_part=16\n\t$ sudo qemu-nbd -c /dev/nbd0 /opt/qemu/linux-next.qcow2\n\t# Create primary parition and take up all the space\n\t$ sudo fdisk /dev/nbd0\n\t\tCommand (m for help): n\n\t\t...\n\t\tSelect (default p): p\n\t\t...\n\t\tPartition number (1-4, default 1): 1\n\t\t...\n\t\tFirst sector (2048-20971519, default 2048): \n\t\t...\n\t\tLast sector, +sectors or +size{K,M,G,T,P} (2048-20971519, default 20971519): \n\t\t...\n\t\tCommand (m for help): t\n\t\t...\n\t\tPartition type (type L to list all types): 83\n\t\t...\n\t\tCommand (m for help): w\n\t$ sudo partprobe /dev/nbd0\n\t$ sudo mkfs.ext4 /dev/nbd0p1\n\t$ sudo mkdir -p /mnt/linux-next\n\t$ sudo mount /dev/nbd0p1 /mnt/linux-next\n\t$ sudo cp -a ~/linux-next/ /mnt/linux-next\n\t$ sudo umount /mnt/linux-next\n\t$ sudo qemu-nbd -d /dev/nbd0\n\t# nbd has buggy suspend/resume, better remove it\n\t$ sudo modprobe -r nbd\n\nThis image is exposed to the kvm-boot guest kernel we boot later as a secondary\ndisk, using qemu -hdb parameter.\n\n## guest-install\n\nguest-install scripts can help you install an ISO image onto a target qcow2\nimage file, with a fully functionaly network in place, and exposing the\nlinux-next development target image as a secondary disk. Example use:\n\n\t$ ./guest-install -i /opt/isos/some.iso \\\n\t\t\t  -t /opt/qemu/some.img \\\n\t\t\t  -n /opt/qemu/linux-next.qcow2\n\nThat will by defalut use SDL to kick off your installation. Follow the steps to\ninstall the guest, be sure to install and enable SSH, some distros disable this\nby default.\n\nYou can configure the install as you wish, just be sure to dedicate the larger\ndisk for your say, $HOME/$USER/data/ partition.\n\nSome installers are rather pesky and assume the larger disk is where the target\ninstall should be, and sometimes they make it rather difficult through the GUI\nto modify the fact that you just want the larger disk to be used for a home\nsubdirectory for you. So you may want to just skip the -n option and use: -n\nnone:\n\n\t$ ./guest-install -i /opt/isos/some.iso \\\n\t\t\t  -t /opt/qemu/some.img \\\n\t\t\t  -n none\n\nIf you do this can later expose the disk on a second boot and configure it to\nbe mounted on $HOME/$USER/data as follows on /etc/fstab:\n\n\t/dev/sdb1\t/home/mcgrof/data\text4    errors=remount-ro 0       1\n\nOnce done with the install you can use the *same exact command* to boot off the\nhard drive provided the ISO gives you that option (most distros do this). You\nwant to do a first boot to configure the guest a bit for the last touches so\nyou can start hacking away in a nice development environment.\n\nBe sure to expose the development disk so you can configure a mount point for\nit as recommended above, so *make sure* to use the -n option with the respective\nlinux-next.qcow2 file.\n\n## Preparing for first kvm-boot use on guest\n\nOnce you are done with the installation of the guest there are a few more things\nyou will want to set up to be a happy camper Linux developer using kvm-boot,\nyou can set these up using the same guest-install script as described above\nand booting from the hard disk.\n\nYou will want to do the following:\n\n  * console access - useful for early crashes or in case networking dies\n  * grub tty setup - lets you select your kernels on the boot prompt\n  * write down the guest IP address - these should be static after first DHCP\n\n### Setting up console and grub\n\nEdit /etc/securetty and ensure you have the entries:\n\n\tttyS0\n\tttyS1\n\tttyS2\n\nYou will also need to setup the getty to spawn. This will vary depending\non what init system you are using. If you are using old init you will\nneed to add the entries on /etc/inittab:\n\n\tT0:23:respawn:/sbin/getty -L ttyS0 115200 vt100\n\tT1:23:respawn:/sbin/getty -L ttyS1 115200 vt100\n\tT1:23:respawn:/sbin/getty -L ttyS2 115200 vt100\n\nOn systemd this is done as follows:\n\n\tsystemctl enable console-getty.service getty@ttyS0.service\n\tsystemctl enable console-getty.service getty@ttyS1.service\n\tsystemctl enable console-getty.service getty@ttyS2.service\n\nEdit the guest /etc/default/grub and ensure you have these entries:\n\n\tGRUB_CMDLINE_LINUX=\"console=ttyS1,115200 console=ttyS1\"\n\tGRUB_TERMINAL=serial\n\nThe last line mentioned above enables you to select a kernel through the\ngrub prompt through serial.\n\nAfter this you will need to run the boot loader refresh script for your\ndistribution so that the grub configuration files get updated.\n\n  * Debian: update-grub\n  * OpenSUSE: update-bootloader --refresh\n\n## Booting development guest for the first time\n\nProvided you could setup all the above correctly you should be ready to go.\nTry now:\n\n\t$ kvm-boot -t /opt/qemu/some.img -n /opt/qemu/linux-next2.qcow2\n\nYou should see something like this on stdout:\n\n\tGoing to boot directly onto image disk\n\tqemu-system-x86_64: -monitor pty: char device redirected to /dev/pts/9 (label compat_monitor0)\n\tqemu-system-x86_64: -chardev pty,id=ttyS1: char device redirected to /dev/pts/11 (label ttyS1)\n\tqemu-system-x86_64: -chardev pty,id=ttyS2: char device redirected to /dev/pts/12 (label ttyS2)\n\nWe purposely redirect two ttys to a PTS so you can then use screen to attach\nto them (root should not be required). You can also get access to the qemu\ncontrol interface using screen as well:\n\n\t$ screen /dev/pts/9\n\t$ screen /dev/pts/11\n\t$ screen /dev/pts/12\n\n## Sshing into your guest image\n\nMake sure to write down the IP address of the guest before using kvm-boot, you\nshould then be able to ssh into it. There is a slew of issues which can occur\nwhen using console (see the WTF note on kvm-boot), for this reason the author\nhas relied mostly on ssh for access to the system.\n\n## Keeping your /boot small\n\nWhen using qcow2 images you may often find /boot can fill up quickly when\ndoing a lot of development. If you are working with a linux-next development\nwork flow you can consier copying over the file install-next-kernel.sh and\nusing that when installing your kernels, it will make sure to always remove\nold linux-next instances, while keeping your distribution kernels.\n\nTODO\n----\n\n  * Document how to get direct raw access to disk for filesystem benchmarking and\n    testing.\n  * Make sure the above intructions work for most distributions and adjust as\n    needed\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftklauser%2Fkvm-boot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftklauser%2Fkvm-boot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftklauser%2Fkvm-boot/lists"}