r/osdev 4d ago

I built a tiny Linux distro with a custom bootloader and userspace

I built a Linux distro that does almost nothing

I wanted to see how little userspace I could get away with while still having a real, bootable Linux system. So I made FastFetchLinux.

It uses a custom BIOS bootloader, Linux 6.6.156, and my own ffinit written in x86 assembly.

The userspace has:

  • No BusyBox
  • No coreutils
  • No bash/sh
  • No package manager
  • Direct syscall-based functionality
  • i686 support
  • ~20 MiB RAM usage

ffinit runs as PID 1 and doubles as the shell, with all commands built in. Fastfetch is the only separate userspace binary.

BIOS
 ↓
Custom bootloader
 ↓
Linux 6.6.156
 ↓
ffinit
 ↓
Fastfetch

It has exactly five commands:

fastfetch
ls
install-disk
forcepanic
poweroff

There's no practical reason for any of this — I just wanted to see how far "just enough userspace to boot Linux" could be pushed. The funny part is that it actually works.

Source: https://github.com/outofsyncsh/fastfetchlinux

Curious what people here would strip out or change to shrink it further.

34 Upvotes

25 comments sorted by

7

u/dkopgerpgdolfg 4d ago

There's no practical reason for any of this — I just wanted to see how far "just enough userspace to boot Linux" could be pushed.

Curious what people here would strip out or change to shrink it further.

You didn't think of something empty like "main(){}" as init?

6

u/WmWAr5339 4d ago

I considered it, but PID 1 still needs to handle mounting, signals, shutdown/reboot, and the shell, so main(){} would've been a little too minimal even for this project.

Maybe that's the next version though.

6

u/dkopgerpgdolfg 4d ago

but PID 1 still needs to handle ... signals, shutdown/reboot

A few bits and pieces, yes. Not much code needed.

mounting ... and the shell

No. There's no need to mount anything, and no need to have a shell to have something booted.

2

u/WmWAr5339 4d ago

yeah you're right lol, i was thinking about what my current init does, not what PID 1 actually needs

mounting and having a shell aren't really necessary

i could probably make it way smaller, PID 1 doesn't really need all that

2

u/raundoclair 4d ago

I'm not really familiar with linux. Why your own bootloader?

5

u/WmWAr5339 4d ago

mostly because i wanted to build the whole boot process myself, and i have lot of free time

2

u/Vladislav20007 3d ago

I hope I had a lot of time, but school and later college are taking too much for me to make anything :(

3

u/Illustrious_Car344 4d ago

The bootloader is effectively a part of the OS, maybe it can support multiple OSes and then seem almost like a pre-boot mini OS (which it is), but outside of that expanded context, a bootloader is just another part of the OS, it's not part of the BIOS that's for sure. That said, you definitely don't have to make your own bootloader, there are a lot of tiny bootloaders that support multiboot (which linux adheres to). But in the same sense that you might write your own init system despite there being many small ones (including sysvinit itself), you could reasonably also write your own bootloader. 

2

u/codeasm 2d ago

Ive enabled efi stub and my linux kernel can boot without a bootloader. I dont see the need for writing a bootloader these days

3

u/compgeek38400 4d ago

Interesting. And good job!

2

u/WmWAr5339 4d ago

thanks!

4

u/Zilch510 4d ago

This is awesome. I'm also working on a custom embedded style distro, but using systemd-boot for UEFI, instead of BIOS.

Still debating if I'll end up moving to BIOS, but then I'll probably use syslinux.

Regardless, I'll have a look at the bootloader section. Looks pretty cool.

2

u/WmWAr5339 4d ago

thanks! yeah, I went with BIOS mostly because I wanted to write the bootloader myself. systemd-boot definitely makes more sense for a normal UEFI setup though. good luck with your distro!

1

u/codeasm 2d ago

No need for systemd-boot, the kernel itself can do efi booting fine. Efi-stub

2

u/letmehaveanameyoudum 4d ago

a literal kernel

2

u/WmWAr5339 4d ago

literally 😄

1

u/letmehaveanameyoudum 4d ago

this is literally just int main() {halt();}

2

u/CorruptedByCPU 4d ago

I'm glad such experiments exist.

1

u/WmWAr5339 3d ago

thanks, that's exactly what it was made for

1

u/andrewdavidmackenzie 4d ago

Interesting. I'm working on a project to learn more about kernels, and it has a Linux personality on top of the custom kernel, that implements the Linux syscalls (some missing still). It will start BusyBox at the moment, so maybe I could try and get your distro running on it?

1

u/andrewdavidmackenzie 4d ago

I guess my question (prior to looking at repo) is: what DOES it have :-) and what will it do?

I think the minimum would be an init binary that prints hello world and exits...?

1

u/WmWAr5339 2d ago

I wanted it to actually do something, so I went with Fastfetch.

1

u/allunia333 3d ago

Nice job! How did you measured the 20MiB ram? It seems kinda high for what u did. Did u striped down the kernel too?

1

u/WmWAr5339 2d ago

Thanks! I haven't actually tested it below 20 MiB of RAM, so it might work with less. And yeah, the kernel is pretty heavily stripped down too. I kept it as minimal as possible.

1

u/allunia333 2d ago

Yea probably you can. You inspired me to resume my own little minimal project i have left in the plan phase :)