Monday, December 8, 2008

Grub repair for Ubuntu

In my experience, Ubuntu is the most trouble-free Linux distribution. That being said, there is a fundamental issue with the Grub boot loader that can cause issues with some types of hardware that doesn't fit into the mold of the "typical desktop machine". There are basically two types of hardware that have the "issue": a. Early SATA controllers that emulate IDE and b. Other various machines that try to manage controller order in the BIOS. This causes a conflict between the ordering of the hard drive controllers between the BIOS vs. the PCI bus.

When Grub loads at boot time, it does not know what /dev/sda1, /dev/hda1, /dev/cciss/c0d0p1, or /dev/{anything} are. The kernel and udev need to be loaded before those devices exist, so Grub has to rely on the BIOS to get its information about which devices are available to get a kernel booted. On systems with a more-or-less linear boot order, this is not an issue. However, sometimes the BIOS can be set to a different boot order than the Linux kernel will agree with. Once the BIOS passes control of the boot process to the kernel, the kernel no longer requires the help of the BIOS at all (unless compiled in an unusual way). It can look directly at the PCI bus to figure out the order of the disks.

Grub and the Linux Kernel use different naming schemes for hard disks. Since Grub is all BIOS-based, SCSI vs. IDE are not an issue. All hard drives are (hdD,P) where "D" is the disk number and "P" is the partition number. These start with Zero, so if you are used to referring to a partition as /dev/sda2 it will be (hd0,1) and /dev/sdb1 will be (hd1,0).

Linux Kernel Hard Disk Devices:
    /dev/TdDP
where
    "T" is the type of driver used (s for SCSI or h for IDE)
    "D" is the disk letter, starting with a
    "P" is the partition number, starting with 1
Example: /dev/sdb2 == SCSI driver, Second disk, Second partition


Linux Kernel Hard Disk Devices: (Some RAID arrays)
    /dev/cciss/cCdDpP
where
    "C" is the number of the controller, starting with 0
    "D" is the disk number, starting with 0
    "P" is the partition number, starting with 1
Example: /dev/cciss/c0d1p2 == RAID Array, First controller, Second disk, Second partition

Grub Hard Disk Devices:
    (hdD,P)
where
    "D" is the disk number, starting with 0
    "P" is the partition number, starting with 0
Example: (hd1,0) == Second drive, First partition


Here is the part of the Ubuntu installer where things can get messed up:


If (hd0) happens to be on a different controller than will be booted to, the boot process will fail. This requires some very manual intervention. I will go through this step-by-step.

Boot to a Live CD of your choice. For the purposes of this tutorial I will use an Ubuntu 8.10 Live CD.
Choose "Try Ubuntu without any change to your computer":

When the CD starts up, open a Terminal window:


To become a super user, type:
    sudo su -
Change to the /mnt directory, where we will be doing most of the work
    cd /mnt
List the available partitions in the system:
    fdisk -l
Based on the list of partitions, create a directory under /mnt with an appropriate name, for example:
    mkdir sda1
Mount the partition to this directory:
    mount /dev/sda1 sda1
Verify this is indeed the partition you wanted to mount:
    ls sda1

Bind-Mount the existing /dev, /proc, /sys (located in RAM) to the /dev, /proc, /sys folders on the partition you just mounted:
    mount --bind /dev /mnt/sda1/dev
    mount --bind /proc /mnt/sda1/proc
    mount --bind /sys /mnt/sda1/sys


Enter a chroot environment. This tells the kernel that within this environment, it will assume a new path is the root of the filesystem. The above filesystems will now be available in this new environment:
    chroot sda1

With your favorite text editor (beginners should use "nano", help is at the bottom of the screen) edit the file /etc/fstab:
    nano /etc/fstab
You should see a string similar to this: "UUID=c6d12c7f-fac9-4e0b-b86a-4e0b4cd5b29b" with a slash "/" next to it.  Replace it with the kernel's version of the root "/" partition.  For example:
    /dev/sda1 / ext3 relatime,errors=remount-ro 0 1
Do the same for the swap partition:
    /dev/sda5 none swap sw 0 0
This certainly cleans up the file a bit, as well as helps if you are planning on making a disk image of this system and need to put it in a different system on a different hard drive.  Save and exit.  (in nano this is accomplished with <Ctrl>-<x> followed by a "y" to the question of whether to save)
Enter the Grub shell:
    grub

