Tools to develop kernel, and test it in virtual machines.
kbuild
builds itmkrootfs
creates a rootfs imageqrun
Runs a qemu image with the built kernel and created rootfs image.
This script simplifies building the Linux kernel:
- Builds a lightweight kernel configuration suitable for virtualization (
defconfig
+kvm_guest.config
). - Performs an out-of-tree build (output placed in
x86_64/
orarm64/
subdirectory). - Optionally merges custom configuration options from
pub/pub.config
. - Automatically performs initial configuration if the
.config
file is missing for the target architecture, or when forced with-f
. - Uses parallel make (
-j $(nproc)
) for faster builds.
kbuild [-a ARCH] [-f] [-h]
-a ARCH
Specify the target architecture. Supported values are x86_64
and arm64
. Defaults to x86_64
if omitted.
-f
Force a clean configuration (make mrproper
, make defconfig
, etc.) before building, even if a .config
file already exists in the output directory (ARCH/.config
).
-h
Display the help message and exit.\
If a file named pub/pub.config
exists in the top-level source directory when the configuration sequence is run (see "Automatic Configuration" above), its contents will be appended to the .config file generated by make defconfig. make olddefconfig is then run to integrate these options properly. This provides a convenient way to add or override specific kernel options needed for your build.
-
Clone the kernel source repository:
git clone [email protected]:googleprodkernel/linux-liveupdate.git cd linux-liveupdate git checkout -b luo remotes/origin/luo/rfc-v1
-
Create a custom configuration snippet: Create the
pub
directory and add desired options topub/pub.config
.mkdir pub cat << EOF > pub/pub.config CONFIG_X86_PMEM_LEGACY_DEVICE=y CONFIG_X86_PMEM_LEGACY=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_DAX=y CONFIG_KEXEC_FILE=y CONFIG_KEXEC_HANDOVER=y CONFIG_LIVEUPDATE=y CONFIG_LIVEUPDATE_SYSFS_API=y CONFIG_SAMPLE_KHO=y CONFIG_IGB=y CONFIG_IGBVF=y CONFIG_PCI_IOV=y EOF
-
Run the build script:
- First build for x86_64:
Explanation: This defaults to
kbuild
-a x86_64
. Sincex86_64/.config
does not exist yet, the script automatically runs the full configuration sequence (including mergingpub/pub.config
if it exists) and then starts the build.
- First build for x86_64:
This script automates the creation of a bootable Debian disk image (.img
) using mmdebstrap
. The resulting image is tailored for use in virtual machines (like QEMU), pre-configured with essential tools, SSH access, basic networking, and other useful settings for development and testing.
The script requires sudo
privileges to run and relies on the following key packages being installed on the host system:
mmdebstrap
: For bootstrapping the Debian system.qemu-utils
: Providesqemu-img
for creating the disk image file.e2fsprogs
: Providesmkfs
(specificallymkfs.ext4
) for formatting the image.- Standard Linux utilities:
mount
,umount
,mkdir
,rmdir
,cat
,tee
,sed
,sync
,mountpoint
,nice
, etc.
mkrootfs -o <output-image-file> [-d <release>] [-a <arch>] [-s <size>] [-h]
-o <file>
: Mandatory. Specifies the filename for the output disk image (e.g.,debian-bookworm.img
). The script will exit if the file already exists.-d <name>
: Specify the Debian release codename to bootstrap (e.g.,bookworm
,bullseye
). (Default:bookworm
)-a <arch>
: Specify the target architecture using Debian's naming convention (e.g.,amd64
,arm64
). (Default:amd64
)-s <size>
: Set the total size of the disk image (e.g.,8G
,10G
,20G
). (Default:8G
)-h
: Display the help message and exit.
The script performs several configurations on the bootstrapped Debian system:
- Installed Packages: Installs a base system plus common development and debugging tools, including:
ssh
,acpid
,gdb
,systemtap
,strace
,vim
,bpftool
,bpftrace
,trace-cmd
,linux-perf
,pciutils
,psmisc
,file
, etc. (See thePACKAGES
variable in the script for the complete list). - SSH Access:
- Configures the SSH daemon (
sshd_config
) to allow root login via public key and password (PermitRootLogin yes
,PasswordAuthentication yes
). Note: These are permissive settings suitable for testing VMs. - Copies the public SSH key found at
$HOME/.ssh/id_rsa.pub
(by default) on the host machine to/root/.ssh/authorized_keys
inside the image, enabling passwordless root login via that key. Ensure this key exists or modify theSSH_PUB_KEY
variable in the script.
- Configures the SSH daemon (
- Networking:
- Enables
systemd-networkd
. - Creates a network configuration file (
/etc/systemd/network/80-dhcp.network
) to enable DHCP on interfaces nameden*
. - Sets the DNS server to
8.8.8.8
in/etc/resolv.conf
.
- Enables
- Hostname: Sets the hostname within the image (Default:
liveupdate-vm
). - Serial Console Autologin: Modifies the
[email protected]
unit file to automatically log in theroot
user on thettyS0
serial console. - Filesystem Table (
fstab
): Adds an entry for mounting a potential 9p filesystem (often used for host directory sharing in QEMU) namedhostfs
at the/host
mount point within the image. - Enabled Services: Enables
sshd
,systemd-networkd
, andacpid
services to start on boot.
# Create a default Debian bookworm amd64 image
mkrootfs -o pub/bookworm.img -s 8G
This script acts as a convenient wrapper for launching QEMU virtual machines, primarily intended for testing custom-built Linux kernels. It sets up common QEMU options, networking, filesystem sharing, and architecture-specific parameters, simplifying the QEMU command line. It now integrates with the mkrootfs
script to automatically create a suitable Debian root disk image if one doesn't exist at the specified path.
- QEMU: Requires
qemu-system-x86_64
and/orqemu-system-arm64
to be installed and in the system'sPATH
, or specified via the-q
option. - (x86_64 Optional): The default configuration uses
-bios "qboot.rom"
. Ensure this BIOS file is available to QEMU if using the default x86_64 setup. - Kernel Image: A compiled kernel image (
bzImage
for x86_64,Image
for arm64) needs to be available. The script expects it at a path relative to the current working directory, typically matching the output structure ofkbuild
(e.g.,x86_64/arch/x86/boot/bzImage
orarm64/arch/arm64/boot/Image
). - Root Disk Image OR
mkrootfs
:- EITHER a suitable pre-existing root filesystem image (see
-i
option and default path). - OR the
mkrootfs
script (assumed to be in thePATH
or same directory) and its dependencies (mmdebstrap
,qemu-utils
,e2fsprogs
,sudo
, etc.) to allow for automatic image creation if the specified image file is not found.
- EITHER a suitable pre-existing root filesystem image (see
qrun [-k <append_kernel_cmd>] [-m MEM] [-c NCPU] [-a ARCH] [-N] [-i image] [-q qemu_exec] [-h] [-- qemu_options]
-k <append_kernel_cmd>
: Append extra parameters to the kernel command line string (e.g.,-k "debug loglevel=7"
).-m MEM
: Specify the amount of RAM for the virtual machine (e.g.,4G
,8192M
). (Default:8G
)-c NCPU
: Set the number of CPU cores for the virtual machine. (Default:4
)-a ARCH
: Define the target architecture (x86_64
orarm64
). (Default:x86_64
)-N
: Disable the script's default network configuration (no-net nic
,-net user
,-qmp
, or-s
).-i <image>
: Specify the path to the root disk image file to use. (Default:$HOME/.images/debian_ARCH-RELEASE.img
, e.g.,$HOME/.images/debian_x86_64-bookworm.img
)-q <qemu_exec>
: Specify the path to the QEMU executable. (Default:qemu-system-ARCH
, e.g.,qemu-system-x86_64
)-h
: Display the help message and exit.-- <qemu_options>
: Any arguments placed after a double dash (--
) are passed directly to the underlying QEMU command line, bypassing the script's parsing.
Unless overridden by options, qrun
sets up the VM with:
- General:
- Runs headless (
-nographic
) with the serial console connected to stdio (-serial mon:stdio
). - Exits QEMU when the guest shuts down (
-no-reboot
). - Sets the VM name to
qrunvm
(-name "qrunvm"
).
- Runs headless (
- Filesystem Sharing:
- Shares the host's root filesystem (
/
) using virtfs (-virtfs local,path=/,mount_tag=hostfs,...
). This can typically be mounted inside the guest usingmount -t 9p -o trans=virtio hostfs /host
.
- Shares the host's root filesystem (
- Networking (Enabled by default, disable with
-N
):- Attaches a
virtio-net-pci
network interface (-net nic,...
). - Uses QEMU's user-mode networking (
-net user,...
). - Forwards host TCP port
5555
to guest port22
(SSH) (hostfwd=tcp::5555-:22
). - Enables the QEMU Machine Protocol (QMP) server on TCP port
4444
(-qmp tcp:localhost:4444,...
). - Includes
-s
, which is shorthand for enabling a GDB server stub (-gdb tcp::1234
).
- Attaches a
- Architecture Specifics:
x86_64
: Enables KVM hardware acceleration (-enable-kvm
), uses theq35
machine type, attempts to pass through the host CPU features (-cpu host
), and usesqboot.rom
as the BIOS. Appendsconsole=ttyS0... root=/dev/sda...
to the kernel command line. Expects kernel imagebzImage
.arm64
: Uses thevirt
machine type andcortex-a57
CPU model. Appendsconsole=ttyAMA0... root=/dev/vda...
to the kernel command line. Expects kernel imageImage
.
- Disk Image (
-i
): Uses the image specified via-i
, or defaults to a path like$HOME/.images/debian_x86_64-bookworm.img
. See note below regarding automatic creation. - Kernel (
-kernel
): Uses the kernel image found relative to the current directory (e.g.,x86_64/arch/x86/boot/bzImage
). - Kernel Command Line (
-append
): Includesrw
and architecture-specificroot=
andconsole=
parameters, plus any extra arguments added via-k
.
This example shows how to invoke qrun
with specific settings for the QEMU executable, architecture, memory, CPU count, kernel parameters, and a custom disk image. It also demonstrates how to pass complex, specific -netdev
and -device
configurations directly to QEMU using the --
separator.
./qrun \
-q /qemu/bin/qemu-system-x86_64 \
-a x86_64 \
-m 16G \
-c 8 \
-k 'memmap=8G!4G kho_scratch=1G kho=1 liveupdate=1 quiet selinux=0 intel_iommu=on intel_iommu=pt ' \
-i pub/bookworm.img \
-- \
-netdev user,id=PHYS_FUNC0 \
-netdev user,id=VF0 \
-netdev user,id=VF1 \
-netdev user,id=VF2 \
-device pcie-root-port,id=BUS0 \
-device virtio-net-pci,bus=BUS0,addr=0x0.0x3,netdev=VF2,sriov-pf=PF0 \
-device virtio-net-pci,bus=BUS0,addr=0x0.0x2,netdev=VF1,sriov-pf=PF0 \
-device virtio-net-pci,bus=BUS0,addr=0x0.0x1,netdev=VF0,sriov-pf=PF0 \
-device virtio-net-pci,bus=BUS0,addr=0x0.0x0,netdev=PHYS_FUNC0,id=PF0