Skip to content

Latest commit

 

History

History
130 lines (104 loc) · 5.04 KB

05-cheatsheet.md

File metadata and controls

130 lines (104 loc) · 5.04 KB

Kernel build & QEMU cheat-sheet

A condensed reference for everything in this project. Paths assume the workspace root ~/os_experiments/linux_kernel.

0. One-time host setup (Ubuntu 24.04)

# build toolchain + libs
sudo apt-get install -y flex bison libssl-dev libelf-dev dwarves \
     zstd lz4 cpio kmod build-essential libncurses-dev pkg-config rsync

# LLVM/Clang (needed for kCFI and for Rust) + QEMU
sudo apt-get install -y clang lld llvm libclang-dev qemu-system-x86 qemu-utils

# Rust (for Phase 3)
sudo apt-get install -y bindgen-0.71                 # kernel needs bindgen >= 0.71.1
rustup component add rust-src --toolchain 1.91.1-x86_64-unknown-linux-gnu

# WSL2 only: allow QEMU to use KVM
sudo usermod -aG kvm "$USER"; sudo chmod 0666 /dev/kvm

1. Get the source

# tarball (used for minimal + modern), verified against kernel.org sha256sums.asc
curl -LO https://cdn.kernel.org/pub/linux/kernel/v7.x/linux-7.1.tar.xz
tar -I 'xz -T0' -xf linux-7.1.tar.xz

# git clone (used for the Rust work) — kernel.org has final release tags
git clone --depth 1 --branch v7.1 \
  https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git rust-kernel

2. Config verbs

Command What it does
make tinyconfig smallest possible config
make defconfig sane arch default (boots in QEMU)
make olddefconfig fill in missing symbols with defaults (non-interactive)
make menuconfig interactive TUI editor
make O=<dir> … out-of-tree build (keeps the source tree clean)
scripts/config --file <.config> -e FOO -d BAR --set-str X "y" scripted edits
scripts/kconfig/merge_config.sh -m -O <dir> base.config frag.config merge a fragment
make savedefconfig minimal diff-from-default of current config

3. Build verbs

make -j"$(nproc)" bzImage          # just the compressed kernel image
make -j"$(nproc)" modules          # loadable modules
make -j"$(nproc)" all              # image + modules + dtbs
make LLVM=1 …                      # build with clang + lld instead of gcc
make LLVM=1 BINDGEN=bindgen-0.71 … # Rust-aware build
make rustavailable                 # check the Rust toolchain is usable
make rust-analyzer                 # generate IDE metadata for kernel Rust

Outputs: arch/x86/boot/bzImage (bootable), vmlinux (ELF with symbols/debug).

4. Minimal initramfs (no root needed)

gcc -static -Os -s -o init init.c
gcc -O2 -o gen_init_cpio usr/gen_init_cpio.c
printf 'dir /dev 0755 0 0\nnod /dev/console 0600 0 0 c 5 1\nfile /init %s/init 0755 0 0\n' "$PWD" \
  | ./gen_init_cpio /dev/stdin | gzip -9 > initramfs.cpio.gz

5. Boot in QEMU

qemu-system-x86_64 -M pc -accel kvm -m 256M \
  -kernel arch/x86/boot/bzImage \
  -initrd initramfs.cpio.gz \
  -append "console=ttyS0" \
  -nographic -no-reboot
# quit a -nographic guest:  Ctrl-A  then  X

Useful -append kernel cmdline knobs:

Token Effect
console=ttyS0 kernel log → serial (what -nographic shows)
quiet suppress most boot messages
earlyprintk=serial,ttyS0 very early boot messages
nokaslr disable KASLR (easier debugging)
init=/bin/sh run a shell as PID 1
`preempt=full voluntary

6. Inspect a built kernel / config

file arch/x86/boot/bzImage                     # version, compression
ls -lh arch/x86/boot/bzImage vmlinux           # sizes
strings bzImage | grep -m1 'Linux version'     # version string
scripts/extract-vmlinux bzImage | file -        # decompress bzImage
grep -c '=y'  .config ; grep -c '=m' .config    # built-in vs module counts
scripts/diffconfig old.config new.config        # diff two configs
make kernelrelease                              # full release string incl. LOCALVERSION

7. Rust module workflow (Phase 3)

cd rust-kernel
rustup override set 1.91.1            # pin toolchain for this tree
make LLVM=1 BINDGEN=bindgen-0.71 rustavailable
make LLVM=1 BINDGEN=bindgen-0.71 defconfig
scripts/config -e RUST -e SAMPLES -e SAMPLES_RUST \
               -e SAMPLE_RUST_MINIMAL -e SAMPLE_RUST_SAFE_COUNTER
make LLVM=1 BINDGEN=bindgen-0.71 olddefconfig
make LLVM=1 BINDGEN=bindgen-0.71 -j"$(nproc)"
# built-in Rust modules announce themselves in dmesg at boot; loadable ones:
#   insmod samples/rust/rust_safe_counter.ko   (inside the booted guest)

8. Gotchas hit during this project

Symptom Cause / fix
Boot log cut off at "Inode-cache hash table" pipe block-buffering on SIGTERM; redirect QEMU to a file, not a pipe
QEMU extremely slow, never reaches init no KVM; chmod 0666 /dev/kvm (WSL2) or accept slow TCG
# CONFIG_X86_16BIT is not set ignored option is behind CONFIG_EXPERT; enable EXPERT first
git clone --branch v7.1 fails on GitHub mirror final tags lag there; clone from git.kernel.org
rust_is_available warns libclang≠clang cosmetic (bindgen's libclang-20 vs clang-18); still "available"
bindgen: command not found install bindgen-0.71, pass BINDGEN=bindgen-0.71