-
Install packages that we need. For Ubuntu this includes:
apt-install git build-essential ncurses-dev xz-utils libssl-dev \ bc flex libelf-dev bison qemu-system-x86 gdb
-
Get the Linux source. (Or use your Linux distribution's package manager to fetch it.)
mkdir ~/src cd ~/src # Choose the tag for the version you want... git clone --depth 1 --branch v6.8 \ git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git cd linux
-
Choose debugging parameters for the kernel. (You can use your Linux distribution's config from /boot but it probably has a lot of features enabled and therefore take a long time to compile.)
make defconfig ./scripts/config -d DEBUG_INFO_NONE \ -e DEBUG_INFO \ -e DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT make oldconfig
-
Compile the kernel.
# Choose a number of parallel processes based on the number of # processors in your CPU. make -j $(nproc)
-
Make initramfs. In this example we'll use
~/src/linux/my_test_binary
as the "init" process. If you want to boot a full system then it will be more complicated!cat << EOF > initramfs dir /dev 755 0 0 nod /dev/console 644 0 0 c 5 1 nod /dev/loop0 644 0 0 b 7 0 dir /bin 755 1000 1000 dir /proc 755 0 0 dir /sys 755 0 0 dir /mnt 755 0 0 file /init my_test_binary 755 0 0 EOF ./usr/gen_initramfs.sh initramfs | gzip -9 > cpio
-
Start QEMU. This will wait for you to attach GDB in the next step. qemu-system-x86_64 -kernel ~/src/linux/arch/x86_64/boot/bzImage
-initrd /boot/initrd.img-6.8.0-51-generic
-append "console=ttyS0 nokaslr"
-s -S -nographic -
In another terminal, start GDB.
cd ~/src/linux gdb ./vmlinux
-
In GDB, attach to the kernel. Happy debugging!
target remote :1234 # You can set breakpoints hb load_elf_binary continue
https://kernelnewbies.org/KernelBuild https://www.youtube.com/watch?v=2VcA5Wj7IvU https://nickdesaulniers.github.io/blog/2018/10/24/booting-a-custom-linux-kernel-in-qemu-and-debugging-it-with-gdb/ https://bmeneg.com/post/kernel-debugging-with-qemu/ https://trac.gateworks.com/wiki/linux/initramfs