Linux on doomacracy #
A no-MMU Linux 6.8 (cnlohr's mini-rv32ima fork) with busybox in an initramfs, configured for the DE1's 8 MB of SDRAM.
Build (on a Linux machine) #
cd linux
nix-build fhs.nix -o br-fhs # NixOS only: a normal /usr layout for buildroot
./br-fhs/bin/br-fhs -c ./build.sh
The first build makes a cross toolchain and takes about an hour on two
cores. Copy work/buildroot/output/images/Image to build/linux-Image.
Run in the emulator #
make linux-emu # 8 MB, the board's real size
Changes from cnlohr's configs #
CONFIG_RISCV_MISALIGNED=y: our CPU traps on misaligned loads and stores (cnlohr's emulator quietly handles them), so the kernel has to fix them up.- busybox:
FEATURE_PREFER_APPLETSandFEATURE_SH_STANDALONE, so hush runs simple applets in-process;viturned on; a few applets dropped (unzip, top, tree, lsof, checksums, xxd, and login/getty, which pulled in 83 KB of password code nothing here uses). No-MMU loads a private copy of busybox for every process, rounded up to a power of two, so its load size (text + data + bss + stack, fromflthdr) has to stay under 512 KB; it is 430 KB. patches/uclibc/0001-riscv32-no-64bit-syscall-arg-alignment.patch: uClibc padded 64-bit syscall arguments ARM-style on riscv32, softruncatereceived a length of 0 andviemptied every file it saved.overlay/etc/inittab: a respawning root shell on the serial console and one on the screen (tty1).- Framebuffer console:
FB_SIMPLE,FRAMEBUFFER_CONSOLE,FONT_6x8. - Keyboard:
SERIO_ALTERA_PS2,KEYBOARD_ATKBD, and the PLIC driver. patches/linux/0001-altera_ps2-receive-only.patch: the board's PS/2 port only receives, so the driver registers no write function;atkbdthen skips probing the keyboard and treats it as plain set 2. The patch directory is listed after cnlohr's own (board/qemu/riscv32-virt/nommu/ patches), which carries the rv32 no-MMU support; replacing it instead of adding to it builds a kernel whosewait4returns ENOSYS.- The kernel's built-in device tree is not used;
tools/gen_dts.pywrites it.
doomfetch #
doomfetch/doomfetch.c is a small neofetch, compiled into the image by
post-build.sh and run from /etc/profile when a shell starts. It is C on
purpose: every process here loads its own copy of its program, so a 64 KB
binary is far cheaper than a script that runs busybox (430 KB) a dozen
times. For the same reason a pipe of two external busybox commands can run
out of memory; prefer shell builtins where you can.
Programs of your own are built the same way: the buildroot cross gcc with
-fPIC -Wl,-elf2flt="-r -s STACK", and delete the .gdb file elf2flt
leaves next to the binary.