Grumpy Linux

Rough Ideas

I don't think anyone reading will have known this about me, but way back in the day (~14 years ago now) I started and maintained a Linux distribution. Don't worry, there's no trace of it on the internet anymore. It's been something I've toyed with on and off since though, and Grumpy Linux is my latest toy, one which is weird enough to share with the world soon.

Grumpy Linux, at least the Lite form, is as far as I can tell the first Linux distro to try to productively support floppies in over a decade as more than a curiosity. At the moment it consists of two of them: a boot floppy and a busybox floppy. Unfortunately I can't do any better than that: both Linux and even small busybox configurations are over a MB each these days. Due to the size constraints, you'll have to do your own configuration on Linux: you simply can't afford to build a generic kernel. When you need to include the USB stack, since my floppy drive is USB. This one has almost exactly what I need to boot off of a floppy on my T41 and nothing else. The good news is that in my kernel budget I was able to squeeze in loadable module support, so theoretically you can load up a floppy with kernel modules and get all of your hardware working.

More generally though, Grumpy Linux is a ports collection, almost a meta-distribution. I'm focusing on Lite right now because it's the most interesting challenge, but I'm hoping to end up with a usable, experimental little distro. For now it requires what I'd consider an expert user.

Using Grumpy


Right now you can get the ports tree from my sourcehut repository here. You'll need this, a build environment, and specifically a BSD make to run the ports tree. For some ports, most notably the ones targeting Grumpy Lite, you'll need musl installed and its wrapper musl-gcc. If you have a native musl install, just edit the references to musl-gcc out when relevant. If you're experimenting, you'll probably want to not clobber your host install, so mkdir a place for your experimental system to live like ~/grumpy.

Building Packages

At its most basic, installing a package is just a matter of make install. That'll fetch it, compile it, build the dummy package in the objs folder, build the manifest, and then actually install into the root. Remember to set the $ROOT variable when building to your Grumpy directory. You can remove the package later with make remove. make update just performs a remove, then an install.

The full list of "normal" targets is as follows. These are all you should need to manually run:

Getting Into A System

There are a couple of fake convenience ports to help get you set up in a chroot environment: bootstrap and chroot. You can export ROOT and run make bootstrap to set up the directory tree. Next set up a userland. At time of writing you have 2 choices available for the userland: busybox or what I'm calling "suckless". Busybox comes in both busybox and busybox-lite flavors. The latter is super cut down and intended for floppies. Don't install both at once: grumpy has no concept of conflicting packages yet. bmake ROOT=~/grumpy should do fine for you. Then you'll be able to use the chroot pseudo-package to get in and poke around.

Writing Ports

Finally, you might want to package software on top of Grumpy. For the most part this just consists of copying an existing port and editing the Makefile to fit. If you're lucky, editing the variables might be all you need:

You'll need to choose a template which fits based on whether it's from a git repo or a normal tarball. After that you'll need to edit the build and copy targets to make sure that they make sense for your software. You may want to run make fetch and manually build first, to get a feel for the process. As time goes on more pre-defined targets will be added to the grumpy library to make this even easier. When those steps are complete, set up a dummy folder and run your build with $ROOT set to make sure it completes, then chroot in to make sure it runs.

Grumpy Lite Installation

Grumpy Lite strictly speaking isn't a Grumpy Linux, more a curiosity which uses its infrastructure. In particular I wouldn't expect to use the actual package management features if only because it'd be too hard to fit a full compiler and/or libc onto floppies, even tcc would be tight, though maybe a fun challenge.

Since space is too tight for things to be precompiled, there are a few manual steps involved in setting up Grumpy Lite (some of which I may automate later.) Before you start you're going to need:

The Boot Disk

We'll start by building the boot disk. Start out with a blank Grumpy root. Don't run bootstrap, just mkdir. Linux is already packaged for grumpy and its default config is my Lite config so you can immediately install it. The linux package also has a special config target, which will let you configure it before building. Just remember to copy your config out for later too. This should leave you with a ~1.2Mb bzImage, just barely small enough to fit with the other things we need. Unfortunately it's this big because I need to include USB and SCSI support to work with my floppy drive, expect it to be much smaller when my real drive comes in.

The only other thing which has to be compiled for the boot disk is pbr, my pico bootstrap utility. It's also packaged, naturally. Either edit the Makefile or pass in DISKROOT when building, though be careful to mind the quoting. DISKROOT has to be the device the kernel will assign to your floppy drive. Unfortunately I can't tell you what device that'll be, you may just have to experiment.

Next we build our initramfs. The initramfs package takes care of all of this for you, all you have to do is invoke make with ROOTDISK set to the device your kernel will see your floppy drive as. By default it sees it as sda because that's what it is on my box. On yours it'll probably be fd0 unless you're also using a USB floppy drive. It'll leave your initramfs at init.cpio

Finally we're ready to prepare our boot floppy. Insert it into your drive and format it as ext2 (format the whole drive, don't partition it.) You're going to install extlinux next. Mount the floppy drive and run syslinux --install [mountpoint] which will overwrite the bootloader and copy on the necessary files. Edit syslinux.cfg to match your system, something like this:

DEFAULT grumpy
LABEL grumpy
        LINUX vmlinuz
        APPEND root=/dev/sda initrd=/init.cpio ro

Copy vmlinuz and init.cpio from your fake grumpy root to the root of your boot disk and that should be all. Unmount it and make yourself a userland disk.

The Root Disk

First clear out your old grumpy install or make a new one. All you have to do is install either busybox-tiny or suckless-base. I recommend the latter, since it can fit more utilities. After installing, format your other floppy as ext2 in the same way and copy the bin and/or sbin (if it exists,) to the floppy. Go ahead and unmount, you're done.

Booting The Damned Thing

This is where all the gross manual interventions happen, but I'm hoping I'll have space to make pbr handle much of it later. Put in the boot disk and boot. When the text output stops then pbr and the initramfs should be in control; there will be some log messages but they may be buried under kernel logs. Swap your boot floppy for your root floppy and hit enter. If all has gone well, the root floppy will have been mounted and dropped you into a shell. You could use the system as it is right now, but my recommendation is to run /new-root/bin/cp -rf /new-root/* /ram/, which will copy the root disk to the ramdisk, then exec /ram/bin/sh to move to a shell onto the ramdisk, and finally exec /ram/bin/switch_root /ram /bin/sh which will finish the boot process, leaving you in the ramdisk. From there mkdir and mount sys, proc,and dev and you're all done.

Future Work

My main idea with Grumpy-Lite is going to center around what I'm calling "layers" in my mind. Floppies are slow and tiny, even hardware from the late 90's has the ram to store dozens of floppies. Rather than deal with that, I plan on making some tools for grumpy which more or less amount to "mount a floppy, copy its contents into the root ramdisk" which will let you build up a full system by just loading things into your ramdisk. At the moment this is a completely manual process though, hence the hassle.

But this page is ugly!