I need a i386 kernel.
Long time ago everything changed to 64bits for the most common architectures like x86 and arm.
We just don't remember i386 but sometimes we need to build an old 32bits .
What I need to build an i386 (how I did it)
- The toolchain for the i386
- Tell the kernel build system that we want an architecture different from default (which now is 64bits)
That's it , in fact the linux kernel build systems is used to build several different architectures so this exercise is nothing for this beast.
I'll add the commands for my OpenSuse , for other distros it should be very similar
sudo zypper in cross-i386-binutils
export ARCH=i386 ;time make LLVM=1 -j$(nproc) all CC='ccache clang'
You can check that the binary is one of 32bits architecture with the file command
$file arch/x86/boot/bzImage
arch/x86/boot/bzImage: Linux kernel x86 boot executable, bzImage, version 6.16.0-rc1-dirty (jg@dell) #28 SMP PREEMPT_DYNAMIC Sat Oct 4 18:23:47 CEST 2025, RO-rootFS, Normal VGA, setup size 512*39, syssize 0xaa820, jump 0x26c 0x8cd88ec0fc8cd239 instruction, protocol 2.15, from protected-mode code at offset 0x94 0xa99cd0 bytes gzip compressed, relocatable, handover offset 0xaa1ad8, 32-bit EFI handoff entry point, max cmdline size 2047, init_size 0x1791000
ok,ok ... but now what I do with that ... let's use qemu for i386 and let see the options used
The cpu will use and old 32bits ... do you remember the core2duo just before the 64bits ;-) ?
The memory just 2G for our testNumber of cpu's , 1 for this test , you can try more ... maybe 2
The kernel , the path to our ,still hot, compiled kernel
The append options, in this case I use the syzbot/syzkaller way (raw disk,etc)
qemu-system-i386 \
-cpu core2duo \
-m 2G \
-smp 1 \
-kernel "arch/x86/boot/bzImage" \
-drive file="./my_img.img",format=raw \
-append "root=/dev/sda rw init=/sbin/init console=tty0 console=ttyS0 rootfstype=ext4 rootwait nomodeset " \
-vga std \
-net user,host=10.0.2.10,hostfwd=tcp::10021-:22 \
-net nic,model=e1000 \
-enable-kvm Yeah, let's go but arrrggghhhhhhh .... the kernel boots but when is the time for the init process we have a "beautiful" kernel panic
[ 1.166891] Run /sbin/init as init process
[ 1.169495] Starting init: /sbin/init exists but couldn't execute it (error -8)
[ 1.169807] Run /etc/init as init process
[ 1.170183] Run /bin/init as init process
[ 1.171264] Run /bin/sh as init process
[ 1.171740] Starting init: /bin/sh exists but couldn't execute it (error -8)
[ 1.172088] Kernel panic - not syncing: No working init
What happened?. We have everything in 32bits : the kernel, quemu i386 version , cpu parameter for qemu ...
Yes, but ...
The init (sh in this case) process in our image is a 64bits binary , that's the mean of the error -8.
So what can we do?
As we're working with the syzbot/syzkaller tools for create out image we can ask to create a 32bits one, use the one create to the previous qemu command and you're done.
tools/create-image.sh --distribution bookworm --arch i386
Comments
Post a Comment