Diskless Booting

From OSDev Wiki
Jump to navigation Jump to search

"Diskless Booting" is a synonym for booting across a network. The kernel and its modules are downloaded from a computer on the network. This can be very useful for large projects where Bochs is too slow or one has to use a floppy disk, and is used in some corporate environments to enable centralized OS updates.

In order to boot up your kernel by network, you need a DHCP server, a TFTP server, and a program acting as client on the other computer.

The GRUB Legacy Way

First, you have to create a floppy with GRUB Legacy configured for net support. You can download a current source release of GRUB Legacy and ./configure it with support for your NIC.

Although this is the simplest way, GRUB Legacy doesn't seem to support all network cards.

The PXELINUX Way

Compile syslinux; a pxelinux.0 file will be created. It is a PXE binary of a simple bootloader-over-tftp, which can be booted by the client computer (not the one with the TFTP server). After setting up DHCP and TFTP accordingly so the file boots, you can use pxelinux to load "memdisk", which comes with syslinux as well.

This file is loaded with a memdisk initrd=grub.ima syntax, which will cause pxelinux to load memdisk and grub.ima through TFTP. Memdisk will hook interrupt 0x13, and boot the disk image that way. (However, not all GRUB Legacy disk images seem to access floppies through bios. If you've got such an image you're stuck.)

You should get a pxelinux.0 file, which can be loaded by, for example, etherboot. Many modern computers allow booting from NICs so you only need the TFTP and DHCP server up.

At this point, you can make changes to the grub.ima disk image, and put a GRUB Legacy config file and your kernel's binaries there.

Try mount /tftpboot/grub.ima /mnt/fpy -o loop under linux, for example.

The gPXE + GRUB Way

GRUB since version 2 can piggy-back on gPXE's network support, unlike GRUB Legacy that does not support newer network cards. The gPXE project is a currently-maintained, open source, free network bootloader. It is easy to get gPXE ISO, disk, or USB disk images from their website, but there is a workaround you need to apply in order to get GRUB to successfully load.

gPXE supports multiboot, but if it detects a multiboot image then it will not provide PXE services. Unfortunately, it detects your generated GRUB image as multiboot, and the only way I found to get around this was to recompile gPXE without multiboot support. Recompiling gPXE is easy: unpack it, cd src; make. Before you do that, you will want to edit src/config/defaults/pcbios.h and comment out the line that defines IMAGE_MULTIBOOT. After compiling you should be left with bin/gpxe.{dsk,iso,usb} which you can write to disk or CD.

To create a GRUB PXE bootable image, you can follow the advice in the GRUB manual's Network chapter. Several of the options to grub-mkimage did not exist in past versions and you need to upgrade if they aren't supported. If you compile from source, you can get all the *.{lst,mod,img} files you need in the source directory. In the case you compile your own GRUB you do not need to install it, just do commands like this:

./grub-mkimage -d . --format=i386-pc --output=core.img --prefix="(pxe)/boot/grub" pxe pxecmd
cat pxeboot.img core.img > grub2pxe

The final thing you need to do is setup a DHCP/BOOTP/TFTP server. I used dnsmasq which came preinstalled on my workstations, and seems to be widely available in distributions. It can easily be configured on the command line or in /etc/dnsmasq.conf which uses the same syntax as the long-form command-line options but without the leading dashes. You will need the following options:

interface=...                # be careful what interface the dhcp server runs on!
bind-interfaces              # *really* only bind that interface
dhcp-range=a.b.c.d,e.f.g.h   # whatever your private network uses
dhcp-boot=boot/grub/grub2pxe # tells machine to boot grub
dhcp-no-override             # some kind of workaround that gpxe needs
enable-tftp
tftp-root=/tftp              # or wherever

and there are other options to explore as well. Now make sure that you take grub2pxe,*.lst,*.mod from the GRUB source and put them in /tftp/boot/grub or equivalent. Also put your grub.cfg file there. The format of that is fairly simple. Here's the essence of what I use:

set timeout=0
set default=0
menuentry "MY OS" {
  set root=(pxe)
  multiboot /kernel
  module    /shell
  module    /test
}

Make sure your kernel and modules appear in the tftp root, and you should be set to boot using your gPXE media, over a private network connection hooked up between workstations.

The Direct Way

Main article: PXE

Both of the options above involve using someone else's code to do the dirty work, which may be undesirable in some situations - licensing conflicts, technical problems (e.g. for "memdisk" the interrupt 0x13 hook won't work in protected mode) and possibly personal pride. Fortunately, writing your own PXE boot code isn't as difficult as it sounds.

At first glance the PXE specification can look rather daunting, however most of it relates to BIOS and network cards and can be safely ignored. The important part is in chapter 3, the PXE API.

The PXE API is capable of doing raw UDP connections among several other things, however, for a start, you might just want to read files using TFTP.

See Also

External Links