Get a listing of your available partitions:
    root (hd<tab><tab>   (don't press enter)
Based on the output of the above command, note the grub disk name for the root (/) partition, for example (hd0,0).
Quit Grub
    quit

With your favorite text editor, edit the file /boot/grub/menu.lst:
    nano /boot/grub/menu.lst
Page down to the end of the file.  There should be three entries, each beginning with a "title" line.  Comment out (Put a # in front of) the line that starts with "uuid".  Do this for all three entries:
    #uuid c6d12c7f-fac9-4e0b-b86a-4e0b4cd5b29b
In the first two entries, there is a line that begins with "kernel".  On this line you will find a string similar to "root=UUID=c6d12c7f-fac9-4e0b-b86a-4e0b4cd5b29b".  Change this to "root=/dev/TdDP" based on the kernel name of your root (/) partition.  (see chart at top of article, example is /dev/sda1)  Also, add a line above the "kernel" line to point grub to the partition in the format "root (hdD,P). (see chart at top of article, example is root (hd0,0)):
    root (hd0,0)
    kernel    /boot/vmlinuz-2.6.27-7-generic root=/dev/sda1 ro quiet splash

Repeat this step for the recovery mode entry:
    root (hd0,0)
    kernel    /boot/vmlinuz-2.6.27-7-generic root=/dev/sda1 ro single

Save and exit this file.
Now, run the Grub shell again:
    grub
Enter the root partition that contains menu.lst, in Grub format:
    root (hd0,0)
Install Grub into the master boot record of the hard disk:
    setup (hd0)
Quit Grub:
    quit
Exit the chroot environment:
    exit

List your mount points:
    mount

You will get a long list of all the mounts that have been done in the Live CD environment.  We are only concerned with the last 4 displayed.  Start at the bottom and work your way up the list, unmounting only the mount points, not the devices:
    umount /mnt/sda1/sys
    umount /mnt/sda1/proc
    umount /mnt/sda1/dev
    umount /mnt/sda1

Exit the superuser environment:
    exit
Exit the shell:
    exit

Finally, restart your system and cross your fingers:

Monday, July 21, 2008

TheRantBastard's Ubuntu Linux Success Story

There are a lot of techie reviews of Linux distributions out there. Techies are the ones that usually read, write, (and flame) these reviews. This is a good success story of a Windows user's Linux experience. Hopefully this will have a little more weight than just me preaching to the choir.

I have been installing Ubuntu on various peoples' machines for about a year now and have had almost no complaints. Occasionally I will get a question about the nature of how to do some sort of maintenance (such as installing an anti-virus product) only to inform them that said maintenance is not necessary. I must admit this lack of support calls surprised me.

One particular friend I gave Ubuntu to was on a testing contract at Microsoft and said he was "fed up" with all Microsoft has to offer and wished there was an alternative. As you might imagine, there was no way out of the discussion at this point. Since he only had one home machine, a laptop, I initially offered to set up a Dual-Boot environment on it. He said "No way, I don't want any Microsoft products on my machine any more." Although he had never used Linux before, he was not a complete novice when it came to computers in general, so I explained the technical barriers he might run into with a Linux-only setup. I told him that he might have trouble with his scanner, printer, camera, sound, and video. I refused to wipe his machine until he assured me he had burned all his data to CDs, and had his XP and Office software available in case we needed to back out of the whole ordeal. When he promised this had been done, I went over to his house and ran a standard Ubuntu 7.04 Live CD.

I was shocked at how well it worked with the hardware even before the installation. Sure enough, after I had installed it, every single piece of hardware in the system worked flawlessly. His Camera, Webcam, Scanner, Printer, and Video chipset were all detected and working without any intervention at all. He was absolutely dazzled by all of this, and couldn't believe something that is free was able to "just work" right out of the box. He was used to fighting with Windows drivers for years. I was taken back myself, until then I hadn't had a system work that well with Linux. I am used to either a. building Linux from source code or b. using distros that were not anywhere near this good with hardware.

I had to call him the other day just to see if he was still alive, or more important for this article, if his Linux machine was still up and running. He said he never has to do any troubleshooting. He just allows the updates to continue. He has been allowing the package manager to perform dist-upgrades since 7.04 and the same installation of Ubuntu is now running 8.10. He said it feels like it is just a snappier, more refined version of the original each time an upgrade occurs. This is impressive when you think about the move from 7.10 to 8.04, which had many fundamental changes.

I find it necessary to tell this story when someone at work or otherwise insists that "Linux isn't ready for users". If by users they mean cutting-edge gamers that require only the most updated DirectX-capable machine, then no it is not ready for them. The gaming market is the last stand for user adoption. I admit I have a Windows XP Home dual-booted with my main Desktop machine. I only use it for playing a Windows game when I can't get it to work with Wine. Some of my Windows games (Call of Duty 2 for example) actually run better in Wine than in Windows. If more games are written with this level of compliance, I see an interest in game studios porting their game engines to Linux (SDL or OpenGL). Most of the work in creating a game goes into creating the universe with graphics and audio, which are just pieces of data that care not what operating system they are being run on.