Research and Development

How to Boot LTSP Clients From Local Harddrive Using Grub

Sometimes PXE booting LTSP clients is not possible - e.g. if the device doesn’t have PXE enabled NIC. If the client device has a local harddrive, it’s possible to install the image locally and use Grub to boot it. Everything else works still the same, just kernel loading and NBD mount are replaced by using the local harddrive. The image is placed on the harddrive as a single file and it is not uncompressed.

This does not make the LTSP client mobile and it still requires wired network connection to work. Changing the image not to require a wired connection is possible, though.

Grub and image can be installed e.g. with a live CD or a live USB stick or even by first PXE booting the device and then using the LTSP client itself to do the installation.

The testing here was done with Ubuntu 13.10 live CD and the internal harddrive was completely formatted using traditional DOS partition table. If you are using Ubuntu to do this, Ubuntu 12.10 or newer is required as Grub version in Ubuntu 12.04 is too old for loading kernel and initramfs image from loopback mounts.

Partitioning

First we need to create a partition that holds the image. The partition can be either normal partition or LVM partition. You can use e.g. fdisk or cfdisk to create the partitions.

A single partition is enough, but if you want to also enable local swap, it might be a good idea to create a second swap partition.

1
2
3
4
5
6
7
8
9
10
11
12
13
# fdisk /dev/sda

Command (m for help): p

Disk /dev/sda: 128.0 GB, 128035676160 bytes
97 heads, 20 sectors/track, 128901 cylinders, total 250069680 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xd16eac62

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048    62916607    31457280   83  Linux

After creating the partition you need to format it and mount it somewhere (here /mnt/disk):

1
2
3
4
mkfs.ext4 /dev/sda1

mkdir -p /mnt/disk
mount /dev/sda1 /mnt/disk

To get Grub installed on the disk, we need call grub-install command, that creates boot directory under the specified root directory path:

1
grub-install --root-directory=/mnt/disk/ /dev/sda

There should be now files under /mnt/disk/boot/.

Now you need to somehow copy the i386.img file from the LTSP server to /mnt/disk/.

Next we need a custom grub.cfg file that tells Grub how to load the kernel and initrd.img from inside the LTSP image. Below is a basic example that does that. Replace (hd0,1) with the partition you are using. The syntax is specified here: http://www.gnu.org/software/grub/manual/grub.html#Device-syntax

/mnt/disk/boot/grub/grub.cfg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
set default="0"

function load_video {
  if [ x$feature_all_video_module = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
  fi
}

if loadfont unicode ; then
  set gfxmode=auto
  load_video
  insmod gfxterm
  set locale_dir=$prefix/locale
  set lang=fi_FI
  insmod gettext
fi
terminal_output gfxterm

insmod gzio
insmod part_msdos
insmod ext2
insmod squash4
insmod biosdisk
insmod regexp
insmod loopback
insmod usb_keyboard
insmod lvm

menuentry "LTSP local image" {
    loopback loop "(hd0,1)/i386.img"
    set root='(loop)'

    linux   /boot/vmlinuz ro quiet splash init=/sbin/init-ltsp root=/dev/sda1 loop="i386.img"
    initrd  /boot/initrd.img

    loopback -d loop
}

That’s it. Unmount /mnt/disk and reboot from the local harddrive. If you want to update the image, you can copy new i386.img to the harddrive. No other changes are needed.

1
umount /mnt/disk

Comments