-
Notifications
You must be signed in to change notification settings - Fork 5
Description
During the Clang implementation of -fzero-call-used-regs
, @nathanchance came across an issue where a Clang-built kernel failed to boot. It was seen as a issue, but is probably more pernicious than we first thought.
Related to #84.
Steps to replicate (by @nathanchance).
We uses Fedora for ease of installation via the serial console. @nathanchance wrote a Python script to drive QEMU specifically for testing. The latest version can be found here:
With that, the setup command can be run to initially configure the machine.
cbl_vmm.py setup -i "https://download.fedoraproject.org/pub/fedora/linux/releases/36/Server/x86_64/iso/Fedora-Server-netinst-x86_64-36-1.5.iso" -n fedora
This downloads the .iso
file in to a vm
folder in the same folder as cbl_vmm.py
. Once it's finished downloading, QEMU should fire up, printing the full command it uses.
Next, you should see grub. Hit 'e
' to add console=ttyS0
to the linuxefi
line after quiet
then hit Ctrl-X
to boot.
After a bunch of text flies across the screen, you should be prompted to either use VNC or text mode for configuration. I usually use text mode
because it is a little simpler. The console might look a bit garbled, hitting r
then Enter
a few times should clear things up enough to see. In text mode, I customized the time zone and user creation sections but leave the installation source, software selection, and network configuration. Don't touch the root account. Instead create a user account that's the same as yours on the host and give it a password of some sort (i.e. don't just leave it blank).
The installation destination has to be run through but leave everything on the default. After the installation process finishes, the machine should reboot.
The script adds a forwarding rule for the virtual machine's SSH port (22
) to the host (8022
) so you should be able to log into the machine like:
ssh -p 8022 localhost
Once you are in, you'll need to do three things to make booting self compiled kernels through QEMU possible (as opposed to generating a kernel package and installing it within the machine).
-
Copy the contents of
/proc/cmdline
somewhere you can use later, aside from theBOOT_IMAGE
variable. -
Generate an
initramfs
and copy it out of the machine.Within the VM:
sudo bash -c "rm -f /tmp/initramfs.img && dracut --no-kernel /tmp/initramfs.img && chown $USER:$USER /tmp/initramfs.img"
Outside of the VM:
scp -P 8022 localhost:/tmp/initramfs.img /tmp
-
Get a list of the currently running kernel modules (it is easier to generate outside of the VM):
ssh -p 8022 localhost lsmod >/tmp/lsmod.txt
Once those are done, exit QEMU and go into your kernel source.
First, we'll use Fedora's kernel configuration as a base:
curl -LSso .config https://src.fedoraproject.org/rpms/kernel/raw/rawhide/f/kernel-x86_64-fedora.config
Next, we're going to build all the modules that we need to boot the VM into the kernel image with the 'localyesconfig
' target (I have not found a clean way to generate a Fedora initramfs
with modules) then run 'menuconfig
' to turn on CONFIG_ZERO_CALL_USED_REGS
then finally build the bzImage
. The 'localyesconfig
' step might prompt you for some values, I usually just hit <Enter>
to choose the defaults.
make -skj"$(nproc)" LLVM=1 LSMOD=/tmp/lsmod.txt olddefconfig localyesconfig menuconfig bzImage
Once the image is done, you should be able to fire up the VM with the pieces we generated earlier (I usually do this in a different terminal/tmux tab):
cbl_vmm.py run -C "<cmdline_string_from_earlier>" -i /tmp/initramfs.img -k <path_to_kernel_src> -n fedora
That hangs for me with CONFIG_ZERO_CALL_USED_REGS=y
. If it is disabled, the machine fully boots.
The script supports -g
, which will pass -s -S
to QEMU for easier debugging with GDB, you'll just need to make sure to enable CONFIG_GDB_SCRIPTS
during the menuconfig
stage and add the scripts_gdb
target to your make command (or just use all
in lieu of bzImage
).