Mowson.org/karl

Not all WinNT T20 models have a PXE boot option. If you can’t get a standard PXE setup for your machine, maybe this document will help…

Go to http://rom-o-matic.net and choose these settings:

Then click "Configure" and select these options:

Then hit the "Get ROM" button and the download should start - it’s only about 22k.

Alternatively, you could download the etherboot source from http://www.etherboot.org and configure/compile it yourself. Or maybe use the Debian etherboot package. Config_PCI_Direct is the essential option you need for the T20 BIOS.


The two other files you will need are your standard WinNT image file for your T20 (mine uses U96CPQ163.bin) and this script called t20-etherboot.sh

#! /bin/sh
# Title:
#    t20-etherboot.sh
#
# Author:
#    Karl Mowatt-Wilson
#    http://mowson.org/karl
#    copyright: 2007 Karl Mowatt-Wilson
#    licence: GPL v2
#
# Revisions:
#    v0.1  -  5 Jul 2007 - initial testing
#    v0.11 - 21 Jul 2007 - use getopts
#    v0.12 - 12 Oct 2007 - simplify echo test to not use hd/tr

Usage () {
cat <<-EOF

        USAGE:
           t20-etherboot.sh [-d] [SourceImage [EtherbootRom]]

        This script combines a standard WinNT Evo T20 image file with an etherboot
        image, to make a T20 image which can do PXE booting (ie. a PXE client).
        SourceImage is the name of the standard WinNT firmware for your model
        of T20 - default is "./U96CPQ163.bin" (for 96M/128M T20).
        EtherbootRom is the name of the etherboot image to install - this cannot
        be specified without specifying SourceImage as well - default
        is "./eb-5.4.3-natsemi.zhd"
        The patched image file will be called "./bootp.bin"

        OPTIONS:
           -d  DANGEROUS!
               Disable test of MBR end marker.  It is unlikely that this option
               will help anyone, but there is a possibility that my marker test
               code fails on your machine, but the rest of the script works, in
               which case this option would be useful.  The risk is that without
               checking MBR location, the script may install etherboot in the
               wrong place and corrupt the image file.
               DANGEROUS!

        NOTES:
           Shells:
              This has been tested with dash and is hopefully posix compliant.
              bash should work fine.
              tcsh is completely unknown to me.

EOF
}
###########################################################################
# Default names of files to use:
T20_STANDARD_FIRMWARE="./U96CPQ163.bin"
ETHERBOOT="./eb-5.4.3-natsemi.zhd"

# We need real echo for some things, rather than built-in shell echo, since
# this script needs predictable octal escape expansion.
ECHO="/bin/echo"
ECHOOPTIONS='-n -e'

# IMAGE is the name of the file to create from combining the two files above.
IMAGE="./bootp.bin"

###########################################################################
## Function to exit with error message.
## First param is return code, remaining params are lines of error message.
#
Fail() {
   ExitCode=$1
   shift
   echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" >&2
   echo "$(basename "$0"): FATAL ERROR" >&2
   while [ $# -gt 0 ]; do
      echo "$1" >&2
      shift
   done
   sleep 2
   exit $ExitCode
}

###########################################################################
## Function to check a list of desired tools are available.
#
Toolcheck() {
   while [ $# -gt 0 ]; do
      TOOL="$1"
      shift
      echo "Checking '$TOOL'"
      which "$TOOL" >/dev/null 2>/dev/null \
         || Fail 3 "'which' failed for '$TOOL' - can't find this command."
   done
}


###########################################################################
#==========================================================================
# Parse command-line options.

MBR_TEST="TRUE"
while getopts "d" OPT; do
   case $OPT in
      d)   # Disable test of MBR end marker
           MBR_TEST=""
           ;;
      *)   Usage
           exit
           ;;
    esac
done
shift $(($OPTIND - 1)); OPTIND=1

# Accept files specified on command-line.
[ "$1" ] && T20_STANDARD_FIRMWARE="$1"
[ "$2" ] && ETHERBOOT="$2"


#==========================================================================
echo "=== Checking tools =================================================="
Toolcheck \
   dd \
   strings \
   grep

echo "=== Sanity checks ================================================="
echo "Check source image exists and is readable."
[ -r "$T20_STANDARD_FIRMWARE" ] \
   || Fail 3 "Can't read from standard firmware '$T20_STANDARD_FIRMWARE'"

echo "Check etherboot image is readable."
[ -r "$ETHERBOOT" ] \
   || Fail 3 "Can't read etherboot image '$ETHERBOOT'"


echo "=== Start working ================================================="
echo "Copying standard firmware '" \
      $T20_STANDARD_FIRMWARE      \
      "' to working file '$IMAGE'"
