old-www/LDP/LG/issue01to08/linuxita_mar96.html

791 lines
38 KiB
HTML

<HTML>
<HEAD>
<TITLE>Linuxita: the Minimal Working Set?</TITLE>
</HEAD>
<BODY>
<H1>Linuxita: the Minimal Working Set?</H1>
<H4>Copyright (C) 1996 Peter T. Breuer 1996.</H4>
<HR>
<BLOCKQUOTE>
<CENTER><B>Abstract</B></CENTER>
<P>
How small can a useful Linux system get? Linuxita fits on 4.7M of disk
space, works well in 3MB of RAM on a 386sx, and the compressed tar file
fits on a single 1.44M floppy. Is there any reason to be running DOS on
legacy systems?
</BLOCKQUOTE>
<HR>
<P>
When my carefully manicured Linux system had to be sent away for a
long-postponed service call, I turned to an abandoned 386 for rescue.
<I>Baby</I> allows me to keep my office hours as irregular as I like them to
be, with email and the pcmcia modem, and I had been desperate to find a
stopgap. I had prised a replacement for the 386's failed power supply
from a backyard factory via long-distance, and lo! -- the hard disk
turned, dusty or no.
<P>
After much fuss in the dead month of August, I had taken delivery of a
new external modem from the states and picked up a mains voltage
converter to run it off -- non-trivial shopping in those weeks. A few
days before zero hour, I booted DOS on the old machine and it upped and
went as though it had not been down for a year and a half. I called up
Windows 3.1, played a little, and saw that it would not do. I had
forgotten all about Windows on a 16MHz 386sx! Linux had to be installed
on the 386 or I would go crazy while <I>baby</I> was gone. The following
is the story of how to fit a Linux system into the minimum of disk space
and RAM, and be happy.
<H3>Gosh, Darn, Preparations</H3>
<P>
I thought it might be a problem to fit Linux into the 20M disk of
the 386, but knew it was room enough; a pared-down system plus a minimal
X goes 15M at most. The problem would lie in separating out just the
right pieces and getting the installation order so that nothing
overflowed the available space at any stage. I would have to install
piecemeal from the running system on <I>baby</I> over the countdown
period.
<P> I was too optimistic. I had problems backing up <I>baby</I>. The RAM
on my office machine is faulty and I cannot copy over large files
without errors. To cut the story short, I ran the office machine in DOS
and made the transfers at 115K baud through the parallel port with
<B>FastWire</B> both it and <I>baby</I>, the latter under <B>dosemu</B>.
In the end, I never got time to install Linux on the 386 before
<I>baby</I> left. I was lucky to finish the backup.
<P>
Then more problems. I had trouble setting up communications with the
386. There was no space for <B>FastWire</B> in the cramped 20M and no
time to relearn my old setup in order to see how I could make room.
Worse, everything under Windows on the old machine seemed to freeze the
system, for the unknown reasons that normally apply. Its only serial
port applications -- apart from an ancient copy of kermit -- were
Windows applications!
<P>
In the end I found a small but modern serial package for DOS on the
Garbo ftp archive site (<KBD> garbo.uwasa.fi</KBD>) I tried three or
four packages before finding one (<B>QVT</B>) both worked and fitted in
the disk! To download it, I used DOS kermit to set up a 9600 baud direct
login to the office machine through the serial port, then uuencoded and
cat'ed the files past the screen while logging the session (I had a
working DOS uudecode). That gave me an application that could set up a
serial port connection at 38.4K under DOS, and I had an external 14.4K
modem on standby. So when the courier arrived an hour early with the
customs forms for <I>baby</I> not yet typed I felt the situation was
livable.
<P>
But was 386sx hardware really compatible with a modern kernel? That was
an old system. Was 3M of RAM enough? The HOWTO's said yes, but when did
they date from? And because I could not afford to be without a system at
home, I would have to keep DOS working on the 386 while I tried putting
Linux either on top of it or in whatever space I could scrounge on the
disk. I had not foreseen that.
<P>
More, I needed to keep some DOS installations like the C compiler and
LaTeX alive in case Linux installation failed. I did not have any more
room (or time!) to back those up to the office machine too. And most of
the 20M disk was occupied by a Stacker compressed file system so I only
had about 2M accessible via the bare FAT. I would have to fit
the initial installation into something like 2M of disk space!
<H3>Revised Estimates</H3>
<P>
I took a close look at the office system. I keep that at a fairly
standard Slackware 2.1 a.out installation, plus newer kernels and
anything else I find I need, but I have not kept disk space down. How
little could I really cut it down to? I needed <B>/bin</B>,
<B>/sbin</B>, a kernel, the configuration files in <B>/etc/</B>, the
dynamic libraries in <B>/lib</B>, and not much else, as far as I could
guess. To my astonishment, <B>du</B> said that was not very much at all!
Six or seven megabytes. And I could probably trim it some.
<P>
Over the next few days I familiarized myself with the old 386 and DOS.
I stripped out utilities I felt I could lose. I removed the permament
Windows swap file and shrank the Stacker file system down. I collected
<B>fips</B> and <B>presizer</B> for DOS and checked out the partition
table. I found a disk defragmenter on one of my old archive diskettes.
I no longer had <B>fdisk</B> on the 386 but I copied it from the office
system and set up <B>setver</B> to cover up the difference in DOS
versions (and languages!). I relearned my elaborate multi-boot setup on
the 386 -- which dynamic driver loader worked with which driver and
which memory manager, which I needed right then and which I might need
later. In the end I found myself with precisely 4.7M of free disk
space. After a couple of fumbles, I had <B>fips</B> set up a new 4.7M
partition at the end of the 20M disk. The method -- if not the
dimension! -- is familiar to anyone who has installed Linux while
preserving an existing DOS partition.
<P>
I had been experimenting on the office system too. In Linux mode, her
name is <I> monica</I> and she runs as part of a campus-wide net. <I>
Monica</I> has one small 16M partition that I do not use for much of
anything and which I have been meaning to set up as a spare root file
system. What with the RAM fault, I can never be sure when <I> monica</I>
will throw a fit that eats the file system instead of crashing
more-or-less gently (she has since done the inevitable, and I am proud
to say that I managed to put most of the 100M of nameless <TT>
lost+found</TT> files back in the right places in an afternoon), and I would
feel much safer with a separate root. I cleared out the partition and
filled it with the files I thought I would need on root in the 386, and
nothing else.
<P>
I will say that the documentation did not help me learn how to boot from
a different partition with Lilo. It is easy when you know the trick --
you really do have to just change the root partition name in
<B>lilo.conf</B> and run Lilo -- but it took me a day's experimenting.
Along the way, I discovered that one can set up Lilo to boot from a
kernel on a different partition too, even a DOS partition. Just change
the location for the image in <B>/etc/lilo.conf</B>. The trick is to
give the image location relative to the current root, not relative to
the intended root. That is not as obvious as it sounds.
<P>
I found that almost nothing in the Slackware 2.1 <B>/bin</B> directory
can be done without if the <B>init</B> boot sequence is to work. The
<B>/etc/rc.d/</B> files are a flexible, well-designed and
integrated system, but they exercise, or can exercise, quite a few
unexpected utilities. I noticed that the Slackware root (and boot)
diskette contains a much simplified <B>rc.d</B> system and thought about
borrowing it. But I like and understand the <B>rc.d</B> system as it
is, so I decided to hang on to it and live with the overhead. I could
always change my mind later. But <B>/bin</B> came in at just under
1.2M, including both <B>bash</B> and <B>tcsh</B> shells (obviously, I
only needed the first of these for the <B>init</B> sequence, and could
even have got away with a lighter shell if I were only thinking about
the <B>rd.d</B> sequence, but I could not live with a system on which I
could not run decent shell scripts) so I would just have to be prepared
to rethink later. One surprise was that I needed <B>test</B> from
<B>/usr/bin</B>. It is needed in <B>rc.[SM0]</B>, at least. I had
thought that a Unix system was meant to be able to boot up without using
anything from <B>/usr</B>! (<TT> sleep</TT> is also in the wrong place in
the current ELF slackware distribution).
<P>
Pretty soon, I had a bootable partition on <I> monica</I> with about 8M of
files in it. I had not been cutting files out so much as throwing files
in wholesale when I detected a need, so, encouraged, I went back to my
386, used <B>fdisk</B> again to split out a 1M partition from the 4.7M
for use as swap and started to think about the important things ahead.
What would I call the new system! Thanks to some unjustifiable extra
spending some years ago, it has 3M of RAM to complement the 16MHz
processor. One day I will be able to afford a coprocessor. <I>
Bambam</I> was clearly an appropriate name for it and a choice that I look
back on with satisfaction. 3.7M of disk space, 1M of swap and 3M of RAM
would make for a mighty machine.
<H3>Installation</H3>
<P>
<I> Bambam</I> and I went back home and I used DOS and the modem to start
transfering pieces that I reckoned I needed out of <I> monica</I>'s trial
setup. I used a floppy as an intermediate storage area. I had no room
to do anything else. Catch number one turned out to be that I could not
use the ramdisk on the Slackware bootdisk kernel (I do not have enough
memory on <I> bambam</I>) I had to use the Slackware rootdisk as my root
device. With only one floppy slot, that left me stuck. I needed the
floppy both as a root filesystem and as an i/o device. So I sighed,
scrapped some more favourite utilities from my DOS partition, then
squeezed the tar files onto it and tried again. Now I know that I
should have made my own bootdisk using the minimally configured kernel
on <I> monica</I>. I have had many communications since with people
seeking to set up Linux systems in 3M of RAM or less, and in most cases
the mistake they have been making has been using the slackware boot
kernels. Those will take up at least 1.5M of RAM with all the
compiled-in drivers, often leaving too little to boot <B>init</B> and
the standard <B>getty</B>'s and daemons, plus a shell. <I> Monica</I>'s
kernel takes up 1068K (and loads extra kernel modules when needed).
Looking back, it is amusing that I made this mistake too.
<H3>System binaries</H3>
<P>
<I> Monica</I>'s little trial partition had given me a guide as to what I
really needed and what would be nice, but could be done without. So
this time round I was careful to include the minimum. I have already
mentioned that I needed about all of slackware 2.1 <B>/bin</B>. The list is
in Figures 1, 2, 3, &amp; 4.
<PRE>
total 1181
-rwxr-xr-x 1 root bin 1248 Sep 17 1994 arch
-rwxr-xr-x 1 root bin 295940 Sep 5 1994 bash
-rwxr-xr-x 1 root bin 4840 Nov 25 1993 cat
-rwxr-xr-x 1 root bin 9220 Jul 20 1994 chgrp
-rwxr-xr-x 1 root bin 13316 Jul 20 1994 chmod
-rwxr-xr-x 1 root bin 13316 Jul 20 1994 chown
lrwxrwxrwx 1 root root 17 Sep 3 07:18 compress -> /usr/bin/compress
-rwxr-xr-x 1 root bin 21508 Jul 20 1994 cp
lrwxrwxrwx 1 root root 4 Sep 3 07:19 csh -> tcsh
-rwxr-xr-x 1 root bin 5192 Nov 25 1993 cut
-rwxr-xr-x 1 root bin 19872 Mar 23 1994 date
-rwxr-xr-x 1 root bin 17412 Jul 20 1994 dd
-rwxr-xr-x 1 root bin 13316 Jul 20 1994 df
-rwxr-xr-x 1 root root 1848 Aug 28 01:38 dirname
-rwxr-xr-x 1 root bin 1752 Sep 17 1994 dmesg
lrwxrwxrwx 1 root root 8 Sep 3 07:18 dnsdomainname -> hostname
-rwxr-xr-x 1 root root 26 Sep 6 06:04 domainname
-rwxr-xr-x 1 root bin 13316 Jul 20 1994 du
</PRE>
<B>Figure 1</B><BR>
The <TT>/bin</TT> directory, a--d
<P>
As remarked, I voted to retain <B>bash</B>, despite its size, or I could
have no fun writing shell scripts. I was surprised, but I could not do
without <B>cut</B>. The <B>domainname</B> script I kludged as a call to
<B>hostname</B> with the <B>-d</B> option. It would also be possible to
use <B>yp-domainname</B> under other circumstances.
<PRE>
-rwxr-xr-x 1 root bin 3312 Mar 23 1994 echo
-rwxr-xr-x 1 root bin 326 Mar 23 1994 false
-rwxr-xr-x 1 root bin 2456 Oct 17 1994 free
-rwxr-xr-x 1 root bin 1912 Sep 17 1994 getoptprog
lrwxrwxrwx 1 root root 4 Sep 3 07:18 gunzip -> gzip
-rwxr-xr-x 1 root bin 46084 Sep 5 1993 gzip
-rwxr-xr-x 1 root bin 4256 Nov 25 1993 head
-rwxr-xr-x 1 root bin 3536 Sep 17 1994 hostname
-rwxr-xr-x 1 root bin 2000 Aug 16 1994 ipmask
-rwxr-xr-x 1 root bin 2028 Sep 17 1994 kill
-rwxr-xr-x 1 root bin 4228 Oct 17 1994 killall
-rwxr-xr-x 1 root root 54276 Sep 3 02:10 less
-rwxr-xr-x 1 root bin 13316 Jul 20 1994 ln
-rwxr-xr-x 1 root bin 6752 Sep 18 1994 login
-rwxr-xr-x 1 root bin 25604 Feb 26 1994 ls
</PRE>
<B>Figure 2</B><BR>
The <TT>/bin</TT> directory, e--l.
<P>
I have no idea if I had scripts that needed <B>getoptprog</B>, but it
did not seem worth worrying about. The <B>ipmask</B> program has similar
status. <I> Monica</I> is hooked up to the campus network the whole
time, and I am sure that she needs it, but <I> bambam</I> could probably
do without. Note that I put <B>less</B> here, and replaced <B>more</B>
with a symlink to <B>less</B>.
<PRE>
-rwxr-xr-x 1 root bin 13316 Jul 20 1994 mkdir
-rwxr-xr-x 1 root bin 9220 Jul 20 1994 mkfifo
-rwxr-xr-x 1 root bin 9220 Jul 20 1994 mknod
lrwxrwxrwx 1 root root 4 Sep 3 12:24 more -> less
-rwxr-sr-x 1 root bin 17424 Sep 17 1994 mount
-rwxr-xr-x 1 root bin 13316 Jul 20 1994 mv
-rwxr-xr-x 1 root bin 21508 Oct 17 1994 ps
-rwxr-xr-x 1 root bin 1368 May 4 1994 pwd
-rwxr-xr-x 1 root bin 13316 Jul 20 1994 rm
-rwxr-xr-x 1 root bin 9220 Jul 20 1994 rmdir
-rwxr-xr-x 1 root bin 7536 Sep 17 1994 setserial
-rwxr-xr-x 1 root bin 10968 Sep 17 1994 setterm
lrwxrwxrwx 1 root root 4 Sep 3 07:18 sh -> bash
-rwxr-xr-x 1 root bin 11132 Sep 17 1994 sln
-rwxr-xr-x 1 root bin 19356 Mar 23 1994 stty
-rwsr-sr-x 1 root bin 5492 Mar 23 1994 su
-rwxr-xr-x 1 root bin 64 Sep 17 1994 sync
</PRE>
<B>Figure 3</B><BR>
The <TT>/bin</TT> directory, m--s.
<P>
The <B>ps</B> utility is rather costly -- it also means compiling the
<B>proc</B> filesystem into the kernel -- but I hate to be without it.
Likewise for <B>setterm</B>, though with less verve. Note that I
included <B>sln</B> here. It is a statically linked version of <B>ln</B>
that I have learned can get one out of a hole when playing with dynamic
libraries.
<PRE>
-rwxr-xr-x 1 root bin 140292 Jun 24 1994 tar
-rwxr-xr-x 1 root bin 209924 Jul 11 1993 tcsh
-rwxr-xr-x 1 root bin 21508 Jul 20 1994 touch
-rwxr-xr-x 1 root bin 328 Mar 23 1994 true
-rwxr-xr-x 1 root bin 8888 Sep 17 1994 umount
-rwxr-xr-x 1 root bin 2772 Mar 23 1994 uname
lrwxrwxrwx 1 root root 4 Sep 3 07:18 zcat -> gzip
lrwxrwxrwx 1 root root 2 Sep 3 23:33 zls -> ls
</PRE>
<B>Figure 4</B><BR>
The <TT>/bin</TT> directory, t--z.
<P> To comment on the last (<B>zls</B>) link -- I am running the ZLIB
versions of the dynamic libraries in order to make use of compressed
data files wherever possible, so I need <B>zls</B> as a way of calling
<B>ls</B> and avoiding the interpretation induced by on-the-fly
decompression. For the rest -- I needed <B>tar</B> then and felt that I
might need it again. The <B>tcsh</B> is my normal shell and I had to
have it. I might have replaced <B>touch</B> with a shell script, but in
the end I did not.
<P>
The <B>/sbin</B> directory I pretty much copied wholesale over to <I>
bambam</I> (see Figure 10). I eliminated some utilities that I could
rely on never needing again, such as <B>mk2efs</B>. Indeed, I removed
all the file system <B>mk</B>\dots utilities. But I kept <B>fdisk</B>
because I like to check that my partitions are still there occasionally!
I eliminated <B>hdparm</B> because it does not work on my old drive )or
at least, the version that I had did not seem to). I threw out various
Slackware setup utilities (notably <B>setup</B>).
<PRE>
/sbin:
total 252
drwxr-xr-x 2 root uucp 1024 Oct 4 04:28 ./
drwxr-xr-x 17 root root 1024 Sep 10 21:26 ../
-rwxr-xr-x 1 root bin 6504 Sep 17 1994 agetty*
-rwxr-x--- 1 root bin 5336 Apr 12 1994 badblocks*
-rwxr-xr-x 1 root users 124 Apr 1 1995 bdflushd*
-rwxr-xr-x 1 root bin 4568 Sep 17 1994 clock*
lrwxrwxrwx 1 root root 14 Sep 3 06:49 depmod -> /sbin/modprobe*
-rwxr-x--- 1 root bin 55936 Apr 12 1994 e2fsck*
-rwxr-xr-x 1 root bin 18136 Sep 17 1994 fdisk*
-rwxr-xr-x 1 root bin 3232 Sep 17 1994 fsck*
-rwxr-xr-x 1 root bin 9220 Nov 25 1993 halt*
-rwx--x--x 1 root bin 1392 Jul 14 1993 hostname_notcp*
-rwxr-xr-x 1 root bin 17412 Nov 25 1993 init*
-rwxr-sr-x 1 root root 18080 Jun 11 1995 insmod*
-rwxr-xr-x 1 root bin 1920 Sep 17 1994 kbdrate*
-rwx------ 1 root root 5336 Jun 11 1995 kerneld*
lrwxrwxrwx 1 root root 6 Sep 3 06:49 ksyms -> insmod*
-rwxr-xr-x 1 root root 118 Jun 11 1995 lsmod*
-rwxr-xr-x 1 root bin 5212 Sep 17 1994 mkfs*
-rwxr-x--- 1 root bin 4000 Nov 30 1993 mksuper*
-rwxr-xr-x 1 root bin 2452 Sep 17 1994 mkswap*
-rwxr-xr-x 1 root bin 18816 Jun 11 1995 modprobe*
lrwxrwxrwx 1 root root 10 Sep 3 06:49 mount -> /bin/mount*
lrwxrwxrwx 1 root root 4 Sep 3 06:49 ramsize -> rdev*
-rwxr-xr-x 1 root bin 3852 Sep 17 1994 rdev*
lrwxrwxrwx 1 root root 4 Sep 3 06:49 reboot -> halt*
lrwxrwxrwx 1 root root 6 Sep 3 06:49 rmmod -> insmod*
-rwxr-x--- 1 root bin 9220 Nov 27 1993 rmt*
lrwxrwxrwx 1 root root 4 Sep 3 06:49 rootflags -> rdev*
-rwxr-xr-x 1 root bin 13316 Nov 25 1993 shutdown*
lrwxrwxrwx 1 root root 4 Sep 3 06:49 swapdev -> rdev*
lrwxrwxrwx 1 root root 6 Sep 3 06:49 swapoff -> swapon*
-rwxr-xr-x 1 root bin 2428 Sep 17 1994 swapon*
lrwxrwxrwx 1 root root 4 Sep 3 06:49 telinit -> init*
-rwxr-x--- 1 root bin 1936 Nov 30 1993 testfs*
lrwxrwxrwx 1 root root 7 Sep 3 06:49 udosctl -> umssync*
lrwxrwxrwx 1 root root 11 Sep 3 06:49 umount -> /bin/umount*
lrwxrwxrwx 1 root root 7 Sep 3 06:49 umssetup -> umssync*
-rwxr-xr-x 1 bin bin 23832 Jul 18 1995 umssync*
-rwxr-xr-x 1 root users 160 Apr 1 1995 updated*
lrwxrwxrwx 1 root root 4 Sep 3 06:49 vidmode -> rdev*
</PRE>
<B>Figure 10</B><BR>
The <TT>/sbin</TT> directory.
<P>
On the other hand, I had to keep, or perhaps include as extras, if one
wishes to look at it that way, utilities to insert and remove dynamic
kernel modules (<B>insmod</B>, <B>rmmod</B>, <B>modprobe</B>,
<B>depmod</B>). These come in the <B>modules-1.2.8</B> package
on most archive sites. I use the kernel daemon (same package) to take
some of the strain away. It unloads modules from RAM when they are
not used for 30 seconds (by default), which is valuable.
<P>
I run both the <B>msdos</B> and <B>umsdos</B> modules in order to
access the DOS partition on the disk. The <B>umsdos</B> file system
means that I also have to keep around the <B>umssync</B> (a.k.a.
<B>umssetup</B>) utilities to keep Linux up to date with the
state of the DOS partition. Every so often I tend to makes some
changes from DOS and then Linux will not see the new files (or lose the
old ones) until <B>umssync</B> is run. It is worth having on the disk.
<PRE>
/lib/modules/1.2.13/fs:
total 63
drwxr-xr-x 2 root uucp 1024 Sep 3 09:54 ./
drwxr-xr-x 5 root uucp 1024 Jul 9 1995 ../
-rw-r--r-- 1 root root 30083 Jul 9 1995 msdos.o
-rw-r--r-- 1 root root 27307 Jul 9 1995 umsdos.o
/lib/modules/1.2.13/misc:
total 9
drwxr-xr-x 2 root uucp 1024 Aug 27 19:32 ./
drwxr-xr-x 5 root uucp 1024 Jul 9 1995 ../
-rw-r--r-- 1 root root 7253 Jul 9 1995 binfmt_elf.o
/lib/modules/1.2.13/net:
total 4
drwxr-xr-x 2 root uucp 1024 Sep 3 09:43 ./
drwxr-xr-x 5 root uucp 1024 Jul 9 1995 ../
-rw-r--r-- 1 root root 1367 Jul 9 1995 dummy.o
</PRE>
<B>Figure 11</B><BR>
The <TT>/lib/modules</TT> directories.
<P>
As can be seen in Figure 11, the only modules I chose to have available
on <I> bambam</I> cost just under 80K of disk space. There was no need
to keep <B>binfmt_elf.o</B> around -- I was not running ELF, nor any
need for <B>dummy.o</B> -- I was not running the net, but I thought I
might possible play a little.
<P>
Note that I use the <B>bflushd</B> and <B>updated</B> daemons, instead
of the larger daemon (which splits into two when run) that is on the
standard distributions. As I recall, I got these from the <B>apm-0.5</B>
package. They are specially tuned for laptops and other small machines
(the kernel I was using on <I> bambam</I> had APM compiled into it, although
I doubt if <I> bambam</I> knew anything about it). I have not been able
to compile the assembler with newer compiler versions, so I have been
passing these on to myself as a binary inheritance for some time now.
<H3>System libraries</H3>
<P>
My extravagance so far had left me with 2.25M free from the 4.7M
partition minus 1M swap. I went back and remade the standard
<B>/lost+found</B> directory in order to save myself 8K. The
<B>mk2efs</B> sets the directory size to 12K to start with, which has
always seemed pessimistic to me. On <B>/lib</B> itself, however, I saved
a little more.
<PRE>
total 779
lrwxrwxrwx 1 root root 12 Sep 3 07:53 cpp -> /usr/bin/cpp
lrwxrwxrwx 1 root root 11 Sep 3 07:53 ld.so -> ld.so.1.7.3
-rwxr-xr-x 1 root root 20484 Jun 29 23:02 ld.so.1.7.3
lrwxrwxrwx 1 root root 13 Sep 3 07:53 libc.so.4 -> libc.so.4.7.2
-rwxr-xr-x 1 root root 634880 Apr 29 14:58 libc.so.4.7.2
lrwxrwxrwx 1 root root 14 Sep 3 07:53 libm.so.4 -> libm.so.4.6.27
-rwxr-xr-x 1 root root 110592 Feb 18 1995 libm.so.4.6.27
-rwxr-xr-x 1 root root 22349 Jun 29 06:50 linuxaout-uncompress.o
drwxr-xr-x 9 root uucp 1024 Sep 3 10:21 modules
</PRE>
<B>Figure 15</B><BR>
The <TT>/lib</TT> directory.
<P>
To my surprise, I did not need anything more than the basic <B>libc</B>
and <B>libm</B>. I had been worried that I might need <B>libvga</B> or
other exotica for some of the standard utilities, but no. The
<B>linuxaout-uncompress.o</B> contains the to-be-preloaded library
functions for the ZLIB library modification. I prefer using the
preloaded module rather than altering <B>libc</B>, which is the other
method of getting ZLIB up and running. But it obviously uses more space.
I need the <B>ld.so</B> version 1.7.3 or better to make dynamic
preloading work. With LD\_PRELOAD set to point to it, on each call to
the dynamic libraries the preload module is scanned first. The module
intercepts reads from compressed files and uncompresses them through a
pipe. It can save considerable space.
<P>
I believe that I am supposed to hard-link <B>ld.so</B>, but a soft link
seems to work fine.
<P>
The libraries consumed 780K. At this point I had 1.45M of partition
space available and the configuration files in <B>/etc</B> were still to
come.
<H3>System configuration</H3>
<P>
I edited down the number of <B>agetty</B>'s started in
<B>/etc/inittab</B> to two. Any more was an extravagance from my point
of view. Even if they did share code. Two virtual consoles is enough.
Note that I preferred <B>agetty</B> to <B>getty_ps</B> or other
alternatives for reasons of space. It is the simplest.
<P>
In the end, I had <B>/etc</B> down to just over 100K. The biggest
files are <B>magic</B> (for the <B>file</B> command) and
<B>termcap</B>. The latter can be edited down and the former I
compressed. Using ZLIB means that it is read alright.
<P>
I left the <B>init</B> sequence files in <B>/etc/rc.d</B> as
standard -- for a cost of 27K. And out of nostalgia (or hope?) I
let one or two network configuration files stand -- <B>resolv.conf</B>,
for example. I did optimize some things in <B>/etc</B>, however. I
emptied the <B>skel</B> subdirectory (I was not going to make new
users). I made sure that the <B>locale</B> subdirectory was empty, and
checked that <B>fs</B> only contained soft links and no executables.
The real executables should go in <B>/sbin</B>.
<PRE>
/boot:
total 27
drwxr-xr-x 2 root uucp 1024 Sep 4 00:04 ./
drwxr-xr-x 17 root root 1024 Sep 10 21:26 ../
-rwxr-xr-x 1 root root 200 Sep 3 23:52 any_b.b*
-rwxr-xr-x 1 root root 200 Sep 3 23:52 any_d.b*
-rwxr-xr-x 1 root root 512 Sep 3 23:52 boot.030*
-rw-r--r-- 1 root root 512 Sep 4 00:04 boot.0300
-rwxr-xr-x 1 root root 3336 Sep 3 23:52 boot.b*
-rwxr-xr-x 1 root root 84 Sep 3 23:52 chain.b*
-rwxr-xr-x 1 root root 7743 Sep 3 23:52 config.in*
-rw------- 1 root root 7168 Sep 4 00:04 map
-rwxr-xr-x 1 root root 140 Sep 3 23:52 os2_d.b*
</PRE>
<B>Figure 6</B><BR>
The <TT>/boot</TT> directory.
<PRE>
/etc:
total 107
drwxr-xr-x 6 root uucp 1024 Jan 25 23:48 ./
drwxr-xr-x 17 root root 1024 Sep 10 21:26 ../
-rw-r--r-- 1 root root 1952 Jun 23 1995 DIR_COLORS
-rw-r--r-- 1 root root 11 Sep 6 00:07 DOMAINNAME
-rw-r--r-- 1 root root 19 Sep 3 08:38 HOSTNAME
-rw-r--r-- 1 root root 30 Sep 6 00:00 KEYTABLE
lrwxrwxrwx 1 root root 14 Sep 3 06:46 X11 -> /var/X11R6/lib
-rw-r--r-- 1 root root 1324 Aug 26 20:31 conf.modules
-rw-r--r-- 1 root root 139 Sep 9 10:17 csh.cshrc
-rw-r--r-- 1 root root 787 Sep 9 10:16 csh.login
-rw-r--r-- 1 root root 443 Jan 24 1994 disktab
-rw-r--r-- 1 root root 0 Dec 24 1994 fastboot
-rw-r--r-- 1 root root 1182 Dec 13 1992 fdprm
drwxr-xr-x 2 root uucp 1024 Jan 5 1995 fs/
-rw-r--r-- 1 root root 379 Sep 5 01:39 fstab
-rw-r--r-- 1 root root 369 Oct 2 23:44 group
-rw-r--r-- 1 root root 26 Mar 4 1995 host.conf
-rw-r--r-- 1 root root 4 Jan 28 1995 hostid
-rw-r--r-- 1 root root 402 Sep 3 08:39 hosts
-rw-r--r-- 1 root root 23 Jul 11 1995 hosts.term
lrwxrwxrwx 1 root root 1 Sep 3 06:46 inet -> ./
-rw-r--r-- 1 root root 2745 Dec 30 22:26 inittab
-rw-r--r-- 1 root root 27 Jan 25 23:32 issue
-rw-r--r-- 1 root root 99 Sep 4 23:41 ld.so.cache
-rw-r--r-- 1 root root 45 Mar 18 1994 ld.so.conf
-rw-r--r-- 1 root root 609 Sep 3 12:40 lilo.conf
drwxr-xr-x 3 root root 1024 Sep 3 23:42 locale/
pr--r--r-- 1 root root 47874 Sep 27 1994 magic|
-rw-r--r-- 1 root root 23 Jan 25 23:32 motd
-rw-r--r-- 1 root bin 123 Jan 25 23:48 mtab
-rw-r--r-- 1 root root 835 Sep 9 23:35 mtools
-rw-r--r-- 1 root root 233 Jan 28 1995 networks
-rw-r--r-- 1 root root 847 Sep 9 10:44 passwd
-rw-r--r-- 1 root root 1280 Sep 4 07:32 profile
drwxr-xr-x 2 root uucp 1024 Sep 10 23:41 rc.d/
-rw-r--r-- 1 root root 39 Jan 28 1995 resolv.conf
-rw-r--r-- 1 root root 86 Jan 28 1994 securetty
-rw-r--r-- 1 root root 37 Jan 5 1995 shells
drwxr-xr-x 3 root uucp 1024 Jan 5 1995 skel/
-rw-r--r-- 1 root root 24318 Jul 9 1995 termcap
-rw-r--r-- 1 root root 138 Jan 20 1995 ttys
lrwxrwxrwx 1 root root 13 Sep 3 06:46 utmp -> /var/log/utmp
lrwxrwxrwx 1 root root 13 Sep 3 06:46 wtmp -> /var/log/wtmp
</PRE>
<B>Figure 7</B><BR>
The <TT>/etc</TT> directory.
<P>
1.35M left and counting.
<PRE>
/etc/rc.d:
total 27
drwxr-xr-x 2 root uucp 1024 Sep 10 23:41 ./
drwxr-xr-x 6 root uucp 1024 Jan 25 23:48 ../
-rw-r--r-- 1 root root 11 Jan 5 1995 ROOTDEV
-rwxr-xr-- 1 root root 807 Sep 10 23:40 rc.0*
-rwxr-xr-- 1 root root 437 Nov 26 1993 rc.6*
-rwxr-xr-- 1 root root 461 Sep 6 01:31 rc.K*
-rwxr-xr-- 1 root root 2118 Sep 3 22:48 rc.M*
-rwxr-xr-- 1 root root 4528 Sep 5 08:52 rc.S*
-rwxr-xr-- 1 root root 2929 Sep 10 23:39 rc.local*
-rw-r--r-- 1 root root 1631 Jul 9 1995 rc.pcmcia
-rwxr-xr-- 1 root root 8114 Sep 3 10:26 rc.serial*
</PRE>
<B>Figure 8</B><BR>
The <TT>/etc/rc.d</TT> directory.
<H3>Application binaries</H3>
<P>
What applications would I need? My requirements were connectivity and local
editing. The rest I could rely on my remote systems for.
<PRE>
/usr/bin:
total 575
drwxr-xr-x 2 root root 1024 Sep 26 09:58 ./
drwxr-xr-x 9 root root 1024 Sep 12 00:27 ../
lrwxrwxrwx 1 root root 4 Sep 3 20:52 [ -> test*
-rwx--x--x 1 ptb users 1976 Sep 11 23:55 basename*
-rwxr-xr-x 1 root root 25 Sep 4 06:27 clear*
-rwxr-xr-x 1 501 users 13084 Sep 3 21:20 file*
-rwxr-xr-x 1 root root 62468 Sep 3 00:03 grep*
-rwx--x--x 1 ptb users 3823 Sep 11 23:47 gzexe*
-rwxr-xr-x 1 501 users 2648 Sep 3 18:33 ldd*
-rwxr-xr-x 1 ptb users 37892 Sep 5 21:06 loadkeys*
-rwxr-xr-x 1 root bin 25604 Jul 17 1994 lrz*
-rwxr-xr-x 1 root bin 29700 Jul 17 1994 lsz*
-rwxr-sr-x 1 root uucp 78852 Sep 2 23:55 minicom*
lrwxrwxrwx 1 root root 3 Sep 3 12:33 rb -> lrz*
-rwxr-xr-x 1 ptb users 121 Sep 5 21:05 reset*
-rwxr-xr-x 1 root root 13316 Sep 9 01:20 runscript*
lrwxrwxrwx 1 root root 3 Sep 3 12:33 rx -> lrz*
lrwxrwxrwx 1 root root 3 Sep 3 12:33 rz -> lrz*
lrwxrwxrwx 1 root root 3 Sep 3 12:34 sb -> lsz*
-rw-r--r-- 1 root root 0 Sep 26 09:58 screen.dump
-rwx--x--x 1 ptb users 54276 Sep 12 00:31 sed*
lrwxrwxrwx 1 root root 3 Sep 3 12:34 sx -> lsz*
lrwxrwxrwx 1 root root 3 Sep 3 12:33 sz -> lsz*
-rwxr-xr-x 1 ptb users 7672 Sep 5 21:05 tail*
-rwxr-xr-x 1 501 users 12228 Sep 3 18:36 test*
-rwxr-xr-x 1 501 users 21508 Sep 12 00:37 top*
-rwxr-xr-x 1 501 users 13316 Sep 4 04:20 tset*
lrwxrwxrwx 1 root root 3 Sep 3 09:56 vi -> vim*
-rwxr-xr-x 1 root root 185348 Sep 2 23:55 vim*
</PRE>
<B>Figure 9</B><BR>
The <TT>/usr/bin</TT> directory.
<H3>Communications</H3>
<P>
Since I wanted to work a modem, I needed <B>minicom</B> as a
communications package. It is small and neat (about 80K) and I like
it. Perhaps there is something more suitable out there, but I do not
know about it. It needs one or two configuration files in
<B>/var/lib/minicom</B>, and nothing else. Each user also gets a local
configuration file <B>~/.minirc</B> and a phone number list, but there
would only be one user -- apart from root. A few extra kilobytes.
By this stage I was definitely counting kilobytes. A separate utility,
<B>runscript</B>, is also required in order to parse the login scripts.
15K more. And I needed to upload and download, so I needed the zmodem
protoocols. That requires <B>lrz</B> and <B>lsz</B> and some soft
links. 60K more.
<H3>Editor</H3>
<P>
For each individual, there is only one choice of editor. For me, it is
<B>vi</B> -- rather <B>vim</B>, the multi-window version. Perhaps
an <B>emacs</B> person would have to settle for <B>joe</B> as a poor
substitute in the disk space available, but I did not have to compromise.
That cost 185K, plus my configuration file.
<H3>Sundries</H3>
<P> Certain applications are neither necessities nor luxuries. One can
do without them, but life would be sadder. In that category I count the
compression utilities <B>gzip</B> and <B>gzexe</B>, as well as the
ever-entertaining <B>top</B>. At least it is useful for tuning.
<B>tset</B> (and <B>reset</B>, only a shell script) are also too much
bother to miss out. <B>loadkeys</B> I needed for my UK keyboard layout,
but I trimmed <B>/usr/lib/kbd/keytables</B> down to just the map that I
needed. See Figure~\ref{9} for the complete list that I left in
<B>/usr/bin</B>. It occupied just under 600K in total, which left me
with 750K.
<H3>Luxuries</H3>
<P>
Although my institute's modems are all even-parity, I had had success in
getting <B>term</B> to work across the link (the 1.9 version, not the
later series, for some reason), so I bundled it too. Multiplexed unix
logins to a big system are a blessing not to be missed. I would have
used <B>slirp</B>, but then I would have had to install some network
utilities, and I did not have the space. What is more, I have never
discovered how to get slirp to cope with an even-parity modem line.
<B>term</B> goes in <B>/usr/local/bin</B> with the remote shell
(<B>trsh</B>) and shutdown utility (<B>tshutdown</B>). For fun I added
the termified uploader too. All these utilities are the same size and I
suspect that they may be the same inside. Perhaps soft links might work
instead of renamed copies? I did not experiment. They came to just under
100K, with the configuration file. 650K to go.
<PRE>
/usr/local/bin:
total 144
drwxr-xr-x 2 root root 1024 Sep 10 23:53 ./
drwxr-xr-x 5 root root 1024 Sep 10 19:46 ../
lrwxrwxrwx 1 root root 6 Sep 4 06:31 mcd -> mtools*
lrwxrwxrwx 1 root root 6 Sep 3 13:02 mcopy -> mtools*
lrwxrwxrwx 1 root root 6 Sep 3 13:02 mdel -> mtools*
lrwxrwxrwx 1 root root 6 Sep 3 13:02 mdir -> mtools*
lrwxrwxrwx 1 root root 6 Sep 3 13:02 mformat -> mtools*
lrwxrwxrwx 1 root root 6 Sep 22 09:46 mlabel -> mtools*
lrwxrwxrwx 1 root root 6 Sep 4 06:32 mmd -> mtools*
lrwxrwxrwx 1 root root 6 Sep 4 06:35 mrd -> mtools*
lrwxrwxrwx 1 root root 6 Sep 3 13:02 mread -> mtools*
-rwxr-xr-x 1 501 users 41988 Sep 12 00:37 mtools*
lrwxrwxrwx 1 root root 6 Sep 3 13:02 mwrite -> mtools*
-rwxr-xr-x 1 root term 49152 Sep 8 21:30 term*
-rwxr-sr-x 1 root term 16384 Sep 8 21:31 trsh*
-rwxr-sr-x 1 root term 16384 Sep 8 21:31 tshutdown*
-rwxr-sr-x 1 root term 16384 Sep 8 21:31 tupload*
</PRE>
<B>Figure 6</B><BR>
The <TT>/usr/local/bin</TT> directory.
<P>
And although I can read my dos floppies by mounting <B>/dev/fd0</B>
as an <TT>msdos</TT> type file system, I prefer to use the <B>mtools</B>
suite. It only requires a single 42K executable, and all the variants
(<B>mwrite</B>, <B>mread</B>, <B>mcopy</B>, etc.) are soft links to it.
I put those in <B>/usr/local/bin</B> too. 600K left.
<H3>Application libraries</H3>
<P>
Fortunately, my choice of applications did not require any extra dynamic
libraries.
<H3>Overheads</H3>
<P>
What about all the uncountable bits and pieces, like directories (which
take up room) and a few scripts such as <B>MAKEDEV</B> that one should
never risk being without? Those take up a bit of extra space. Then
there is the compressed kernel image itself, and some log files and
other administrivia. All in all, about another 3500K of disk space.
<P>
Of course I chose not to run <B>syslog</B> and friends (the messages
just scroll pass the console instead) and pointed the log files at
<B>/dev/null</B>. I did not need the Slackware <B>/var/log/packages</B>
directory either, or <B>scripts</B>. I did not need most of the
<B>/var/spool</B> subdirectories since I was not running <B>cron</B> or
<B>at</B>, or a printer or mail. So I saved a little there.
<P>
There is a small penalty for using a system -- instead of looking at it
admiredly. I had to install a home directory for myself. Since I had so
much space, I gave root its own home too, just as one is supposed to. In
the end I had about 250K of usable space left free on the disk. Enough
to edit files on, and pass files to and from over the modem -- just as I
had required.
<H3>Conclusion</H3>
<P>
It is indeed possible to run Linux on a 386sx machine with just a few
megabytes of disk space available, and very limited RAM. With less RAM
than the 3M I had I might have needed to use a non-production kernel,
but the standard 1.2.13 kernel worked well for me, when cut down and
mounting modules dynamically by need. I was able to shoehorn the file
system into a little over 3.6M, and used a 1M swap partition. The
performance is at least as good as with DOS, and I am a lot happier.
<HR>
<BR>
Back up to <A HREF="./lg_issue7.html">Linux Gazette!</B>
</BODY>
</HTML>