linuxrc in i386 assembly
I was originally disappointed by how large initrd was primarily because it
used libc. I knew a way around this was to use assembly language. I realise
a statically linked C program also does not require libc, but the job that
initrd does is so simple that I assumed an assembly language version would
not be taxing. Indeed I was right, so long as I didn't want compression and
decompression of the rootfs file.
If we ignore the gunzipping part of linuxrc for now, the basic outline
of linuxrc involves making a few mounts and unmounts,
opening and reading a few files and copying some stuff. Pretty simple even
in assembly. I made it easier by using the asmutils framework from
www.linuxassembly.org. It didn't take
too long to throw together a program that did it all, but just dd a 4mb copy
of the rootfs directly off the CD. This I noticed was quite slow compared to
using a gzipped copy, so I set about converting gunzip to assembly ... and
soon gave up.
Then I looked for some simpler compression/ decompression
algortihms and came across a thing
called the 624. It was designed for the 4k intro
'scene'. I think the basic goal of it was to crunch a 6k assembly program
down to about 4k and attach a very small decruncher to it. The author had the
compressor part written in C and the decruncher part written in 386 asm.
Perfect. I just mangled the code so that it wasn't compressing such small files
and it wasn't decompressing as part of an executable. That all worked
eventually, though the compressor didn't seem to compress as well as gzip.
My 4mb rootfs went down to 1.1mb with gzip, but only 1.6mb with the 624
based compressor. Not a major problem really.
The relevant source code is shown below. pcomp can be compiled as
gcc -o pcomp pcomp.c and will compress whatever you pass to
it as the 1st argument (might take a while). linuxrc.asm was assembled using
nasm as part of asmutils (ie. it uses asmutil's include files).