Penguin

InNeedOfRefactor

First draft:

Using GRUB to boot EPIA with > 130gb drive on secondary channel

This document is primarily written as an alternative for those experiencing the lilo 'L 99' error found under LiloNotes.

The guidance here resolves several issues for a specific situation. The configuration is such that we are using an EPIA M-II 10k motherboard with a CDR as IDE0 master and a > 136gb hard drive as IDE0 slave. A linux install is already laid out on the drive, but unaccessable due to boot loader issues.

Bios settings

The EPIA bios is unable to reliably identify the 203Gb drive I'm using; sometimes it will identify as 136gb, other times as 203gb. To resolve this, first go into the BIOS and set the drive to 'Manual' for primary slave.

Despite much documentation on the net regarding using LBA or Large mode, the bios will not reliably detect the disk with these options; the only way to hard code the sectors heads and cylinders is to use CHS. When setting CHS use bios autodetection to ensure the Capacity displayed is correct for your hard drive before saving. In my case that was 203Gb.

Interrogating your drive to discover layout

Next, boot from a linux ISO or floppy boot disk to get to a root shell prompt. 'fdisk /dev/hdb' followed by 'p' should show your layout. In my case, I had a 512 mb swap partition as /dev/hdb1 and the rest of the disk as a single boot partition called /dev/hdb2.

Mount your existing root partition and set it as root

This is done as follows; 'mkdir /mnt' will make a mount point if not already present.

Next, mount the partition displayed by fdisk, in this case hdb2, as follows: 'mount /dev/hdb2 /mnt'.

Finally, we set this as our root partition for further work. This will make life much easier as we will no longer load binaries from CDRom or floppy with the associated loading delays:

'chroot /mnt bash'

If you prefer ksh, sh, or another shell simply substitute its name for 'bash' in the above command.

We are now root editing our inaccessible system.

See if you have network connectivity

'ifconfig -a' will list network interfaces. If you don't see your local interface, either configure it up with 'ifconfig eth0 inet <ip address> netmask <netmask> up' and 'route add -net default gw <gateway>' or use the 'dhclient' command to retrieve an ip address from any local dhcp server.

Install grub

Documentation can be found at http://www.gnu.org/software/grub/. Using debian (or derivatives such as knoppix) I simply typed 'apt-get install grub'.

Configure grub

'grub-install --force-lba --no-floppy /dev/hdb' will install grub and layout the appropriate files under /boot. Under debian 'update-grub' will then build a menu of available kernel images, which can be edited under '/boot/grub/menu.list'. For non debian users typing

grub

followed by

root (hd0,1)
setup (hd0)

will install the basic grub bootloader without a menu. In the above example 'hd0' indicates our first hard drive (the cdrom is not included in that scan), '1' indicates our 2nd partition listed under fdisk (hdb2).

Note: grub starts counting partitions from 0, rather than 1, so fdisk hdb1 is grub partition (hd0,0), hdb2 is (hd0,1), etc. Grub also ignores extended partitions, so if you are using any you will need to subtract an additional 1 from the count.

Further changes

So far, so good - but what if the partitions you wish to boot are above the 136gb mark? At this point grub will give you 'Error 18', the bios does not support the cylinder that partition is present on.

To avoid this error, I repartitioned my drive as follows:

First, I stole 40mb from my swap partition to make a 'boot' partition within the first 1024 cylinders of the disk, those supported by the BIOS. To ensure no configuration changes were required, I did the following:

  1. Delete existing swap partition
  2. Create new swap partition 40mb smaller
  3. Create new boot partition within first 1023 cylinders
  4. set new swap partition to be of type swap
  5. write table
  6. Edit /etc/fstab and add a new line as follows:
/dev/hdb3  /boot  ext3  defaults                    0  1

Note: 'hdb3' will only be correct if you created your new boot space as partition three during the fdisk operations.

  1. Copy boot files over:
mount /dev/hdb3 /mnt
cd /boot
find . | cpio -pdv /mnt
umount /mnt
rm -rf *

Be very careful to ensure you only type the rm -rf command while still under the /boot directory, and that all the files successfully copied during the cpio stage.

At this point, either 'update-grub' under debian or 'system (hd0,2)' using the 'grub' command will set grub to boot off your new boot partition to load the kernel, allowing OS images to be above cylinder 1023.

Once again, edit your menu.lst file to ensure your OS entries list the correct partitions for the actual operating system images.

An example follows:

title           test, kernel 2.6.13.2-chw-3
root            (hd0,2)
kernel          /vmlinuz-2.6.13.2-chw-3 root=/dev/hdb2 ro
savedefault
boot

This line will provide a grub menu option titled 'test, kernel 2.6.13.2-chw-3' located on our new boot partition (hd0,2) (hard disk 0, fdisk partition , which we just created). Once located the kernel will be loaded with the line 'root=/dev/hdb2', telling it to find the rest of the operating system under linux hard disk hdb2. If you wish to create subsequent OS images to test other distros, os's or builds on, the kernel is simply loaded with a different root= argument.

Fdisk example:

The commands for fdisk are shown below:

fdisk /dev/hdb

The number of cylinders for this disk is set to 24792.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)

