Previous Sections of this document covered the basics of creating boot/root disks, and are applicable to nearly all kernels up to the present (2.0, the latest stable kernel).
Kernels 1.3.48+ involved a substantial rewrite of the ramdisk code, adding significant new capabilities. These kernels could automatically detect compressed filesystems, uncompress them and load them into the ramdisk on boot-up. Root filesystems could be placed on a second disk, and as of kernel 1.3.98 or so, ramdisks are dynamically expandable.
Altogether, these new capabilities mean that boot disks can contain substantially more than they used to. With compression, a 1722K disk may now hold up to about 3.5 megs of files. As anyone who has created bootdisks knows, much time is spent pruning down the file set and finding trimmed-down versions of files that will all fit in a small filesystem. With the new capabilities this is no longer such a concern.
Unfortunately, creating bootdisks to exploit these new features is slightly more difficult now. To build a compressed filesystem on a floppy, the filesystem has to be built on another device and then compressed and transferred to the floppy. This means a few more steps.
The basic strategy is to create a compressed root filesystem, copy the kernel to the floppy disk, tell the kernel where to find the root filesystem, then copy the compressed root filesystem to the floppy.
Here's a simple ASCII drawing of what the disk will look like:
|<--- zImage --->|<------ Compressed root filesystem -------->|
|________________|____________________________________________|
Floppy disk space
Here are the steps to create the boot floppy:
The root filesystem is created pretty much the same way as outlined in Section 2.3 of this document. The primary difference is that you can no longer create a root filesystem directly on a floppy -- you must create it on a separate device larger than the floppy area it will occupy.
In order to build such a root filesystem, you need a spare device that is large enough. There are several choices:
ftp://ftp.win.tue.nl:/pub/linux/util/mount-2.5X.tar.gz
where X is the latest modification letter.
If you do not have loop devices (/dev/loop0, /dev/loop1, etc) on your
system, you'll have to create them first. The command
MAKEDEV loop
will do this.
ftp://tsx-11.mit.edu/pub/linux/sources/sbin/
dd if=/dev/zero of=/tmp/fsfile bs=1k count=nnn
to create an nnn-block file.
Use the file name in place of DEVICE below.
When you issue a mount command you must include the
option "-o loop" to tell mount to use a loopback device.
For example:
mount -o loop -t ext2 /tmp/fsfile /mnt
will mount /tmp/fsfile (via a loopback device) at the mount point
/mnt. A 'df' will confirm this.
RAMDISK_SIZE = nnn
which determines how much RAM will be allocated. The default
is 4096K.After you've chosen one of these options, prepare the device with:
dd if=/dev/zero of=DEVICE bs=1k count=3000
This command zeroes out the device. This step is important because the filesystem on the device will be compressed later, so all unused portions should be filled with zeroes to achieve maximum compression.
Next, create the filesystem with:
mke2fs -m 0 DEVICE
(If you're using a loopback device, the disk file you're using should be supplied in place of this DEVICE. In this case, mke2fs will ask if you really want to do this; say yes.)
Then mount the device:
mount -t ext2 DEVICE /mnt
Proceed as before, copying files into /mnt, as specified in Section 2.3.
After you're done copying files into the root filesystem, you need to copy it back out and compress it. First, umount it:
umount /mnt
(Technically you can copy the filesystem without unmounting it first, but that's somewhat dangerous, and bad practice.)
Next, copy data off the device to a disk file. Call the disk file
rootfs
:
dd if=DEVICE of=rootfs bs=1k
Then compress it. Use the '-9' option of gzip for maximal compression:
gzip -9 rootfs
This may take several minutes. When it finishes, you'll have a file rootfs.gz that is your compressed root filesystem.
If you're tight on disk space you can combine dd and gzip:
dd if=DEVICE bs=1k | gzip -9 > rootfs.gz
At this point, check the space to make sure both the kernel and the root filesystem will fit on the floppy. An "ls -l" will show how many bytes each occupies; divide by 1024 to determine how many blocks each will need. For partial blocks, be sure to round up to the next block.
For example, if the kernel size is 453281 bytes, it will need
ceil(453281 / 1024) = 443
blocks, so it will occupy blocks 0-442 on the floppy disk. The
compressed root filesystem will begin at block 443. Remember this
block number for the commands to follow; call it ROOTBEGIN.
You must tell the kernel where on the floppy to find the root filesystem. Inside the kernel image is a ramdisk word that specifies where the root filesystem is to be found, along with other options. The word is defined in /usr/src/linux/arch/i386/kernel/setup.c and is interpreted as follows:
bits 0-10: Offset to start of ramdisk, in 1024 byte blocks
(This is ROOTBEGIN, calculated above)
bits 11-13: unused
bit 14: Flag indicating that ramdisk is to be loaded
bit 15: Flag indicating to prompt for floppy
(If bit 15 is set, on boot-up you will be prompted to place a new floppy disk in the drive. This is necessary for a two-disk boot set, discussed below in the section "Making a two-disk set". For now, this will be zero.)
If the root filesystem is to begin at block 443, the ramdisk word is
1BB (hex) 443 (decimal) (bits 0-10)
+ 4000 (hex) Ramdisk load flag (bit 14)
----------
= 41BB (hex)
=16827 (decimal)
This ramdisk word will be set in the kernel image using the "rdev -r" command in the next section.
At this point you're ready to create the boot floppy. First copy the kernel:
dd if=zImage of=/dev/fd0
Next, tell the kernel to find its root filesystem on the floppy:
rdev /dev/fd0 /dev/fd0
Next, you have to set the ramdisk word in the kernel image now residing on the floppy. The ramdisk word is set using the "rdev -r" command. Using the figure calculated above in the section titled "Calculating the space":
rdev -r zImage 16827
Finally, place the root filesystem on the floppy after the kernel. The
dd
command has a seek
option that allows you to specify how many
blocks to skip:
dd if=rootfs.gz of=/dev/fd0 bs=1k seek=443
(The value 443 is ROOTBEGIN from the section "Calculating the space" above.)
Wait for the floppy drive to finish writing, and you're done.
If you want more space, you can make a two-disk boot set. In this case, the first floppy disk will contain the kernel alone, and the second will contain the compressed root filesystem. With this configuration you can use a compressed filesystem of up to 1440K.
A two-disk set is created using a simple variation of the instructions above. First, you must set the ramdisk PROMPT flag to 1 to instruct the kernel to prompt and wait for the second floppy. The root filesystem will begin at byte 0 of the second floppy.
From the section "Calculating the space" above, the ramdisk PROMPT flag (bit 15) will be set to 1, and the ramdisk offset will be zero. In our example the new calculation would be:
4000 (hex) Ramdisk load flag (bit 14)
+ 8000 (hex) Ramdisk prompt flag (bit 15)
------------
= C000 (hex)
=49152 (decimal)
which would be used in the 'rdev -r' calculation as before.
Follow the instructions of "Copying files to the floppy" above, but after issuing the 'rdev -r' command, put a new floppy in the drive and issue the command:
dd if=rootfs.gz of=/dev/fd0
The seek
option is not needed since the root filesystem starts at block
zero.