How to install Grub built by the Factory

Purpose

This document outlines a reference procedure for installing the Grub bootloader built by the Desktop factory to a boot device for the target board.

Prerequisites

  • x86 Host Machine
  • x86 Target Machine
  • Root file system with the following options
    • bash (needed for chroot)
    • grep (needed for grub-install)
    • gettext (optional, if you want to use grub-mkconfig to automatically generate a grub menu entry)
    • Target Software->Kernel->Include kernel image within the RFS

Procedure

Attach volume to host machine

If you are using USB stick, Compact Flash, SD, or hard drive, connect it to the host. Determine the device node using dmesg, and unmount any volumes that auto-mount. For the purposes of this document, we assume /dev/sdX is the name of the disk.

Create a Linux partition on the device for the RFS.

  1. Create a Linux partition for the RFS using fdisk.
    $ sudo fdisk /dev/sdX
    • Type o to create a new partition table.
    • Type n to create a new partition.
    • Type p to select a primary partition type.
    • Accept the defaults for Partition Number, First Sector, and Last Sector.
    • Type w to write the new partition table.
  2. Format the new partition using mkfs.ext4.
    $ sudo mkfs.ext4 /dev/sdX1

Initialize the RFS contents

  1. Mount the volume:
    $ sudo mount -t ext4 /dev/sdX1 /rfs
  2. As root, extract the RFS output tarball into the mount point:
    $ sudo tar -xf /path/to/factory/build_*/images/rfs/rootfs.tar.gz -C /rfs
  3. Copy the kernel to the volume and rename it to vmlinuz for autodetection:
    $ sudo mkdir -p /rfs/boot/
    $ sudo cp /path/to/factory/build_*/images/bzImage-<version> /rfs/boot/vmlinuz-<version>
    

Use chroot to install grub to the device

  1. Enter the RFS directory:
    $ cd /rfs
  2. Bind mount the /dev, /sys, and /proc directories. This allows you to access your system from the chroot jail.
    $ sudo mount --bind /dev ./dev
    $ sudo mount --bind /sys ./sys
    $ sudo mount --bind /proc ./proc
    
  3. Enter the chroot jail:
    $ sudo linux32 chroot .
  4. Install grub to your Linux partition:
    # grub-install /dev/sdX

Create a grub.cfg file under /boot/grub

Note: In order for grub-mkconfig to automatically detect the kernel image, it must be named renamed vmlinuz-<version>. Otherwise you can manually add the menuentry pointing to bzImage. Automatic detection requires gettext to be installed on the target.

# grub-mkconfig > /boot/grub/grub.cfg

Exit chroot and unmount dev, sys, and proc

# exit
$ sudo umount ./dev
$ sudo umount ./sys
$ sudo umount ./proc

Cleanup grub.cfg to match target boot device

At this point you should edit the grub.cfg to set the root device correctly. Due to the bind mounted device tree, the generated grub.cfg will specify the wrong root. For example, the generated file may show:

set root='(hd1,1)'

Edit the file to show (This can be done outside chroot also):

set root='(hd0,1)'

(OPTIONAL) Manually add a menu-entry to grub.cfg

Enter an entry like this between the 10_linux lines.

### BEGIN /etc/grub.d/10_linux ###
menuentry 'Timesys' --class gnu-linux --class gnu --class os {
   linux /bzImage <kernel-arguments>
}
### END /etc/grub.d/10_linux ###

Cleanup

Now unmount the device, and connect it to the target system:

$ cd /
$ sudo umount /rfs