While setting up a Via EPIA 800 motherboard to boot from a CompactFlash card,
I discovered a problem: when a Linux loader (in this case, GRUB) loads a
ramdisk for the kernel, it stores it in RAM and points the kernel to it.
The kernel then uncompresses the ramdisk into RAM and starts interacting with
it. This implies that the ramdisk must fit in memory expanded and unexpanded
at the same time. When I was trying to expand a 200MB ramdisk into 256MB of
RAM, I was running out of space because the compressed image had to stay resident
until the ramdisk was fully extracted.
My solution was to build a small ramdisk loader based on the Slackware 10
installer. This loader occupies 1.3MB of RAM when compressed, and 3MB of
RAM when uncompressed.
The loader looks for another ramdisk image in /boot/initrd-stage2.img
and extracts that from disk (or CompactFlash in my case) directly into memory.
The loader is then flushed away. The benefit is that a much larger ramdisk
can be loaded in two stages than can be in one, relative to the amount of
RAM in the system. It may also be faster, because the decompression is
interleaved with reading from disk.
I am providing the stage 1 ramdisk for others
to use. This uses busybox
to do most of its work. I just wrote the linuxrc file that makes it go.
If you have no idea what a loopback filesystem, ramdisk, bootloader, or
kernel are, then this file won't be of much use to you. But to get started,
- Uncompress the image
- As root, mount somewhere as a loopback device
Look at the linuxrc script (i.e. /opt/linuxrc) to see what it does
Change linuxrc as needed (i.e. to read from a different device or file)
Unmount the image, recompress, and set as your initrd to the kernel
- mount -o loop=/dev/loop0 initrd-stage1 /opt