cp "$T20_STANDARD_FIRMWARE" "$IMAGE" \
   || Fail 3 "Couldn't copy '$T20_STANDARD_FIRMWARE'"

# The chmod is in case the file has come from a read-only location.
chmod u+rw "$IMAGE" \
   || Fail 3 "Couldn't chmod '$IMAGE'"

echo "Searching for Master Boot Record."
MBR_SEARCH=$(strings -n20 -td "$IMAGE" \
   | grep -Em1 "( )*[0-9]+( )+Invalid partition table$")
[ "$MBR_SEARCH" ] \
   || Fail 3 "Couldn't find MBR search string in image '$IMAGE'" \
             "Is this really a WinNT image file?"

MBR_SEARCH_LOCATION=$(echo "$MBR_SEARCH" | grep -Eo '[0-9]+')

DISK_START=$(( $MBR_SEARCH_LOCATION - 139 ))

echo "Disk start set to $DISK_START"


###########################################################################
# Define the location of the partition table, in case we want to edit it
MBR_PARTITION1_DD_SEEK=$(( $DISK_START + 446 ))
MBR_PARTITION2_DD_SEEK=$(( $MBR_PARTITION1_DD_SEEK + 16 ))
MBR_PARTITION3_DD_SEEK=$(( $MBR_PARTITION1_DD_SEEK + 32 ))
MBR_PARTITION4_DD_SEEK=$(( $MBR_PARTITION1_DD_SEEK + 48 ))

# Partition-type byte is 4 bytes on from beginning of partition record.
PART_TYPE_OFFSET=4

# Define where to look for the partition sector marker
# (which looks like 0x55AA at the end of the sector)
PART_ID_DD_SKIP=$(( $DISK_START + 510 ))

PART_START=$(( $DISK_START + 512 ))
echo "Partition start set to $PART_START"


###########################################################################
# Test that partition table has the correct marker bytes at the end.
# If this test fails, it is very likely that nothing is going to work
# properly.
# This test is optional - controlled by a command-line switch - see USAGE.

[ "$MBR_TEST" ] && {
   echo "Confirming MBR end marker."

   # We need real echo rather than built-in shell echo, since we need
   # predictable octal escape expansion
   echo "Check that we can use real echo ($ECHO)."
   which $ECHO >/dev/null 2>/dev/null \
      || Fail 3 "Couldn't find $ECHO"

   echo "Check that echo handles octal escapes."
   TESTECHO="$($ECHO $ECHOOPTIONS '\061\062\063')"
   [ "$TESTECHO" = '123' ] \
      || Fail 3 "echo command ($ECHO $ECHOOPTIONS) did not perform as expected with octal escapes." \
                "Expected result to be '123'" \
                "but got               '$TESTECHO'"

   echo "Checking MBR has expected ID of 0x55 0xAA at end."
   # Set marker to 0x55 0xAA (octal bytes 125 252).
   MARKER="$($ECHO $ECHOOPTIONS '\125\252' | tail -c2)"

   # Extract marker from where we think it should be.
   EXTRACT="$(dd if="$IMAGE" skip=$PART_ID_DD_SKIP bs=1 count=2)"

   # Check that the marker is correct.
   [ "$MARKER" = "$EXTRACT" ] \
      || Fail 3 "Couldn't find marker - MBR search failed."

   echo "MBR 'confirmed' at $DISK_START"
}


###########################################################################
echo "=== Setup etherboot ==============================================="
dd if="$ETHERBOOT" of="$IMAGE" bs=1 conv=notrunc seek=$PART_START \
   || Fail 3 "Couldn't copy etherboot."


###########################################################################
echo "=== Finished! ====================================================="
echo
echo "Done!  You should now flash the T20 with '$IMAGE'"
echo

Put the etherboot ROM file, T20 image file, and the script in a directory. Maybe edit the script to have the correct T20 image file name and correct ROM file name (or just specify them on the command-line). Run the script. Flash the resulting bootp.bin to your T20.

You should now have a T20 which boots via PXE.

Now you need a PXE server - eg. the LTSP project, or for simple purposes use the setup I have documented somewhere else around here. You may also want to use the boot-from-initrd document from somewhere around here too - then the T20 can boot entirely via PXE and run standalone (instead of LTSP, which boots off PXE and then requires the server to do all the real work).

There is good info about PXE here: http://syslinux.zytor.com/pxe.php


Note: I generally also use this option:

This allows me to run a separate DHCP server (on different ports) from the normal one on my network, so I can fiddle with things easily without risking breaking the rest of the network. I use this with the -a option of my netxfer.sh script (see ../linux-netxfer).


Contact me if you have any problems!