Main Contents

Easy Gentoo Install using PXE Boot

March 22, 2008

I needed an easy way to install Gentoo on a system without a CD drive. I’ve done this before by moving the hard drive to another machine, but wanted to use PXE booting. I already have a PXE environment running that I use for cloning, so I won’t detail how to get that working (maybe later), but I’ll go over the steps specific to getting a Gentoo 2007 Minimal Install CD available in PXE. There are actually a couple ways to do this, but this method below does not require any pre-built custom kernels or NFS. When finished, you’ll just have two files on your TFTP server that contain the entire installation media.

If you’re preparing this from a Gentoo system, emerge File-Slurp. You’ll need to mount the Gentoo 2007 Minimal Install CD and pull off three file from it:

isolinux/gentoo 
isolinux/gentoo.igz 
image.squashfs

Copy gentoo into your TFTP directory, and the other two files into a temporary directory. In this temporary directory, create a script (let’s call it new_script) that contains the following:

#!/usr/bin/perl -w 
#    

use strict;    

use File::Slurp qw(slurp);    

my $ifile = slurp($ARGV[0], binmode=> ':raw'); 
my $newfile; 
my $i=1; 
my @newfiles = split(/TRAILER!!!/,$ifile); 
`mkdir $ARGV[0].dir`;    

foreach $newfile (@newfiles) 
{ 
        $newfile =~ s/^[\0]*//; 
        if($newfile){ 
           open F, "> ./$ARGV[0].dir/$i"; 
           $newfile = $newfile . "TRAILER!!!"; 
           for(my $null=22*16+21;$null>0;$null--){ 
              $newfile = $newfile . "\0"; 
           } 
           print F $newfile; 
           close F; 
           print "$i\n"; 
           `cd $ARGV[0].dir; cpio -i -H newc < $i; rm $i; cd ..`; 
           $i++; 
        } 
}

Run the following commands:

mv gentoo.igz gentoo.gz 
gunzip gentoo.gz 
chmod +x new_script 
./new_script gentoo 
cd gentoo.dir 
mkdir mnt 
mkdir mnt/cdrom 
cp ../image.squashfs mnt/cdrom/

Create a file called init.patch that contains:

--- init        2008-03-22 01:10:58.000000000 -0600 
+++ init        2008-03-22 01:14:27.000000000 -0600 
@@ -283,11 +283,6 @@ 
                [ ! -e ${NEW_ROOT}/dev/tty1 ] && mknod ${NEW_ROOT}/dev/tty1 c 4 1 
        fi    

-       if [ "${REAL_ROOT}" != "/dev/nfs" ] && [ "${LOOPTYPE}" != "sgimips" ] 
-       then 
-               bootstrapCD 
-       fi 
- 
        if [ "${REAL_ROOT}" = '' ] 
        then 
                echo -n -e "${WARN}>>${NORMAL}${BOLD} No bootable medium found. Waiting for new devices" 
@@ -387,7 +382,7 @@ 
                else 
                        bad_msg "Block device ${REAL_ROOT} is not a valid root device..." 
                        REAL_ROOT="" 
-                       got_good_root=0 
+                       got_good_root=1 
                fi 
        done    

@@ -489,7 +484,6 @@ 
                fi 
        fi    

-       cache_cd_contents 
        # Setup the loopback mounts    

        if [ "${LOOPTYPE}" = 'normal' ] 
@@ -503,7 +497,7 @@ 
        elif [ "${LOOPTYPE}" = 'squashfs' ] 
        then 
                good_msg 'Mounting squashfs filesystem' 
-               mount -t squashfs -o loop,ro ${NEW_ROOT}/mnt/cdrom/${LOOPEXT}${LOOP} ${NEW_ROOT}/mnt/livecd 
+               mount -t squashfs -o loop,ro /mnt/cdrom/${LOOPEXT}${LOOP} ${NEW_ROOT}/mnt/livecd    

                test_success 'Mount filesystem' 
                FS_LOCATION='mnt/livecd'

Run this:

cp init init.orig 
patch -p0 --ignore-whitespace < init.patch 
find . -print | cpio -o -H newc > ../gentoo.igz 
cd ..

Copy the new gentoo.igz file into your TFTP directory. Use the following options in your PXE config:

kernel gentoo 
append initrd=gentoo.igz root=/dev/ram0 init=/linuxrc loop=/image.squashfs looptype=squashfs cdroot=1 real_root=/

Boot your computer via PXE and that’s it.

Filed under: Linux | Comments (1)

1 Comment

  1. Michael Rohde July 26, 2008 @ 11:34 pm

    instead of using the perl script you can use
    gunzip -c ../gentoo.igz | cpio -idv
    to extract

    and
    find . -print | cpio -o -H newc |gzip -9 -c – > ../gentoo.igz.new
    to compress afterwards