9.4 Using GRUB with DiskOnChip Devices

Since the use of GRUB with conventional disk devices is already amply covered in the GRUB manual, we will mainly concentrate on the installation and use of GRUB with DOC devices. Before I start covering the details of how to compile and use GRUB with a DOC device, I must warn you that an improper configuration of GRUB for your DOC can render your system unbootable. Let's see why this happens and how it can be avoided.

As I explained in Chapter 7 when describing the use of the doc_loadbios command, DOC devices contain a ROM program called the IPL that is detected as a BIOS extension at startup and is executed by the BIOS. When it runs, this IPL installs another program, the SPL. To boot from a DOC device using GRUB, the SPL must be replaced by a version of GRUB specifically tailored to boot from a DOC.

Since there may be other BIOS extensions in the system, the SPL loaded by the IPL cannot boot the system right away. Instead, it must install a Terminate and Stay Resident (TSR) program that will lay dormant until the BIOS is ready to boot the system. In the case of GRUB, the GRUB SPL replaces the BIOS's bootstrap interrupt, INT 19h, with a custom interrupt handler that will execute the rest of the GRUB code to finish booting from the DOC device. Hence, the other BIOS extensions get to run and GRUB is called only when the system is ready to be booted.

The problem with this scheme, however, is that the default bootstrap handler installed by the BIOS never gets a chance to run, and any boot configuration option you may have selected in your BIOS?such as booting from disk or floppy first?will be completely ignored by GRUB when its handler is invoked. This is fine if the configuration file on the DOC is correct. At worst, you would then boot using the DOC, change the configuration file in Linux, or completely remove GRUB from the DOC to set the system as you desire.

If you make any mistakes in the GRUB configuration file that result in boot failure, however, you will be unable to restart your system normally without finding a way to disable the replacement of the bootstrap interrupt handler at startup. There are four known ways to do this:

  • You can physically remove the DOC from the system before starting it. The problem with this choice is that your only way to reprogram the DOC thereafter, if you do not have access to a hardware DOC programer, is to insert the DOC after the system has been started. In other words, you would have to connect the DOC to a live electronic circuit. Needless to say, neither the DOC nor the electronic circuits interfacing with it have been designed for this sort of manipulation. Also, I neither encourage you to try this nor take any responsibility if you are crazy enough to do it. However, a few courageous people on the MTD mailing list have reported that they successfully inserted their DOC in a running system in this way to reprogram it.

  • If jumpers are available for configuring the address region to which the DOC device is mapped, you can try removing the jumpers completely and starting the system. In some cases, such as when using the ISA DOC evaluation board provided by M-Systems, this will result in the BIOS not recognizing the IPL and, hence, not running it. In other cases, however, this may result in a system hang. If this trick works for you, you will be able to boot the system using the BIOS's configuration. However, to access the DOC again once the system is running, you will have to insert the jumper while the system is powered on. Again, though this is reported to work, the hardware was not designed for this, I don't encourage you to do it, and I take no responsibility whatsoever for any possible outcome.

  • The configuration of GRUB allows it to use the ROM BASIC interrupt, INT 18h, instead of the bootstrap interrupt. Lately, in addition to being the ROM BASIC interrupt, INT 18h is sometimes used for network boot. When configured to use this interrupt, GRUB would kick in only if the BIOS configuration is set to network boot or if there are no boot devices set in the BIOS. This approach has a few drawbacks. First, it requires changing the BIOS configuration every time you want to switch from booting from the DOC to booting from a hard disk. This can be time-consuming during development. In addition, the use of INT 18h by recent BIOSes is not standardized, as the case of the BIOSes using it to provide network boot demonstrates.

  • Having seen the above choices while writing this book, your author decided to find a "cleaner" way of doing things. Hence, I set out digging in some of my old DOS and BIOS hacking books and came up with a solution that's both elegant and simple. Basically, instead of replacing the default bootstrap interrupt handler outright, my modified GRUB SPL makes a copy of the original handler, replaces it with the GRUB bootstrap handler, and lets the BIOS continue looking for other extensions in the system. When GRUB's bootstrap handler is invoked, it then checks whether the user is holding down the Ctrl key. If so, the original bootstrap handler is restored, and the BIOS is left to continue the bootstrap using the boot configuration chosen by the user. If the Ctrl key isn't held down, GRUB continues its normal procedure to load whatever is on the DOC. As you can see, this solution does not involve any dangerous hardware manipulations; save, maybe, for people suffering from carpal tunnel syndrome.

For obvious reasons, I strongly encourage you to use the last solution. This enhancement is, however, fairly recent at the time of this writing and you will only find it starting with GRUB patch grub-2002-10-08-doc.patch, which is available in the MTD CVS. I will explain how this option is enabled during GRUB's configuration in the next section.

