======PXEGRUB======
=====Overview=====
Our predominant exposure to GRUB has been as the common boot loader used with Linux, installed on the Master Boot Record (MBR) of the hard drive. This, however, is not the only way we can utilize GRUB.
This document will explore setting up GRUB2 (1.99) to be used via DHCP and PXE for use in network-based operation.
=====Premise=====
I discovered that information on successfully setting up GRUB with PXE was horrendously scant, lacking, and even unclear due to lack of differentiation between GRUB1 and GRUB2 details.
After far too much time scouring the internets and getting stuff figured out, I figured the world needed at least one document that can plainly walk someone through the process from start to finish, functionally lowering the bar of entry to PXE GRUB utilization.
=====Step -1: Deploy development environment/VM=====
Because GRUB is the common boot loader used on Linux systems, and since we'll be compiling a fresh copy, I wanted to avoid screwing up the system-installed GRUB.. so I deployed a virtual machine to be host to the compiling, installing, and netdir creation.. this way, if anything went wrong, all I'd be out is a virtual machine (that can be easily discarded and recreated) versus potentially hosing a production server.
Even though it seems that these instructions and resulting operations do not interfere with the system installed grub, I figure it is better to be safe than sorry.
=====Step 0: Obtain GRUB=====
The first order of business, I realized, was the need to compile GRUB from source, due to the apparent omission of the **grub-mknetdir** script and who knows what else (note that in retrospect, this whole thing can //probably// be done with the default GRUB deployment on a Linux system).
====Grab the stable source====
First off, I grabbed the source:
machine:~$ wget ftp://ftp.gnu.org/gnu/grub/grub-1.99.tar.gz
--2011-08-11 10:23:04-- ftp://ftp.gnu.org/gnu/grub/grub-1.99.tar.gz
=> "grub-1.99.tar.gz"
Resolving ftp.gnu.org... 140.186.70.20
Connecting to ftp.gnu.org|140.186.70.20|:21... connected.
Logging in as anonymous ... Logged in!
==> SYST ... done. ==> PWD ... done.
==> TYPE I ... done. ==> CWD (1) /gnu/grub ... done.
==> SIZE grub-1.99.tar.gz ... 4652619
==> PASV ... done. ==> RETR grub-1.99.tar.gz ... done.
Length: 4652619 (4.4M) (unauthoritative)
100%[================================================>] 4,652,619 477K/s in 10s
2011-08-11 10:23:15 (445 KB/s) - "grub-1.99.tar.gz" saved [4652619]
machine:~$
Extract the source:
machine:~$ tar -zxvf grub-1.99.tar.gz
grub-1.99/
grub-1.99/ABOUT-NLS
grub-1.99/AUTHORS
grub-1.99/COPYING
grub-1.99/INSTALL
grub-1.99/README
grub-1.99/THANKS
grub-1.99/TODO
grub-1.99/acinclude.m4
grub-1.99/build-aux/
grub-1.99/build-aux/arg-nonnull.h
grub-1.99/build-aux/c++defs.h
...
grub-1.99/stamp-h.in
grub-1.99/autom4te.cache/
grub-1.99/autom4te.cache/requests
grub-1.99/autom4te.cache/traces.0
grub-1.99/autom4te.cache/output.0
grub-1.99/autom4te.cache/traces.1
grub-1.99/autom4te.cache/output.1
grub-1.99/config-util.h.in
machine:~$
And change into the newly created **grub-1.99** directory:
machine:~$ cd grub-1.99
machine:~/grub-1.99$
=====Step 1: Build/Deploy GRUB=====
We will now proceed to compile a fresh copy of our newly downloaded GRUB source.
====Install necessary prerequisites====
The **grub-1.99/INSTALL** file indicates the need for certain packages/libraries to be installed.
machine:~/grub-1.99$ sudo aptitude install build-essential gawk libfreetype6-dev libfreetype6 libdevmapper libdevmapper-dev make
...
machine:~/grub-1.99$
====Run the configure script====
GRUB2 has made improvements where, for what I wanted (PXE GRUB), no changes in options were needed when running configure, so just run it:
machine:~/grub-1.99$ ./configure
...
machine:~/grub-1.99$
====Build it====
Assuming all has gone according to plan, we simply type '**make**' to commence the build process:
machine:~/grub-1.99$ make
...
machine:~/grub-1.99$
Note that there is a **make check** option that can be invoked, which performs various tests on our GRUB build; when I did this, 20 out of 25 tests failed, but the end result still worked.
====Install it====
Assuming the original **make** successfully built grub, let us go ahead and install it (it should install into **/usr/local**, with the bulk of the binaries in **/usr/local/bin** and **/usr/local/sbin**):
machine:~/grub-1.99$ sudo make install
...
machine:~/grub-1.99$
=====Step 2: Create GRUB net directory=====
To avoid complications with any existing GRUB installation, I opted to have it do its magic in a special **/pxe** directory, so that any confusion over differing versions or files would be minimized.
Using the **grub-mknetdir** script, do the following:
machine:~$ sudo /usr/local/sbin/grub-mknetdir --net-directory=/pxe
Netboot directory for i386-pc created. Configure your DHCP server to point to /boot/grub/i386-pc/core.0
machine:~$
If you look, a **/pxe** directory has been created and contains goodies within (**/pxe/boot/grub/i386-pc**)
=====Step 3: Put GRUB under tftpboot dir on fileserver=====
Because the fileserver acts as the TFTP server for netboots, place the contents of **/pxe** (that would be **/boot** and descendants) in the root of the tftpboot directory-- in our case, that would be **/export/tftpboot**.
I accomplished this via tarring it, scp'ing it, and extracting it on the fileserver under **/export/tftpboot**, so in the end the following path exists: **/export/tftpboot/boot/grub/i386-pc**
=====Step 4: Establish a GRUB config=====
By default, the newly deployed **/export/tftpboot/boot/grub/i386-pc** directory has a config file called **grub.cfg** that contains the following:
source /boot/grub/grub.cfg
So, to roll out our config, we'll simply create a **/export/tftpboot/boot/grub/grub.cfg** file. A sample follows:
menuentry "KNOPPIX 6.7.0 (64-bit)" {
loopback loop /distros/knoppix/knoppix.iso
linux (loop)/boot/isolinux/linux64 iso-scan/filename=/KNOPPIX/KNOPPIX toram
initrd (loop)/boot/isolinux/minirt.gz
}
menuentry "Ubuntu Live 11.04 64bit" {
loopback loop /boot/iso/ubuntu-11.04-desktop-amd64.iso
linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=/boot/iso/ubuntu-11.04-desktop-amd64.iso noeject noprompt --
initrd (loop)/casper/initrd.lz
}
menuentry "Ubuntu Live 9.10 32bit" {
loopback loop /boot/iso/ubuntu-9.10-desktop-i386.iso
linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=/boot/iso/ubuntu-9.10-desktop-i386.iso noeject noprompt -- initrd (loop)/casper/initrd.lz
}
menuentry "Ubuntu Live 9.10 64bit" {
loopback loop /boot/iso/ubuntu-9.10-desktop-amd64.iso
linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=/boot/iso/ubuntu-9.10-desktop-amd64.iso noeject noprompt --
initrd (loop)/casper/initrd.lz
}
Obviously one needs to ensure that the referenced files are in the appropriate locations (root relative to **/export/tftpboot**!!) GRUB is very versatile, and has a lot of functionality... consulting a HOWTO on its configuration and usage would likely be a useful thing to get even more out of this resource.
=====Step 5: Configure DHCP to server core.0=====
On the DHCP Server, change the config as follows:
#filename "pxelinux.0";
filename "/boot/grub/i386-pc/core.0";
I basically just commented out the pxelinux.0 and had it instead serve up core.0 (if **core.0** was specifically placed in **/export/tftpboot**, the path would not be needed).
Note that this "absolute" path is rooted in **/export/tftpboot**.
Restart the DHCP daemon and attempt to netboot! You should get the GRUB menu.
=====Step 5a: ALTERNATE config, launch grub from PXElinux=====
NOTE: This still needs to be verified!
Instead of completely disabling PXELINUX, you could also try adding grub as an option to an existing PXE config, as follows (this was added to **/export/tftpboot/boot-screens/menu.cfg** on the tftp/file server):
label grub
menu label ^GRUB
kernel boot/grub/i386-pc/core.0
menu end
This way, no changes will need to be made on the DHCP server, and we are merely adding an additional option to the existing PXELINUX menu. Likely a more preferred approach, especially if running on an existing PXELINUX configuration.
Obviously, make sure if you've made the previous change on the DHCP server, you remember to revert it:
filename "pxelinux.0";
#filename "/boot/grub/i386-pc/core.0";
And restart the DHCP daemon.
=====Resources=====
The following links were utilized in creating this document:
* http://www.gentoo.org/doc/en/altinstall.xml
* http://www.panticz.de/MultiBootUSB (provides sample GRUB config, especially for booting from ISO images!)
* http://pxe.dev.aboveaverageurl.com/index.php/PXE_Booting/Knoppix (booting KNOPPIX)
* http://www.knoppix.net/wiki/Cheat_Codes (KNOPPIX cheat codes)
* https://wiki.edubuntu.org/LiveCDNetboot