Wiki/kernel.md

5.0 KiB

Kernel

Get and Prepare Source

  • Download kernel from https://kernel.org: wget https://cdn.kernel.org/pub/linux/kernel/<kernelVersion>.tar.{xz,sign}
  • Uncompress the archive: unxz linux-<kernelVersion>.tar.xz
  • Verify Signature of tar: gpg2 --verify linux-<kernelVersion>.tar.sign
    • If there is a key issue, import keys: gpg2 --locate-keys torvalds@kernel.org gregkh@kernel.org
  • Untar the archive: tar -xvf linux-<kernelVersion>.tar
  • Change ownership: chown -R jeanclaude:jeanclaude <linuxKernel>
  • cd <linuxKernel>
  • Clean source: make mrproper

Configure

  • Config is written to .config

For Qemu

  • Create config file make defconfig
  • Configure for Qemu make kvm_guest.config

Use Hosts Configuration

  • Copy the current hosts config: zcat /proc/config.gz > .config
    • Changing CONFIG_LOCALVERSION is required to prevent overwriting a current kernel
      • Can by done by setting LOCALVERSION=-<someSuffix> for the compile command
  • Some options may have changed, run make olddefconfig to accept defaults

Create own configuration

  • Configure Kernel: make nconfig

Compilation

  • Compile the kernel: make -j $(nproc)
    • We can also choose numCores + 1
  • Compressed kernel is written to arch/x86/boot/bzImage
  • Prepare Modules: make modules -j $(nproc)
  • Install Modules: sudo make modules_install
    • Modules are installed to /lib/modules/<kernelVersion>

Prepare initramfs

  • Investigate what is in the initramfs using lsinitcpio <initramfs>
    • Extract to PWD using lsinitcpio -x <initramfs>

Using Busybox

  • Simple but has limited utilities
#!/bin/bash

ARCH="x86_64"
BB_VER="1.31.0"

# Dirs
mkdir -p root
cd root
mkdir -p bin dev etc lib mnt proc sbin sys tmp var
cd -

# Utils
if [ ! -f "root/bin/busybox" ]; then
    curl -L "https://www.busybox.net/downloads/binaries/${BB_VER}-defconfig-multiarch-musl/busybox-${ARCH}" >root/bin/busybox
fi
cd root/bin
chmod +x busybox
ln -s busybox mount
ln -s busybox sh
cd -

# Init process

cat >>root/init << EOF
#!/bin/busybox sh
/bin/busybox --install -s /bin
mount -t devtmpfs  devtmpfs  /dev
mount -t proc      proc      /proc
mount -t sysfs     sysfs     /sys
mount -t tmpfs     tmpfs     /tmp
setsid cttyhack sh
exec /bin/sh
EOF
chmod +x root/init

# initramfs creation

cd root
find . | cpio -ov --format=newc | gzip -9 >../initramfs
cd -

Using Arch

  • Create ./mkinitcpio.conf with following content:
MODULES=(ext4)
HOOKS=(base systemd modconf sd-vconsole filesystems block keyboard)
  • Enter fakeroot: fakeroot
  • Create initramfs: mkinitcpio --generate initramfs.img --kernel <kernel> --config mkinitcpio.conf
    • <kernel> is must be located in /lib/modules/
  • Leave fakeroot: exit

Run in Qemu Step-by-Step

  • Most basic qemu-system-x86_64 -kernel ../Kernel/arch/x86_64/boot/bzImage
    • Window opens with dmesg output with a panic
  • With terminal but not redirected: qemu-system-x86_64 -kernel ../Kernel/arch/x86_64/boot/bzImage -nographic
  • Redirect output using kernel argument: qemu-system-x86_64 -kernel ../Kernel/arch/x86_64/boot/bzImage -nographic -append "console=ttyS0"
    • Still get panic as there is no root filesystem => no init to run
  • Run with initramfs: qemu-system-x86_64 -kernel ../Kernel/arch/x86_64/boot/bzImage -nographic -append "console=ttyS0" -initrd initramfs.img
    • Get same panic as there is not enough RAM
  • Allocate more memory: qemu-system-x86_64 -kernel ../Kernel/arch/x86_64/boot/bzImage -nographic -append "console=ttyS0" -initrd initramfs.img -m 512
    • For busybox this is all which is required
      • For arch we get Failed to start Switch Root.
    • May have increase memory quite a bit more
  • Create spares file: dd if=/dev/zero of=kernel-hd bs=1M count=2048
  • Create FS on virtual HD: mkfs.ext4 kernel-hd
  • Start using virtual HD: qemu-system-x86_64 -kernel ../Kernel/arch/x86_64/boot/bzImage -nographic -append "console=ttyS0 root=/dev/sda rootfstype=ext4 rw" -initrd initramfs.img -m 512 -hda kernel-hd Copy

Run in Qemu

  • Create dedicated folder
  • Copy the kernel <linuxKernel>/arch/x86/boot/bzImage here
  • Copy some suitable disk image here
  • Start qemu: qemu-system-x86_64 -smp 1 -nographic -kernel bzImage -append "root=/dev/sda rootfstype=ext4 rw console=ttyS0" -hda <diskImg>
    • -hda: disk image
    • -smp: number of cores to simulate
    • -kernel: compressed kernel
    • -append: command line parameters to the kernel
    • -nographic: disable graphic window and use command line instead
  • Quit qemu using Ctrl-a x

SSH Into Kernel

  • Add the following to start Qemu
-netdev user,id=unet,hostfwd=tcp::2222-:22 \
-net user \
  • Ssh into kernel usign ssh root@localhost:2222

Other

  • Generate JSON Compilation Database: scripts/clang-tools/gen_compile_commands.py

Debian/Ubuntu

  • Build for: make -jnproc deb-pkg LOCALVERSION=-choose-your-prefix KDEB_PKGVERSION=$(make kernelversion)-1
  • Install sudo dpkg -i <out>.deb
  • Uninstall sudo apt remove --purge <kernelName>
    • Taken from list installed kernels: dpkg --list | grep linux-image