Having covered the dangers of using GRUB to boot from a DOC, let's discuss the building, installation, and use of GRUB with a DOC.

9.4.1 Configuring and Building GRUB for the DOC

As I said earlier, you will need an x86 host to build GRUB. The following instructions assume that you are using such an x86 host. GRUB will fail to build or will create unusable binaries on any other type of host.

To start, download GRUB into your ${PRJROOT}/bootldr directory and extract it there. Then copy the GRUB patch from the ${PRJROOT}/sysapps/mtd/patches directory to the GRUB directory in ${PRJROOT}/bootldr. In the case of my DAQ module, for example, I used GRUB 0.92 and the grub-2002-02-19-doc.patch patch. Now apply the patch to GRUB:

$ cd ${PRJROOT}/bootldr/grub-0.92
$ patch -p0 < grub-2002-02-19-doc.patch

Because this patch was originally meant for GRUB 0.90, there were some warnings and one failure when applying it to 0.92. The failure in this case was in ChangeLog and can therefore be ignored.

If you want to use the Ctrl key method discussed in the previous section to avoid having to hotplug your DOC, use the grub-2002-10-08-doc.patch patch or a later version against a GRUB version retrieved from the CVS repository. Because the CVS repository is constantly changing, however, this patch may not apply cleanly to the latest CVS contents. To get the patch to apply as cleanly as possible and have the resulting source tree compile, for example, I had to retrieve the GRUB sources from the CVS repository as they were on October 10, 2002 and then manually edit a couple of files in the source code. To retrieve the code as it was on the date I mentioned, I used the following command:

$ cvs -z3 -d:pserver:anoncvs@subversions.gnu.org:/cvsroot/grub \
> co -D"10/10/02" grub

With the code patched, you are ready to build GRUB. First, create the Makefile using the automake tools:

$ aclocal && automake && autoconf

Now, configure GRUB to build for the DOC:

$ ./configure --enable-diskonchip-2000 \
> --enable-diskonchip-ctrlbypass \
> --enable-ext2fs \
> --disable-ffs --disable-xfs --disable-jfs --disable-vstafs \
> --disable-reiserfs --disable-minix --disable-fat

This command line disables GRUB's support for all filesystems except ext2 and enables support for the DOC 2000 device. It also enables the Ctrl key bypass method I described in the previous section using the - -enable-diskonchip-ctrlbypass option. There are a few other configuration options relevant to the DOC. If you are using DOC Millennium, for example, you may want to use the - -enable-diskonchip-mil256 or - -enable-diskonchip-mil512 option, depending on whether your DOC Millennium is using 256- or 512-byte page sizes. You can also use the - -enable-diskonchip-biosnetboot option to boot GRUB on the network boot interrupt instead of the bootstrap interrupt as described earlier. For a complete description of the options available for configuring GRUB for the DOC, have a look at the README_DiskOnChip created in the GRUB package directory when the DOC patch was applied earlier.

Once the configuration is done, you can build GRUB:

$ make

Once the compilation is done, the stage1/grub_firmware file will contain the GRUB image to be written to the DOC. Copy this file to ${PRJROOT}/images/grub_firmware-0.92 for future use:

$ cp stage1/grub_firmware ${PRJROOT}/images/grub_firmware-0.92

9.4.2 Installing GRUB on a DOC

I have already covered the installation of the GRUB bootloader image in Section Follow the instructions given in that section to install the GRUB image created here on your DOC device.

9.4.3 Configuring GRUB to Boot from a DOC

As with LILO, GRUB uses a configuration file to determine the boot media and kernel it has to boot. Unlike LILO, however, you do not need to run the GRUB binary to parse and update its configuration. Instead, the GRUB configuration file, menu.lst, is placed as-is in the /boot/grub directory of the target's root filesystem and is read by GRUB at startup. To configure GRUB to boot from a DOC, this is the file that we must create.

As an example, here is a simple menu.lst file for booting from a DOC device:

timeout 5
default 0
title DiskOnChip 2000 Boot
kernel (dc0,0)/boot/bzImage-2.4.18 root=/dev/nftla1
title HD Boot
kernel (hd0,0)/boot/bzImage-2.4.18 root=/dev/hda1

This file states that there are two boot possibilities. The first, which is also the default, involves booting kernel /boot/bzImage-2.4.18 from the first partition of the first DOC, dc0. The second involves booting a kernel by the same name as the previous item from the first partition of the first hard disk, hd0. For each configuration, the root= option indicates the device where the booting kernel will find its root filesystem.

This configuration is useful during development, since it allows you to choose between booting from the DOC and from your hard disk. On a production system, you probably want to remove the entry for the hard disk and set the timeout to zero so that booting from the DOC becomes the only possible option.

You can further modify GRUB's configuration and allow for a number of boot options. Look at GRUB's manual for a complete description of the configuration file format.