A small network bootloader for linux

Because I had so much trouble with bootloaders on my 486, I wrote a small one.

Download

netboot512-1.0.tar.gz (2014-09-21).

Documentation

This is a big hack.

Here is the README file included:

Read README.stage2.
It explains it all for the two stages boot process.

After writing stage1/stage2, I wrote stage1.small, which leads
to a stage1/main of 404 bytes.

Then I wanted to get rid of stage2, and so I wrote stagex.

stagex is a bootloader in one stage. It is small enough to fit
on the first sector of a floppy (even a FAT16 formatted one I
think). The file stagex/all has a size of 436 bytes but it really
contains 434 bytes of real data. A boot sector is 512 bytes.
According to http://en.wikipedia.org/wiki/Design_of_the_FAT_file_system,
we have 3+8+51+4=66 reserved bytes at maximum on a FAT16 floppy.
It leaves 446 bytes for a bootloader. stagex/main is 12 bytes smaller.

Beware! it's a hack, there are no checks at all. I mean *no* check, no
diagnostic, no nothing. If it fails for you, you're doomed. You may
try stage1/stage2 for they are more verbose.

Anyway, just a hack.

Please people, stop the bloat. A bootloader is just a little piece
of nothing. Let's keep it that way, thanks.

And here is README.2stages

This is netboot512, a linux bootloader I wrote for my 486. It smokes the first
sector of a floppy, the rest (stage2 and kernel) comes from the network.
stage1 contains just enough stuff to setup a ne2000 network card and load
stage2. stage2 is big enough to load a *recent* kernel (bootloader protocol
2.10, see Documentation/x86/boot.txt in the linux kernel).

Source code is at: http://sed.free.fr/debian486
This is public domain stuff.

What is there
=============

server: the file server
stage1: 512 bytes bootloader to put on a floppy (cat stage1/main > /dev/fd0)
stage2: stage 2 bootloader, to be served by the server

How to use
==========

I connect my 486 to a recent linux powered thing.
The linux thing has an ethernet eth0 and is with IP 10.0.1.14.

Edit stage1/config.inc: set the base address of your ne2000 in there.

Compile everything, put stage1 on a floppy (cat stage1/main > /dev/fd0),
run "server <stage2> <kernel>", connect the two computers, switch on
the 486 with the floppy in it.

How it works
============

The communication protocol uses UDP. server waits for a 1-byte packet on port
0x6666. If the byte is 0x2, it will serve the stage2 bootloader. If the byte
is 0x17, it will serve the kernel. (2 for stage2, 17 for Linus Torvalds =>
LT => 17 in 1337 language.)

To get rid of the big mess ARP is, all communication is done with
broadcast packets. Well, all this networking thing *is* a big mess
to start with, so, well, ah forget it. I hate complexity. But
this broadcast thing means that it may fail to work in your case.
I don't know much about networking, but broadcast is not supposed
to work everywhere, no? But who cares... No one will ever use that
thing or even know it exists at all. And why do I waste so much
time writing this text instead of finishing stage2? Okay, let's go
back to the subject.

The server sends packets of 1024 bytes. After each packet, the bootloader
sends an ack (same 1-byte packet it sent at the beginning). The server
waits for it and sends the next packet. If all the file has been served,
the server sends a 1-byte packet. When the stage1 bootloader is done, it
jumps to stage2. When stage2 is done, it jumps to the kernel.

stage1 is, well, limited to 512 bytes. stage2 is loaded at 0x0000:0x8600 and
must thus be small enough to finish before 0xffff, and even less, for
there is a stack in the end. 16KiB should be enough to fit whatever you
need.

The kernel is loaded at 0x100000 (1MiB) (my computer has only 16MiB of RAM).
To load at 0x1000000 (16MiB), modify the gdt and add an 'adc' around
the call of int 15h in stage2/main.asm. Yes, the access to high-memory
is done through the BIOS.

Since the kernel is loaded at 0x100000, you must compile it with
CONFIG_PHYSICAL_START=0x100000 and CONFIG_PHYSICAL_ALIGN=0x100000
(the defaults are 0x1000000 on 2.6.32.63 that I have here) (I lost
a few hours because of this one).

Limitations
===========

The bootloader accepts all packets. No other traffic than what
sends the server should thus exist.

Never, I repeat, *never* use that thing in production. There are no
checks at all. It's a hack I needed because all other bootloaders out
there are too big, too complicated, requiring too much infrastructure
to work. With only three programs (server, stage1, stage2) and no other
dependancy, I have a working solution to boot linux on my 486 over the
network. Perfection. Or very close too. And at the price of "dear sed,
your thing does not work for me". It probably won't. Ask for some help.
But how many people out there still have a 486?

But who cares...

I love to solve useless problems.

Ah yes, I forgot. You need nasm and dev86 to compile and link things. I tried
hard with gnu stuff (as, ld), but ld does not want to link 16 bit
object files, so I had to find another solution. If you have something
simpler... Or if you know how to use gnu stuff... (nasm/dev86 is simple, it's
just that dev86 might disappear in the future. Say 50 years from now.
GNU stuff should survive longer, no?)

dev86 is at: http://v3.sk/~lkundrak/dev86/
Seems this comes from: http://www.debath.co.uk/

TODO
====

stage1 is small enough to live in a FAT formatted floppy. I think.
Write a little utility to put it in there.
See http://en.wikipedia.org/wiki/Design_of_the_FAT_file_system
for documentation of the boot sector.

Can we get rid of stage2? It might be possible...

Contact: sed@free.fr

Created: Sun, 21 Sep 2014 14:24:24 +0200
Last update: Sun, 21 Sep 2014 14:24:24 +0200