diff options
-rw-r--r-- | content/20191027-kernel-debugging-qemu.md | 30 | ||||
-rw-r--r-- | content/20191027-kernel-debugging-qemu/Dockerfile | 32 | ||||
-rw-r--r-- | content/20191027-kernel-debugging-qemu/Makefile | 12 | ||||
-rwxr-xr-x[-rw-r--r--] | content/20191027-kernel-debugging-qemu/build_initrd.sh | 12 | ||||
-rwxr-xr-x[-rw-r--r--] | content/20191027-kernel-debugging-qemu/build_kernel.sh | 2 | ||||
-rwxr-xr-x | content/20191027-kernel-debugging-qemu/run.sh | 24 |
6 files changed, 107 insertions, 5 deletions
diff --git a/content/20191027-kernel-debugging-qemu.md b/content/20191027-kernel-debugging-qemu.md index 5189f86..7a97fbc 100644 --- a/content/20191027-kernel-debugging-qemu.md +++ b/content/20191027-kernel-debugging-qemu.md @@ -6,6 +6,10 @@ date = 2019-10-27 tags = ["linux", "qemu"] +++ +**EDIT**: +- 2021-07-15: Added `Appendix: Dockerfile for Kernel development` and updated + busybox + Kernel versions. + The other evening while starring at some Linux kernel code I thought, let me setup a minimal environment so I can easily step through the code and examine the state. @@ -186,6 +190,32 @@ type = struct filename { } ``` +## Appendix: `Dockerfile` for Kernel development + +The following `Dockerfile` provides a development environment with all the +required tools and dependencies, to re-produce all the steps of building and +debugging the Linux kernel. +```dockerfile +{{ include(path="content/20191027-kernel-debugging-qemu/Dockerfile") }} +``` + +Save the listing above in a file called `Dockerfile` and build the docker image +as follows. +```sh +docker build -t kernel-dev +``` +> Optionally set `DOCKER_BUILDKIT=1` to use the newer image builder. + +Once the image has been built, an interactive container can be launched as +follows. +```sh +# Some options for conveniene: +# -v <HOST>:<GUEST> Mount host path to guest path. +# --rm Remove the container after exiting. + +docker run -it kernel-dev +``` + [linux-kernel]: https://www.kernel.org [initrd]: https://www.kernel.org/doc/html/latest/admin-guide/initrd.html [busybox]: https://busybox.net diff --git a/content/20191027-kernel-debugging-qemu/Dockerfile b/content/20191027-kernel-debugging-qemu/Dockerfile new file mode 100644 index 0000000..42e1f05 --- /dev/null +++ b/content/20191027-kernel-debugging-qemu/Dockerfile @@ -0,0 +1,32 @@ +FROM ubuntu:20.04 +MAINTAINER Johannes Stoelp <johannes.stoelp@gmail.edu> + +RUN apt update \ + && DEBIAN_FRONTEND=noninteractive \ + apt install \ + --yes \ + --no-install-recommends \ + # Download & unpack. + wget \ + ca-certificates \ + xz-utils \ + # Build tools & deps (kernel). + make \ + bc \ + gcc g++ \ + flex bison \ + libelf-dev \ + # Build tools & deps (initrd). + cpio \ + # Run & debug. + qemu-system-x86 \ + gdb \ + telnet \ + # Convenience. + ripgrep \ + fd-find \ + neovim \ + && rm -rf /var/lib/apt/lists/* \ + && apt-get clean + +WORKDIR /develop diff --git a/content/20191027-kernel-debugging-qemu/Makefile b/content/20191027-kernel-debugging-qemu/Makefile new file mode 100644 index 0000000..11e7c7b --- /dev/null +++ b/content/20191027-kernel-debugging-qemu/Makefile @@ -0,0 +1,12 @@ +build: + scripts/build_kernel.sh + scripts/build_initrd.sh + +clean: + $(RM) -r linux-* + $(RM) -r busybox-* + $(RM) initramfs.cpio.gz + +docker: + DOCKER_BUILDKIT=1 docker build -t kernel-dev . + docker run -it --rm -v $(PWD):/develop/scripts -v $(PWD)/Makefile:/develop/Makefile kernel-dev diff --git a/content/20191027-kernel-debugging-qemu/build_initrd.sh b/content/20191027-kernel-debugging-qemu/build_initrd.sh index 74f9896..fd82990 100644..100755 --- a/content/20191027-kernel-debugging-qemu/build_initrd.sh +++ b/content/20191027-kernel-debugging-qemu/build_initrd.sh @@ -1,8 +1,12 @@ #!/bin/bash +if test $(id -u) -ne 0; then + SUDO=sudo +fi + set -e -BUSYBOX=busybox-1.31.0 +BUSYBOX=busybox-1.33.1 INITRD=$PWD/initramfs.cpio.gz ## Build busybox @@ -40,9 +44,9 @@ EOF chmod +x init # 3. create device nodes -sudo mknod dev/tty c 5 0 -sudo mknod dev/tty0 c 4 0 -sudo mknod dev/ttyS0 c 4 64 +$SUDO mknod dev/tty c 5 0 +$SUDO mknod dev/tty0 c 4 0 +$SUDO mknod dev/ttyS0 c 4 64 # 4. created compressed initrd find . -print0 \ diff --git a/content/20191027-kernel-debugging-qemu/build_kernel.sh b/content/20191027-kernel-debugging-qemu/build_kernel.sh index f1e15bb..7ae3014 100644..100755 --- a/content/20191027-kernel-debugging-qemu/build_kernel.sh +++ b/content/20191027-kernel-debugging-qemu/build_kernel.sh @@ -2,7 +2,7 @@ set -e -LINUX=linux-5.3.7 +LINUX=linux-5.13.2 wget https://cdn.kernel.org/pub/linux/kernel/v5.x/$LINUX.tar.xz unxz $LINUX.tar.xz && tar xf $LINUX.tar diff --git a/content/20191027-kernel-debugging-qemu/run.sh b/content/20191027-kernel-debugging-qemu/run.sh new file mode 100755 index 0000000..b0a84ae --- /dev/null +++ b/content/20191027-kernel-debugging-qemu/run.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +VER=5.13.2 + +# Launch the emulator with our kernel. +qemu-system-x86_64 \ + -kernel ./linux-$VER/arch/x86/boot/bzImage \ + -nographic \ + -append "earlyprintk=ttyS0 console=ttyS0 nokaslr init=/init debug" \ + -initrd ./initramfs.cpio.gz \ + -serial telnet:localhost:12345,server,nowait \ + -monitor none \ + -gdb tcp::1234 \ + -S & + +# Kill qemu when we exit. +QEMU_PID=$! +trap "kill $QEMU_PID" EXIT + +# Give qemu some time to come up. +sleep 0.5 + +# Attach debugger to qemu and load the kernel symbols. +gdb -ex 'target remote :1234' ./linux-$VER/vmlinux |