Running 2.6.27 kernel, udev, Slackware 12.1 with 8 MiB RAM

Last modified: Sun Jun 2 10:53:31 EDT 2019

Back in the early days, I ran Linux 1.X on a 33 MHz 386DX with only 2 MiB RAM.  Even X11 ran, albeit swappily.  So in 2008-10, when I salvaged a 486 with only 8 MiB RAM, I thought it reasonable to attempt to install a current Linux kernel and Slackware distribution on it.

It was not easy.

  1. Although the initrd used by Slackware's install environment was over 32 MiB, it didn't matter because the 486 would not boot from a CD, no way, nohow, regardless.  Instead, I ran the install on a different PC and moved the hard drives over to the 486.
  2. Memory was so tight that I had trouble getting as far as swapon without running out.  Enabling swap in early userspace didn't seem to help.  Apparently there are limits to what can be swapped out, and loading an initrd did more harm than good.  I cut the kernel down to bare bones to get it to boot, then gradually added back the most important things.
  3. Much thrashing was caused by three bloaty processes that Slackware launches on every boot:  gtk-query-immodules-2.0 ("Input method module registration utility"), fc-cache ("build font information cache files") and update-mime-database ("a program to build the Shared MIME-Info database cache").  All of these appear to be cache updaters.  I let them finish once and then commented them out of rc.M.
  4. The biggest challenge was udev.  You can go far in life without udev, but I did eventually get it to run using the workaround detailed below.


Udev kills you in two ways.  First, it needs a lot of memory just to run.  Slackware doesn't normally enable swap until after udev is started; that's a problem.  Second, rc.udev mounts a tmpfs over /dev, and that also runs out of memory.  I thought a tmpfs would go into swap if it got too big, but it just wouldn't work no matter what size I gave it.

Enabling swap early to fix the first problem is easy enough.  The fix for the second problem is a bit more esoteric.  Instead of mounting tmpfs over /dev, I mounted an actual physical partition on the hard drive.

Following is the hack to rc.udev that makes it work, using /dev/sda1 as the surrogate tmpfs:

*** /etc/rc.d/rc.udev   2008-10-12 20:51:11.000000000 -0400
--- rc.udev     2008-10-12 20:50:57.649395503 -0400
*** 73,79 ****
                  # Mount tmpfs on $UDEV_ROOT:
                  # the -n is because we don't want $UDEV_ROOT umounted when
                  # someone (rc.[06]) calls umount -a
!                 mount -n -o mode=0755 -t tmpfs tmpfs $UDEV_ROOT 
                  # Remount pts:
                  mkdir $UDEV_ROOT/pts 2> /dev/null
--- 73,86 ----
                  # Mount tmpfs on $UDEV_ROOT:
                  # the -n is because we don't want $UDEV_ROOT umounted when
                  # someone (rc.[06]) calls umount -a
!                 echo "Executing low memory udev workaround"
!                 echo "- Activating swap early"
!                 /sbin/swapon -a
!                 echo "- Wiping physical /dev partition"
!                 mke2fs -m 0 /dev/sda1 >& /dev/null
!                 echo "- Mounting physical /dev partition"
!                 mount -n -t ext2 /dev/sda1 $UDEV_ROOT
!                 echo "Low memory udev workaround completed."
                  # Remount pts:
                  mkdir $UDEV_ROOT/pts 2> /dev/null


It sucks, of course.  The 486 boots really fast if I exclude significant kernel functions and disable stuff, but I want all the foo-foo.  With this kernel config and all the usual daemons enabled (including udevd, hald, syslogd, klogd, and dbus-daemon, but not the cache updaters), it takes 3 minutes and 3 seconds to boot from LILO prompt to login prompt and stop all disk activity.  I am able to run small programs without difficulty.  Larger programs and X11 run too, but with lots of swapping.