log

the nix shell:

{ pkgs ? import <nixpkgs> {} }:
 
let
 
 
linux = (pkgs.linux.override { stdenv = pkgs.llvmPackages_latest.stdenv; }).overrideAttrs (prev: { nativeBuildInputs = prev.nativeBuildInputs or [] ++ [pkgs.ncurses]; });
 
in linux

(nixpkgs/917fec990948658ef1ccd07cef2a1ef060786846)

i got the source by running unpackPhase.

then make LLVM=1 defconfig

and make with the makeflags which the nix buildPhase prints (Pasted image 20260710224909.png). (removed the last bit to have only bzImage and vmlinux as the target, not modules)

YESSS. after python ./scripts/clang-tools/gen_compile_commands.py and

{
    "load_direnv":"direct",
    "lsp": {
      "clangd": {
        "binary": {
          "arguments": [
            "--compile-commands-dir=.",
            "--background-index",
            "--clang-tidy",
            "--completion-style=detailed",
            "--header-insertion=never"
          ]
        }
      }
    }

}

in zed (editor)‘s project settings… we have working Intellisence

enabled the 3 debug config options CONFIG_DEBUG_INFO=y CONFIG_DEBUG_KERNEL=y CONFIG_GDB_SCRIPTS=y and smth about automatic dwarf version. with make menuconfig

  • ./vmlinux: the full kernel as an ELF with debug symbols. however not bootable. as compressed data inside the bzImage

    • does not contain the efi_stub_entry symbol (that is before decompression, it then calls decompress_kernel)
  • ./arch/x86/boot/setup.elf: the setup code. but also no efi_stub_entry as this is only the Real Mode part of the setup code… which is completely not in use when using efi…

  • ./arch/x86/boot/compressed/vmlinux: the whole decompressor stuff (runs in Protected Mode i think, where we are when we get run by the efi)

    • has efi_stub_entry … yay
  • next problem: the efi does ASLR = Address Space Layout Randomisation. meaning our binary will be placed ANYWHERE in the address space. (so any breakpoints/source mappings just won’t work where stuff is.)

    • also bzImage is completely stripped…
  • so i added a spinlock: Pasted image 20260710231214.png (so we are stuck there before any uncompressing and start_kernel())

    • you can then do process interrupt inside lldb to “break” there. set thewait_for_lldb to 0 manually (after breakpoints and stuff works) . after which you will continue like normal

(qemu cmdline in makefile at the bottom, does gdb debug listener on localhost:1234) (and (lldb) gdb-remote localhost:1234 of course)

  • with (lldb) dis -s $rip-34 -c 20 i was able to see that pause instruction.

  • no debug symbols/source maps are working. we need to somehow tell the debugger that ./arch/x86/boot/compressed/vmlinux is the executable we “are running” and at what offset it got loaded by efi’s aslr

  • the addr from that pause instruction in the running system is eg 0x780fb15e (from the dis command)

  • with objdump -d arch/x86/boot/compressed/vmlinux | less and then searching for efi_stub_entry i could find the same pause instruction at 0x3a1715e in the file.

  • rech 0x780fb15e - 0x3a1715e gives eg: 1953382400

~ ❯❯❯ command -V rech
rech is a function
rech ()
{
    python3 -c "print($@)"
}
~ ❯❯❯

(“rechnen” is german for calculate)

with

  • (lldb) target create arch/x86/boot/compressed/vmlinux

  • (lldb) target modules load --file /arch/x86/boot/compressed/vmlinux -s 0x1953382400 we should have correctly aligned the debug symbols. BUT IT JUST NOT WORK

  • rech 'hex(0x780fb15e - 0x3a1715e)'

    • yup. big big F.
    • took me i think 2h to realize
    • (did think before) how lucky we got… that there are just no letters in our address… xD
  • now we do se the right symbols in the dissasembly: Pasted image 20260710233644.png

    • but still just no sources via sources info, l

there should be a CompileUnit… but there just is not…

(lldb) image lookup -n efi_stub_entry
1 match found in /root/work/c2vi/acern-fixing/nix-linux/arch/x86/boot/compressed/vmlinux:
        Address: vmlinux[0x0000000003a17109] (vmlinux.PT_LOAD[0]..text + 35801)
        Summary: vmlinux`efi_stub_entry
  • so we mapped the symbols of arch/x86/boot/compressed/vmlinux correctly into our proccess… but just seem to have no debug info????

    • but how can that be… the file command clearly shows “with debug_info”
  • a peak into the .debug_line section using readelf --debug-dump=decodedline arch/x86/boot/compressed/vmlinux | less shows that all entries there are for one file arch/x86/boot/startup/efi-mixed.S

    • so file says “with debug_info” as that section exists… but it just has no useful data.
  • the efi_stub and decompression code needs to be PIC. there is a check in drivers/firmware/efi/libstub/Makefile to make sure there are no absolute adresses in any objfiles in question.

    • as debug_info would have absolute addresses (which are not actually uses for running…) that check would not work… so debug info is stripped. (also to safe space in bzImage)
    • there is a patch on the LKML = Linux Kernel Mailing List about keeping the debug symbols (https://lists.infradead.org/pipermail/linux-arm-kernel/2016-October/462131.html)
    • i think however this patch is applied. SO WHY STILL NO SYMBOLS.
    • well the patch talks about arm64 and the top of said Makefile # non-x86 reuses KBUILD_CFLAGS, x86 does not
      • so for x86 we use special KBUILD_CFLAGS for the efi_stub defined in this Makefile. these flags don’t handle CONFIG_DEBUG_INFO and never add a -g. so there were never any debug symbols emitted for any efi_stub things.
  • YESSSS … after adding that -g… it all works … Pasted image 20260710223729.png

the makefile:


.PHONY: run

#KERNEL=/boot/vmlinuz-6.12.88+deb13-amd64
#KERNEL=./linux/arch/x86/boot/bzImage
KERNEL=./nix-linux/arch/x86/boot/bzImage

default: clean build

clean:
	rm -rf ./initrd

build:
	# initrd
	mkdir -p ./initrd
	cp -r ./nix-busybox/* ./initrd
	ln -fs ./bin/sh ./initrd/init
	find ./initrd | cpio -o -H newc | gzip -9 > ../initrd.img
	
	# efi file
	# useless as i found out bzImage is already an efi file
	# ukify build --linux=${KERNEL} --initrd=./initrd.img --cmdline="debug log_buf_len=10M console=ttyS0,115200 earlyprintk=serial,ttyS0,115200 earlycon=uart8250,io,0x3f8,115200" --output=./linux.efi --uname="6.18.16"

	# copy to VM dir
	cp ${KERNEL} ./boot/EFI/BOOT/BOOTX64.EFI

run: build
	qemu-system-x86_64 -nographic \
		-drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE_4M.fd \
		-drive file=fat:rw:./boot,format=raw \
		-net none \
		-serial mon:stdio \
		-m 2G -s

 		#-kernel ./linux/linux-6.18.16/build/vmlinux \
 		#-initrd ./initrd.img \
 		#-append "debug log_buf_len=10M console=ttyS0,115200 earlyprintk=serial,ttyS0,115200 earlycon=uart8250,io,0x3f8,115200" \