-
Notifications
You must be signed in to change notification settings - Fork 31
Kernel
Clone the mainline kernel: git clone https://github.com/torvalds/linux.git --single-branch
(usually faster than https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git)
Install packages needed for building a kernel.
sudo apt install libncurses-dev flex bison openssl libssl-dev \
dkms libelf-dev libudev-dev libpci-dev \
libiberty-dev autoconf
make O=/tmp/linux/x86_64 ARCH=x86_64 -j60 defconfig
make O=/tmp/linux/x86_64 ARCH=x86_64 -j60 bzImage modules
scripts/clang-tools/gen_compile_commands.py -d /tmp/linux/x86_64 # For ccls
To build the kernel with Clang, lld, and LLVM binary utilities, build the tools in a llvm-project build directory.
ninja -C /tmp/Rel clang lld llvm-{ar,nm,objcopy,objdump,ranlib,readelf,strings,strip}
PATH=/tmp/Rel/bin:$PATH make O=/tmp/linux/x86_64-llvm ARCH=x86_64 LLVM=1 -j60 defconfig all
Clone https://github.com/ClangBuiltLinux/boot-utils
~/Dev/ClangBuiltLinux/boot-utils/boot-qemu.py -a x86_64 -k /tmp/linux/x86_64-llvm
PATH=/tmp/out/custom1:$PATH make O=/tmp/linux/perf ARCH=x86_64 -j60 -C tools/perf EXTRA_CFLAGS='-O0 -g' CC='clang -w' DEBUG=1
Note: don't use a kernel build directory.
https://www.kernel.org/doc/Documentation/kbuild/headers_install.txt
make ARCH=i386 INSTALL_HDR_PATH="$pkgdir/usr" headers_install
Linux Kernel Functional Testing: https://lkft.linaro.org/
Use dracut to build an initramfs.
Use lsinitramfs path/to/initramfs
(from initramfs-tools) to list files in an initramfs.
scripts/config --file /tmp/linux/x86_64/.config -d RANDOMIZE_BASE # or specify noaslr in the kernel command line
scripts/config --file /tmp/linux/x86_64/.config -d CPU_SRSO -d CPU_UNRET_ENTRY # srso_return_thunk & retbleed_return_thunk make debugging hard
scripts/config --file /tmp/linux/x86_64/.config -e DEBUG_INFO_DWARF5 -e DEBUG_INFO_SPLIT -e GDB_SCRIPTS -e KGDB
scripts/config --file /tmp/linux/x86_64/.config -e TRANSPARENT_HUGEPAGE -e TRANSPARENT_HUGEPAGE_MADVISE -e READ_ONLY_THP_FOR_FS
make O=/tmp/linux/x86_64 -j60 scripts_gdb
Set GDB add-auto-load-safe-path
cgdb -ex 'tar rem :1234' /tmp/linux/x86_64/vmlinux
(gdb) hb start_kernel
(gdb) c
Breakpoints do not work reliably. Consider adding __attribute__((optimize("O0")))
(GCC) or __attribute__((optnone))
(Clang) to interesting functions.
In the kernel source directory, run
make O=/tmp/linux/arm64 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j60 defconfig all
Then create an Alpine aarch64 image following https://hackmd.io/@starnight/Run_Alpine_on_QEMU_aarch64_Virtual_Machine
wget https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/aarch64/netboot/vmlinuz-lts https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/aarch64/netboot/config-lts
qemu-img create -f qcow2 alpine-aarch64.qcow2 16G
qemu-system-aarch64 -smp 2 -M virt -cpu cortex-a57 -m 1G -nographic \
-kernel vmlinuz-lts -initrd initramfs-lts \
--append "console=ttyAMA0 ip=dhcp alpine_repo=http://dl-cdn.alpinelinux.org/alpine/latest-stable/main/ modloop=http://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/aarch64/netboot/modloop-lts" \
-hda alpine-aarch64.qcow2 \
-netdev user,id=unet -device virtio-net-device,netdev=unet -net user
On the guest,
# user: root, no password
setup-alpine # install to vda
On the host,
sudo modprobe nbd max_part=8
sudo qemu-nbd -c /dev/nbd0 alpine-aarch64.qcow2
sudo mount /dev/nbd0p1 /mnt/
cp /mnt/vmlinuz-lts ./vmlinuz-lts.img
sudo chmod o+r /mnt/initramfs-lts
cp /mnt/initramfs-lts ./initramfs-lts.img
sudo umount /dev/nbd0p1
sudo qemu-nbd -d /dev/nbd0
qemu-system-aarch64 -smp 2 -M virt -cpu cortex-a57 -m 1G -nographic \
-kernel vmlinuz-lts.img -initrd initramfs-lts.img \
--append "console=ttyAMA0 root=/dev/vda3 rw rootfstype=ext4" \
-hda alpine-aarch64.qcow2 \
-device e1000,netdev=net0 \
-net nic -netdev user,hostfwd=tcp:127.0.0.1:2222-:22,id=net0
To debug a just built kernel, replace -kernel vmlinuz-lts.img
with -kernel /tmp/linux/arm64/arch/arm64/boot/Image
and add -s -S
.
Then, in another terminal, run
gdb-multiarch /tmp/linux/arm64/vmlinux
(gdb) tar rem :1234
(gdb) hb start_kernel
(gdb) c
sudo apt install qemu-system-misc
wget https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/s390x/netboot/vmlinuz-lts https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/s390x/netboot/initramfs-lts
qemu-img create -f qcow2 alpine-s390x.qcow2 6G
qemu-system-s390x -M s390-ccw-virtio -m 1024 -smp 2 -nographic -hda alpine-s390x.qcow2 -kernel vmlinuz-lts -initrd initramfs-lts \
-append "alpine_repo=https://dl-cdn.alpinelinux.org/alpine/latest-stable/main modloop=https://dl-cdn.alpinelinux.org/alpine/v3.19/releases/s390x/netboot/modloop-lts"
Run setup-alpine
. After installation, run:
sudo modprobe nbd max_part=8
sudo qemu-nbd -c /dev/nbd0 alpine-s390x.qcow2
sudo mount /dev/nbd0p1 /mnt/
cp /mnt/vmlinuz-lts ./vmlinuz-lts.img
sudo chmod o+r /mnt/initramfs-lts
cp /mnt/initramfs-lts ./initramfs-lts.img
sudo umount /dev/nbd0p1
sudo qemu-nbd -d /dev/nbd0
qemu-system-s390x -smp 2 -M s390-ccw-virtio -m 1G -nographic -kernel vmlinuz-lts.img -initrd initramfs-lts.img \
--append "console=ttyS0 root=/dev/vda3 rootfstype=ext4 rw" \
-drive file=alpine-s390x.qcow2,if=virtio \
-fsdev local,id=t,path=/tmp/t,security_model=none -device virtio-9p-pci,fsdev=t,mount_tag=t
Download a standard
ISO from https://dl-cdn.alpinelinux.org/alpine/latest-stable/releases/x86_64/.
qemu-img create -f qcow2 alpine-x86_64.qcow2 8G
qemu-system-x86_64 -enable-kvm -smp 2 -cpu host -m 1G -nographic \
-nic user -boot d -cdrom alpine-standard-3.19.0-x86_64.iso -hda alpine-x86_64.qcow2
Run setup-alpine
. After installation, run:
sudo modprobe nbd max_part=8
sudo qemu-nbd -c /dev/nbd0 alpine-x86_64.qcow2
sudo mount /dev/nbd0p1 /mnt/
cp /mnt/vmlinuz-lts ./vmlinuz-lts.img
sudo chmod o+r /mnt/initramfs-lts
cp /mnt/initramfs-lts ./initramfs-lts.img
sudo umount /dev/nbd0p1
sudo qemu-nbd -d /dev/nbd0
qemu-system-x86_64 -enable-kvm -smp 2 -cpu host -m 1G -nographic -kernel vmlinuz-lts.img -initrd initramfs-lts.img \
--append "console=ttyS0 root=/dev/vda3 rootfstype=ext4 rw" \
-drive file=alpine-x86_64.qcow2,if=virtio \
-device e1000,netdev=net0 -net nic -netdev user,hostfwd=tcp:127.0.0.1:2222-:22,id=net0 \
-fsdev local,id=t,path=/tmp/t,security_model=none -device virtio-9p-pci,fsdev=t,mount_tag=t
On the guest,
mkdir /tmp/t && mount -t 9p t /tmp/t -o trans=virtio,msize=$((5*1024*1024))
To debug a just built kernel, replace -kernel vmlinuz-lts.img
with -kernel /tmp/linux/x86_64/arch/arm64/boot/Image
and add -s -S
.
Then, in another terminal, run
gdb-multiarch /tmp/linux/arm64/vmlinux
(gdb) tar rem :1234
(gdb) hb start_kernel
(gdb) c
sudo sshfs -p 2222 -o allow_other root@localhost:/ /mnt/fedora # Add `PermitRootLogin yes` to guest /etc/ssh/sshd_config
make -j$(nproc) O=/tmp/linux/x86_64 INSTALL_PATH=/mnt/fedora/boot install
make -j$(nproc) O=/tmp/linux/x86_64 INSTALL_MOD_PATH=/mnt/fedora modules_install
In the guest, create a new entry under /boot/loader/entries/
based on an existing one. Reuse initramfs but update vmlinuz.
vim /etc/default/grub # Add nokaslr to GRUB_CMDLINE_LINUX
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo grubby --set-default /boot/vmlinuz-6.* # Select the new vmlinuz
(grubby doc)
(If the guest is Debian, do sudo update-initramfs -k all -c; sudo update-grub
)
Alternatively, append -kernel /tmp/linux/x86_64/arch/x86/boot/bzImage -initrd path/to/initramfs -append 'root=/dev/mapper/fedora_ju1f2mb4--trk--14--1-root ro rd.lvm.lv=fedora_ju1f2mb4-trk-14-1/root rhgb quiet nokaslr'
to the qemu command line.
Append -nographic -append 'tty=consoleS0 ...
to avoid video output (a SDL window).
(The virtual serial port and the QEMU monitor are multiplexed onto stdio.)
qemu-system-x86_64 -enable-kvm -nographic -m 16384 -smp 8 -cpu host -kernel /tmp/linux/x86_64/arch/x86/boot/bzImage -initrd /tmp/c/initramfs-5.19.7-300.fc37.x86_64.img -append 'console=ttyS0 root=/dev/mapper/fedora_ju1f2mb4--trk--14--1-root ro rd.lvm.lv=fedora_ju1f2mb4-trk-14-1/root rhgb quiet nokaslr' -drive file=fedora.img,if=virtio -net nic,model=virtio -nic user,hostfwd=tcp::2222-:22
Fedora uses /dev/zram0
as a swap device by default (https://fedoraproject.org/wiki/Changes/SwapOnZRAM). See man zranctl
for other distributions.
Run cat /proc/swaps
(or swapon --show
) to list swap devices.
https://lkml.org/lkml/2018/5/2/74 from Ingo Molnar:
First I make sure that cpufreq is set to 'performance':
for ((cpu=0; cpu<120; cpu++)); do
G=/sys/devices/system/cpu/cpu$cpu/cpufreq/scaling_governor
[ -f $G ] && echo performance > $G
done
Then I copy a kernel tree to /tmp (ramfs) as root:
cd /tmp
rm -rf linux
git clone ~/linux linux
cd linux
make defconfig >/dev/null
... and then we can build the kernel in such a loop (as root again):
perf stat --repeat 10 --null --pre '\
cp -a kernel ../kernel.copy.$(date +%s); \
rm -rf *; \
git checkout .; \
echo 1 > /proc/sys/vm/drop_caches; \
find ../kernel* -type f | xargs cat >/dev/null; \
make -j kernel >/dev/null; \
make clean >/dev/null 2>&1; \
sync '\
\
make -j16 >/dev/null