GRUB PXE network boot

From LinuxMCE
Jump to: navigation, search
Version Status Date Updated Updated By
710 Unknown N/A N/A
810 Unknown N/A N/A
1004 Unknown N/A N/A
1204 Unknown N/A N/A
Usage Information

The bootloader GRUB is able to boot using PXE as well. This can be a great alternative way to boot Media Directors for several reasons.

  • The PCs BIOS does not support or allow you to choose PXE netbooting.
  • The PC's BIOS does not support PXE directly and your PC does not have a hard drive (or has a very small capacity hard drive or hard drive you cannot or don't want to alter). You can use GRUB from a Floppy.
  • Your Ethernet network interface card does not have a PXE-ROM in it.
  • Very few wireless cards have a PXE-ROM chip in them. Older wired Ethernet cards also may not have a PXE-ROM chip in them.
  • Both LinuxMCE and a native OS are installed on different partitions. The GRUB bootmenu can be used to decide whether to boot LinuxMCE or the native OS.
  • Booting is a lot faster when you boot the native OS on your hard drive instead of over the network.
  • GRUB allows for easy adjustments of the boot parameters during bootup.


Prerequisites

  1. The GRUB sources (although GRUB is included in almost all standard Linux distributions, this tutorial installs GRUB as a standalone package from source.)
  2. A development environment capable of building GRUB from source. In general, this implies you have a way to install GRUB, such as a running Linux OS (LiveCD?) (GRUB is automatically installed by most Linux distributions when multiple partitions and OSs are installed on the same PC.)
  3. Knowledge of the specifications of the (supported) Ethernet card in the PC you want to netboot.

Obtaining GRUB source files

  1. Untar the GRUB sources somewhere and move into the newly created directory.
  2. Read The netboot/README.netboot file for additional information on what to specify for which network adapter.
  3. Configure the GRUB build
  4. Build GRUB from source.

Example: Using grub-0.97 with an old Realtek 8139 NIC Ethernet card:

tar xvf grub-0.97.tar.gz
cd grub-0.97
less netboot/README.netboot # make a note of the option you need for your network interface
./configure --prefix=/usr --enable-diskless --enable-rtl8139 # That's the one I needed
make # if this fails see "known problems" below for a possible fix.

WARNING: Do not run make install (as root) unless you want this version to overwrite the existing one on your system.

Install GRUB

You have several options here, basically this version of GRUB works just like the regular version so it can be put on floppy, USB stick, CDRom, Harddrive, etcertera. Please add other examples as you try them.

Install GRUB on a floppy disk using the "extended-2" (ext2fs) filesystem

A better way to do this would be to use the minix-filesystem to save some precious space, one might even be able to squeeze a kernel in, but ext2fs fits my needs as all I want is GRUB so I couldn't be bothered. Before doing this you should have moved to the directory where you built GRUB, obtained root privileges and inserted a writable floppy disk in the drive, WARNING:its current contents will be lost during this procedure unless you skip the first step.

  1. format the floppy
  2. create a directory to mount it on
  3. mount the floppy
  4. install GRUB on the floppy directly
  5. create the boot/grub directory on the floppy
  6. hard link some files into the boot/grub directory
  7. copy the example menu.lst
  8. install GRUB onto the bootsector of the floppy
mkfs.ext2 /dev/fd0
mkdir -pv floppy
mount /dev/fd0 floppy
make install DESTDIR=`pwd`/floppy
mkdir -pv floppy/boot/grub
ln -v floppy/usr/lib/grub/i386-pc/{stage1,e2fs_stage1_5,stage2} floppy/boot/grub/
cp -v docs/menu.lst floppy/boot/grub
umount floppy
grub/grub
    GNU GRUB  version 0.97  (640K lower / 3072K upper memory)

 [ Minimal BASH-like line editing is supported.  For the first word, TAB
   lists possible command completions.  Anywhere else TAB lists the possible
   completions of a device/filename. ]

 grub> root (fd0)
  Filesystem type is ext2fs, using whole disk
 
 grub> setup (fd0)
  Checking if "/boot/grub/stage1" exists... yes
  Checking if "/boot/grub/stage2" exists... yes
  Checking if "/boot/grub/e2fs_stage1_5" exists... yes
  Running "embed /boot/grub/e2fs_stage1_5 (fd0)"... failed (this is not fatal)
  Running "embed /boot/grub/e2fs_stage1_5 (fd0)"... failed (this is not fatal)
  Running "install /boot/grub/stage1 (fd0) /boot/grub/stage2 p /boot/grub/menu.lst "... succeeded
 Done.
 
 grub> quit

You should be all set now. The only thing left is to edit the menu.lst file to your liking.

Configure GRUB to boot from the network

You will need to edit the boot/grub/menu.lst file for this.

This is an example for adding a new Media Director. First I added this as the top "target":

title New Media Director
dhcp
root (nd)
kernel /tftpboot/default/vmlinuz root=/dev/nfs acpi=off vga=normal ramdisk_size=10240 rw ip=all apicpmtimer
initrd /tftpboot/default/initrd