Command (m for help): p

Disk /dev/hdb: 203.9 GB, 203928109056 bytes
255 heads, 63 sectors/track, 24792 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id System
/dev/hdb1               1          65      522080+  82  Linux swap / Solaris
/dev/hdb2              66       23432   198619627+  83  Linux

Command (m for help): d
Partition number (1-6): 1

Command (m for help): n
Command action
   l   logical (5 or over)
   p   primary partition (1-4)
p
Selected partition 1
First cylinder (1-24792, default 1): 1

Last cylinder or +size or +sizeM or +sizeK (1-60): 60 <-- note we have reduced the cylinder count here by 5

Command (m for help): n
Command action
   l   logical (5 or over)
   p   primary partition (1-4)
p
Selected partition 1
First cylinder (1-24792, default 1): 61

Last cylinder or +size or +sizeM or +sizeK (1-60): 65

Command (m for help): t
Partition number (1-6): 1
Hex code (type L to list codes): 82
Changed system type of partition 1 to 82 (Linux swap / Solaris)

Command (m for help):w
partition written to disk

Command (m for help): q

Final words:

But... other distros? Our whole disk is eaten by hdb2. Well, ext2 and ext3 filesystems can be resized without losing data. To do so use the 'resize2fs' command; if your partition is ext3 you will need to disable journaling with the 'tune2fs -O ^has_journal /dev/hdX' command first, use resize2fs to shrink your disk spanning drive, then re-enable it once done using 'tune2fs -j /dev/hdX'.

Once resized use fdisk to delete the old partition data and recreate it starting at the same cylinder but finishing just above the new end point. This can be calculated by the following method:

(number of cylinders reported in fdisk) / (old size in blocks reported by 'fsck.ext2 /dev/hdb2') = cylinders per block
(new size in blocks reported by 'resize2fs /dev/hdb2 <size>') * (cylinders per block) = size of new partition in cylinders

So:

  1. Disable journaling with 'tune2fs -O ^has_journal /dev/hdX'
  2. fsck.ext2 -f /dev/hdX to check the filesystem is ok.
  3. resize2fs /dev/hdX <new, smaller, size>
  4. under fdisk, set the start partition to be the old starting cylinder, and define the size as +<size of new partition in cylinders> using the method described above.
  5. use fsck.ext2 to ensure your new size isn't smaller than the filesystem; if it is, fsck.ext2 will immediately quit warning you of this issue. If not, you're likely to have overshot by a few blocks.
  6. use 'resize2fs /dev/hdbX' to grow the filesystem to use the full size of the new partition,
  7. finally, re-enable journaling with the 'tune2fs -j /dev/hdX' command.

Note: this MUST be done with the drive unmounted - once again, boot off your cd or floppy, and work on the drive unmounted.

With your boot partition in the first 1023 cylinders as outlined above it is perfectly possible to place your subsequent OS layouts in extended partitions anywhere on the disk.

Create a new extended partition as partition 4, then divide up the space amongst as many drives as you like. I made two 5gb partitions for a 'stable' and 'test' OS image, while keeping /dev/hdb2 simply as a 'data' partition for my home directories and PVR recordings.

Once resized, my filesystem looked as follows:

Fdisk:

Disk /dev/hdb: 203.9 GB, 203928109056 bytes
255 heads, 63 sectors/track, 24792 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/hdb1               1          60      481918+  82  Linux swap / Solaris
/dev/hdb2              66       23432   187695427+  83  Linux
/dev/hdb3              61          65       40162+  83  Linux
/dev/hdb4           23433       24792    10924200    5  Extended
/dev/hdb5           23433       24112     5462068+  83  Linux
/dev/hdb6           24113       24792     5462068+  83  Linux

/etc/fstab for /dev/hdb6:

# filesystem  mountpoint  type  options  dump  pass
/dev/hdb6  /      ext3  defaults,errors=remount-ro  0  1
/dev/hdb3  /boot  ext3  defaults                    0  1
/dev/hdb2  /data  ext3  defaults                    0  2
/dev/hdb1 none swap defaults 0 0

proc  /proc  proc  defaults  0  0
sysfs /sys   sysfs defaults  0  0

/boot/grub/menu.lst:

default         0
timeout         5
color cyan/blue white/blue
title           stable, kernel 2.6.13.2-chw-3
root            (hd0,2)
kernel          /vmlinuz-2.6.13.2-chw-3 root=/dev/hdb6 ro
savedefault
boot
title           stable, kernel 2.6.13.2-chw-3 (recovery mode)
root            (hd0,2)
kernel          /vmlinuz-2.6.13.2-chw-3 root=/dev/hdb6 ro
savedefault
boot
title           test, kernel 2.6.13.2-chw-3
root            (hd0,2)
kernel          /vmlinuz-2.6.13.2-chw-3 root=/dev/hdb2 ro
savedefault
boot
title           test, kernel 2.6.13.2-chw-3 (recovery mode)
root            (hd0,2)
kernel          /vmlinuz-2.6.13.2-chw-3 root=/dev/hdb2 ro single
savedefault
boot

/boot/grub/device.map

(hd0)   /dev/hdb

Any questions, I'm at matt at clues dot com ;)