I am writing this page to present info about network boot, and
my primary topic is booting DOS-like systems from IPX/NetWare
network (from Nowell or mars_nwe server). I myself wrote a Boot-ROM
code which is dedicated to be freely copyable (w/ GNU copyleft).

Other net boot packages or info I found on net:

Newest versions I have seen: Etherboot-4.2.10 Comboot-1.2 Netboot-0.8.1

netboot - recommended in NFS-Root-HOWTO; comboot; (.pl)
netboot (home?)

Etherboot: Etherboot home page

Other info which may be helpful for booting.

1. What acts on the begin: the Boot-ROM.

1.1. General rules for boot from NetWare.

   What the server provides to aid workstation boot?

   There is a directory LOGIN on SYS volume. Files which are there
  are accessible for not-logged-in workstations. This means they
  can be accessed after: 1. sending ATTACH request to the server
  (in reply W/S gets connection id which must be used in every
  subsequent request), 2. sending LOGOUT request (this maps the
  SYS:LOGIN directory to default network drive), and of course
  3. sending OPEN request which specifies the file to be accessed
  (a directory search is also possible, and will be in example),
  which can be followed by 4. READing contents of these files.

1.2. Boot start - how BootROM gets control.

   On boot BIOS does ROM scan: it check for 55 AA sequence on
  address where it expects ROM may begin, and if found takes next
  byte as the ROM size in pages (1 page=512=200h bytes), and
  computes checksum of the ROM adding all bytes. Low byte of the
  sum must be 0 - otherwise the ROM is ignored. BIOS calls ROM
  init code, which is assumed to be at offset 3 (i.e. it starts
  on next byte after the ROM size byte), by far call. But it is
  NOT good time to boot - should return from the call, otherwise
  BIOS may fail to find other ROMs. The BootROM sets interrupt
  vector 19h to point to some code in it, and returns.
   When BIOS finishes its initialization, it invokes INT 19h.
  Normally, it points to disk boot, but BootROM has changes it,
  so it gets control. And it should boot if possible - a return
  would most likely invoke ROM Basic, if it is on the computer.

1.3. IPX packet structures.

   The IPX header is 30-byte structure:
    WORD checkSum (send -1 - this means "no checksum"),
         length (Hi-Lo, includes IPX header itself);
    BYTE transportControl (0 when sent),
         packetType (usually 11h);
    IPX_Address destination, source;
   The IPX_Address is structure:
    BYTE network[4], node[6], socket[2];
   Note all values are in Hi-Lo order. The node is same as net
  adapter's Ethernet address, FFFFFFFFFFFF means broadcast,
  network 0 means local net - use such a values in first packet.

   SAP query consists of IPX header followed by:
    WORD query_type, WORD service_type;
  query 3 is nearest, query 1 is general, service 4 is fileserver;
  note on net byte order is Hi-Lo - the data sent is 00 03 00 04.
   SAP reply consists of IPX header followed by: WORD response_type;
  and  WORD server_type; char server_name[48];
       IPX_Addresss server_address; WORD distance;
  repeated if many servers reported (on nearest service query with
  server type = 4 the response has always one entry); Novell's doc
  says the distance is in Lo-Hi order (unlike other WORDs!).

   NCP request: IPX header is followed by WORD type; BYTE sequence,
    connection, 0, 0, code; and optional data as the request needs;
    type is usually 2222h (1111h for ATTACH, 5555h for DETACH).
   NCP reply: IPX header is followed by WORD type; BYTE sequence,
    connection, ?, ?, status, ?; and optional data; the type is
    3333h for normal replies (type of 9999h means sth. special);
    the sequence in NCP reply is same as in corresponding request,
    generally requests should advance the sequence on every one,
    but seems Novell serwer accepts using same sequence again, and
    it ignores requests with other sequence number; the status of
    non-zero means an error occured during request processing;
    on receipt usual checks are: matching sequence, status=0.

   NCP ATTACH request: type=1111h, connection=0FFh, code=11h
   NCP DETACH request: type=5555h, code=0
   NCP LOGOUT request: code=19h
   NCP OPEN request: code=41h, data 1,6 name_length name; the reply
    contains 36 bytes of data, first 6 of them are file handle
   NCP READ request: code=48h, data 0 handle start[4] length[2],
    note start and length in Hi-Lo order; the reply contains data:
    WORD read_length, the_data_read