And here is what I added above that for one of my Media Directors (device #100), lateron after it was added to the system:

title moon100
dhcp
root (nd)
kernel /tftpboot/100/vmlinuz ramdisk=10240 rw root=/dev/nfs boot=nfs nfsroot=192.168.80.1:/usr/pluto/diskless/100
initrd /tftpboot/100/initrd.img

After modifying the boot/grub/menu.lst there is no need to run or install GRUB itself again. This floppy can now be used not only to boot but also to install GRUB on other systems or media.


Known Problems

Building fails with newer version of GCC

When using version 0.97 in combination with a modern version of the Gnu Compiler Collection (GCC) the build is likely to fail, which goes a little like this:

make[2]: Entering directory `/mnt/sda8/usr/src/PMS/Building/grub-0.97/netboot'
if gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../stage2 -I../stage1  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef -Os -fno-stack-protector -fno-builtin -nostdinc -DFSYS_TFTP=1 -DINCLUDE_RTL8139=1 -DCONGESTED=1 -DNE_SCAN=0x280,0x300,0x320,0x340 -DWD_DEFAULT_MEM=0xCC000 -g -MT libdrivers_a-main.o -MD -MP -MF ".deps/libdrivers_a-main.Tpo" -c -o libdrivers_a-main.o `test -f 'main.c' || echo './'`main.c; \
       then mv -f ".deps/libdrivers_a-main.Tpo" ".deps/libdrivers_a-main.Po"; else rm -f ".deps/libdrivers_a-main.Tpo"; exit 1; fi
main.c:57: error: static declaration of 'bootp_data' follows non-static declaration
./etherboot.h:534: error: previous declaration of 'bootp_data' was here
main.c:59: error: static declaration of 'end_of_rfc1533' follows non-static declaration
./etherboot.h:536: error: previous declaration of 'end_of_rfc1533' was here
main.c: In function 'udp_transmit':
main.c:231: warning: pointer targets in passing argument 1 of 'eth_transmit' differ in signedness
main.c:276: warning: pointer targets in passing argument 1 of 'eth_transmit' differ in signedness
main.c:290: warning: pointer targets in passing argument 1 of 'eth_transmit' differ in signedness
main.c: In function 'tftp':
main.c:462: warning: pointer targets in passing argument 1 of 'fnc' differ in signedness
main.c: In function 'rarp':
main.c:509: warning: pointer targets in passing argument 1 of 'eth_transmit' differ in signedness
main.c: In function 'udpchksum':
main.c:729: warning: dereferencing type-punned pointer will break strict-aliasing rules
main.c: In function 'await_reply':
main.c:893: warning: pointer targets in passing argument 1 of 'grub_memcmp' differ in signedness
main.c:895: warning: pointer targets in passing argument 1 of 'grub_memcmp' differ in signedness
main.c:925: warning: pointer targets in passing argument 1 of 'decode_rfc1533' differ in signedness
main.c: In function 'decode_rfc1533':
main.c:973: warning: pointer targets in passing argument 1 of 'grub_memcmp' differ in signedness
main.c:973: warning: pointer targets in passing argument 2 of 'grub_memcmp' differ in signedness
main.c:984: warning: pointer targets in passing argument 1 of 'grub_memcmp' differ in signedness
main.c:1057: warning: pointer targets in passing argument 1 of 'grub_memcmp' differ in signedness
main.c:1057: warning: pointer targets in passing argument 2 of 'grub_memcmp' differ in signedness
make[2]: *** [libdrivers_a-main.o] Error 1
make[2]: Leaving directory `/mnt/sda8/usr/src/PMS/Building/grub-0.97/netboot'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/mnt/sda8/usr/src/PMS/Building/grub-0.97'
make: *** [all] Error 2

No need to panic, this is basically just the GCC maintainers letting the GRUB developers know they need to clean up their code. Just throw (copy+paste) this command in the mix in order to fix the collateral damage:

patch -Np1 << EOF
--- grub-0.97.orig/netboot/main.c       2004-05-21 00:19:33.000000000 +0200
+++ grub-0.97/netboot/main.c    2007-07-20 02:31:28.000000000 +0200
@@ -54,9 +54,9 @@
 
 static int vendorext_isvalid;
 static unsigned long netmask;
-static struct bootpd_t bootp_data;
+struct bootpd_t bootp_data;
 static unsigned long xid;
-static unsigned char *end_of_rfc1533 = NULL;
+unsigned char *end_of_rfc1533 = NULL;

 #ifndef        NO_DHCP_SUPPORT
 #endif /* NO_DHCP_SUPPORT */
EOF

All this does is remove the keyword "static" from 2 lines of code. Now you can continue where it left off by issuing the make command again.

Can't I just use yours?

My version (in the example) is specific for my Realtek 8139 network interface card.

If you happen to use that card, you are welcome to download an image of the floppy I just created (verifying the steps) and write it to a floppy:

dd if=grub-0.97--enable-diskless--enable-rtl8139.floppy.img of=/dev/fd0

Or mount it using a loopback device:

modprobe loop
mkdir floppy
mount grub-0.97--enable-diskless--enable-rtl8139.floppy.img floppy -o loop

Further utilities to read about