1.4. How Novell's BootROM works.

   It uses technique described above, saving original vector at
  0:300h, and setting word at 0:304h to 6a6eh, which is
  flag telling that the vectors were changed. Then returns.
   When invoked by INT 19h it first attempts to read boot sector
  from floppy A: - if succeed, it (A) restores original INT 19h
  vector and invokes it for BIOS to boot the computer as usually.
   Next it check for presence of harddisk, and if present it does
  the following: 1. some video processing - moves cursor to home
  position, asks for video mode, if 7 assumes mono else sets mode
  3 (=CO80) and sets cursor shape according to the mode, finally
  clears screen (assuming address 0B0000h for mono, 0B8000h for
  color mode, and usual size); 2. displays a question
  "Boot from Network (Y or N) ? ", and gets answer (if invalid it
  repeats the question), on N it displays CRLF and goes to A.

   Then the code is moved to segment MemTop-900h, stack is set to
  0:0c000h and jump is done to the moved code.

   After the jump it initializes video as already described and
  displays "Novell Netware Remote Program Loader", driver info,
  and Novell's copyright, then enters boot loop. In the loop it:

  - calls driver initialization code (2 procedures, the second
   may return error - ZF=0 means AX=offset of error message, in
   such a case it shows the message, displays "Error initializing
   network interface board" and waits 3 second, then retries)

  - sends packet from socket 4A58 to broadcast address with socket
   0452 (SAP=Service Advertisement Protocol socket) containing SAP
   query for nearest fileserver, and reads the reply; an immediate
   address of replying node will be used to route all requests,
   destination address net part will be used as net part of own
   address, and the FS address will be used to access the server

  - sends NCP ATTACH request from socket 4A57 (note socket change:
   it prevents receiving replies to SAP query), and gets from the
   reply connection id (ATTACH only uses connection id 0FFh)

  - sends LOGOUT request, error if no reply or invalid

  - sends OPEN requests on the following files: BOOTCONF.SYS (on
   success it is scanned, using READ requests to get data from it,
   for line for this W/S, and file specified in it is tried first),
   then NET$DOS.SYS, IBM$DOS.SYS, first successfull open on image
   file causes boot to be done from it, error if all opens fail.

  - on error a message is displayed, and after 3 second pause the
   loop is started from begin.

   The BOOTCONF.SYS is scanned for 0x,=filename, any of
  these values can be 0 to match everything, preceding 0-s can be
  omitted, scanning countinues until first match or read error.
 
   The boot is processed as follows: vectors 0F1h-0F4h are set
  to 5774:654E ("Netw"), copy of vector 13h, new vector 13h (it
  is changed to point to code which reads boot image), and "boot
  terminate" vector, then a "bootsector" is read from boot image
  (the most recently opened file), sectors per track and number
  of heads are took from it, and jump to it is done; then read
  from floppy is serviced by reading the boot image file

   Boot terminate sends DETACH request, and closes the socket
  used by the boot (see below why).
   
   The boot image is still accessible when IPX driver is loaded
  by booted system. How? The BootROM contains own "mini-IPX"
  which on every request checks if real IPX was loaded, and in
  such a case opens socket (to be able to receive packets), and
  forwards all requests to the real IPX. This of course works
  well providing that network adapter will not be accessed until
  IPX is loaded - true is using IPX.COM containing driver, and
  usually true if NDIS driver is used - note some NDIS drivers,
  in spite specification demands they must not do it, initialize
  adapter when loaded, and cause the boot to fail.

   How the Novell's BootROM is made? There is some code from
  Novell, and there is driver code from the network adapter
  manufacturer, probably they are two .OBJ-s and usual LINK
  can be used to produce .EXE, then DCONFIG/ECONFIG can be
  used to configure it (on image w/o .EXE header offsets would
  not match), and finally EXE2BIN to produce BootROM image.

1.5. My ideas about making Boot-ROMs. my bootrom code
(it was fixed Jan 25,2000 - there was extra 0 byte in "open"
 request causing the request to fail on Windows NT; fixed again
 Mar 31,2000 - allow repeating initial SAP until any reply)
You also need some program to make the rom: here it is.

   First of all, I decided to make it as simple as possible:
  the Boot-ROM is to allow some file to be read into W/S memory
  and executed; everything else can be in the file. IMHO this
  will give maximum flexibility of the boot. Later I decided to
  make it in a way simple program in e.g. Turbo C to be able to
  run without starting the system - and it required adding some
  DOS function simulation (not many, almost all were required
  to start Packet Driver, as described below).

   I wrote code which can interface standard Packet Driver - it
  supports INT 21h interface and few DOS calls for the driver
  to be able to start, and Crynwr drivers work well with it.
  I decided for it to get best flexibility - the only need to
  boot from network is to have Packet Driver for net adapter.
  In practice, not as well as expected - some drivers differ
  from "normal" so they cannot work. E.g. for OvisLink 8029R
  (RealTec 8029 - PCI "NE2000") I use NE2000 driver with PCI
  initialization code rather then driver from OvisLink.
  Also, some new network adapters have no packet drivers...

   My code moves Boot-ROM contents to RAM, prepares PSP, and
  jumps to start of the driver as it were a .COM loaded by DOS.
  After the driver ends by "Terminate and Stay Resident", it is
  used to send and receive packets. The sequence is basically
  the same as in Novell's Boot-ROM: SAP Query, Attach, Logout,
  Open... and here is a difference: I open file which name is
  specified in the Boot-ROM (it can be set, including but not
  necessarily required, the fileserver name so it boots from the
  server even if other server responds first to the SAP), and it
  is loaded into memory (address 4000h:0), and control is passed
  to the address (I wrote some code which, if put before .EXE,
  allows it to be used there, so one may use e.g. Turbo C or
  Turbo Pascal to write program, which will be executed this way
  - nice? ;-), then the program can read files from SYS:LOGIN
  directory and decide how to continue the boot.
   I have separate file which contains list of workstations, and
  for every W/S there can be specified a boot image file and
  CONFIG.SYS file (external to the boot image - one can make
  configuration with one boot image, and different CONFIG.SYS
  for each W/S, to save some disk space on copies of programs).

   I know someone had a problem w/ Novell's Boot-ROM on his net
  - it received SAP reply first from a server connected via slow
  line. Result: it booted horribly slooooooooowly. Novell's boot
  has no standard way to fix it (I made some code which can help:
  instead boot image one can put small program, which gets "good"
  server address, and then boots from it, but I already forgot
  where I have it, and it was not tested)...
   Using my Boot-ROM one can put server name in the file with
  workstations list and the program can process boot from really
  nearest server (the program only comes through the slow line).

   Some other Boot-ROM-s (Etherboot, Netboot packages) allow
  "boot image" which specifies what data is to be put at what
  memory address (there can be many parts to go to different
  addresses). Netboot also can boot simply image of boot disk.

1.6. Boot-ROM test aids: put its image on disk, and try it!
   My Boot-ROM, and Etherboot have this ability. (download)

2. What does the DOS during the network boot?

2.1. Standard DOS boot processing.

   First of all, a bootsector is read - like on normal boot from
  a disk, and the bootsector reads file named IO.SYS in MS-DOS,
  IBMBIO.COM in PC-DOS, DRBOOT.SYS? in DR-DOS/Novell-DOS...
  The bootsector code usually can read contiguous files only - it
  computes where the file starts on the disk, and reads as many
  consecutive sectors as necessary (or even worse is possible -
  it assumes the file starts from cluster 2 on the disk), but the
  IO.SYS can start if, I guess, 3 or 4 sectors were read - it can
  reread remaining data if necessary (MS-DOS), DRDOS simply has
  bootsector which can read non-contiguous files. Seems the file
  contains boot initialization code only, and the "DOS kernel" is
  in another one, it is MSDOS.SYS in MS-DOS, IBMDOS.COM in PC-DOS, 
  DRBDOS.SYS in DR-DOS; all DOS-es I knew used just two files.

   Another important file is CONFIG.SYS - it contains directives
  which are processed during DOS kernel configuring, they can load
  device drivers (sometimes network driver is loaded in it). These
  directives decide what will be done later - usually DOS loads
  its shell COMMAND.COM, and starts processing AUTOEXEC.BAT by it,
  but the default can be redefined in the CONFIG.SYS. A problem:
  where is the code which controls the boot? I tested it for MSDOS
  and found it is near top of "classic" RAM (the 640kB below video
  RAM area at 0A0000h); Novell's Boot-ROM used the same area for
  its boot processing, and they needed to write RPLFIX program to
  patch boot images for they protect the area from overwriting.

   The CONFIG.SYS can contain several directives, like:
  BUFFERS=, FILES=, STACKS=, DOS=, DEVICE=, DEVICEHIGH=, INSTALL=
  SHELL=. From MS-DOS 6.22 multiconfiguration feature was added,
  by directives like [block], MENUITEM=, MENUDEFAULT=, SUBMENU=,
  it shows menu (initially [MENU] block, can be changed if SUBMENU
  is selected) during boot, and processes selected block, setting
  CONFIG environment variable to name of last block selected, note
  can use SET CONFIG=value to get other value if needed. Example:

      DOS=HIGH,UMB
      STACKS=0,0
      BUFFERS=12
      FILES=125
      [MENU]
      MENUITEM=NET,my favorite network configuration
      SUBMENU=CHOOSE,choose other network adapter
      MENUDEFAULT=NET,1
      REM will wait 1 second to allow choosing other
      [NET]
      DEVICE=HIMEM.SYS
      DEVICE=EMM386.EXE RAM
      DEVICE=PROTMAN.DOS /IA:\NE2000
      DEVICEHIGH=NE2000.DOS
      [CHOOSE]
      MENUITEM=SMC8000,use SMC8000 adapter
      MENUITEM=NONET,boot without network
      [SMC8000]
      DEVICE=HIMEM.SYS
      DEVICE=EMM386.EXE RAM
      DEVICE=PROTMAN.DOS /IA:\SMC8000
      DEVICEHIGH=SMC8000.DOS
      SET CONFIG=NET
      REM for later processing same as with NE2000 adapter
      [NONET]
      [COMMON]
      REM reserved name, MS docs say it is processed first

2.2. Memory - how to prevent boot code overwriting? (DOS 5+ only)

    Problem: the code from Boot-ROM, data used by it, and some
   code loaded to support the boot are in area which DOS would
   overwrite if not told to avoid it. How can this be done?
   By setting INT 2Fh vector, and putting a code there which for
   AX=???? returns first paragraph it uses in ?? - MS-DOS-es 5.0+
   checks the vector, and if it is set asks and builds MCB with
   name "RPL", belonging to "SYSTEM PSP" (usually 8).

my boot program uses this during boot.
Do not forget some cleanup must be done to release the memory.

2.3. Programs to aid configuring during the boot. (here) 

    When DOS starts, and sets INT 21h, the Boot-ROM DOS-simulation
   becomes unavailable (in fact, it is turned off earlier - IRQ of
   network adapter is usually masked). There is a program, which
   can be used to copy files from SYS:LOGIN directory still until
   network adapter is initialized by a driver loaded during boot.
   It was initially NWBCOPY.EXE, and could be invoked by AUTOEXEC,
   later I wrote NWBCOPY.SYS, which can be loaded by DEVICE= in
   CONFIG.SYS. Idea: make RAMDRIVE, copy necessary files to it.
   The .SYS version has several enhancements, e.g. it can select
   RAMDRIVE as current drive (for a case it for same reason was
   other then usual C: - e.g. when the computer has harddrive).
   (the NWBCOPY.SYS is replacement for COPYFILE.SYS I wrote long
   ago, a program which could copy file accessible via DOS calls)

2.4. Necessary cleanups during boot and when it finishes.
   - disable INT 13h servicing - restore original INT 13h
   - disable network driver
   - free memory used by Boot-ROM code


Other info which may be helpful for booting.
Homepage GKM - Eprom/Flash-Service - Eprom/Flash-Programmierun
(the page offers EPROM programming in Germany, 32kB EPROM + programming 25DM)
bin2intelhex converter (C source) if eprom writer needs IntelHex
Linux boot: hints about using initrd tu run isapnp before driver init
NILO - Etherboot successor NILO home page NILO mirror
Linux Terminal Server Project
More about NILO and similar projects:
Boot: Remote Boot Howto
Boot: Grub - attempt to produce bootloader
Boot: OsKit - OS Development Kit (for creating OS-es)
Intel wfm specs (PXE pointer), local copy the PXE is here

P.K. Wong's HOWTO for booting Windows 95 diskless
Linux Remote-Boot mini-HOWTO: Configuring Remote-Boot Workstations with Red-Hat Linux, DOS, Windows 3.1 and Windows 95

A collection of jumper settings for old network cards
Ken Yap's Links (e.g. what to do with old PC)