summaryrefslogtreecommitdiffstats
path: root/contrib/baremetal
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/baremetal')
-rw-r--r--contrib/baremetal/Makefile475
-rw-r--r--contrib/baremetal/main.c1119
-rw-r--r--contrib/baremetal/marini.txt52
-rw-r--r--contrib/baremetal/misc.c351
-rw-r--r--contrib/baremetal/startmpcc.S756
5 files changed, 0 insertions, 2753 deletions
diff --git a/contrib/baremetal/Makefile b/contrib/baremetal/Makefile
deleted file mode 100644
index df4de762..00000000
--- a/contrib/baremetal/Makefile
+++ /dev/null
@@ -1,475 +0,0 @@
-#
-# Makefile for Etherboot
-#
-# Most of the time you should edit Config
-#
-# Common options:
-# VERSION=v - Set the version string
-#
-# NS8390 options:
-# -DINCLUDE_NE - Include NE1000/NE2000 support
-# -DNE_SCAN=list - Probe for NE base address using list of
-# comma separated hex addresses
-# -DINCLUDE_3C503 - Include 3c503 support
-# -DT503_SHMEM - Use 3c503 shared memory mode (off by default)
-# -DINCLUDE_WD - Include Western Digital/SMC support
-# -DWD_DEFAULT_MEM- Default memory location for WD/SMC cards
-# -DCOMPEX_RL2000_FIX
-#
-# If you have a Compex RL2000 PCI 32-bit (11F6:1401),
-# and the bootrom hangs in "Probing...[NE*000/PCI]",
-# try enabling this fix... it worked for me :).
-# In the first packet write somehow it somehow doesn't
-# get back the expected data so it is stuck in a loop.
-# I didn't bother to investigate what or why because it works
-# when I interrupt the loop if it takes more then COMPEX_RL2000_TRIES.
-# The code will notify if it does a abort.
-# SomniOne - somnione@gmx.net
-#
-# 3C509 option:
-# -DINCLUDE_3C509 - Include 3c509 support
-#
-# 3C90X options:
-# -DINCLUDE_3C90X - Include 3c90x support
-# -DCFG_3C90X_PRESERVE_XCVR - Reset the transceiver type to the value it
-# had initially just before the loaded code is started.
-# -DCFG_3C90X_XCVR - Hardcode the tranceiver type Etherboot uses.
-# -DCFG_3C90X_BOOTROM_FIX - If you have a 3c905B with buggy ROM
-# interface, setting this option might "fix" it. Use
-# with caution and read the docs in 3c90x.txt!
-#
-# See the documentation file 3c90x.txt for more details.
-#
-# CS89X0 (optional) options:
-# -DINCLUDE_CS89X0- Include CS89x0 support
-# -DCS_SCAN=list - Probe for CS89x0 base address using list of
-# comma separated hex addresses; increasing the
-# address by one (0x300 -> 0x301) will force a
-# more aggressive probing algorithm. This might
-# be neccessary after a soft-reset of the NIC.
-#
-# LANCE options:
-# -DINCLUDE_NE2100- Include NE2100 support
-# -DINCLUDE_NI6510- Include NI6510 support
-#
-# SK_G16 options:
-# -DINCLUDE_SK_G16- Include SK_G16 support
-#
-# I82586 options:
-# -DINCLUDE_3C507 - Include 3c507 support
-# -DINCLUDE_NI5210- Include NI5210 support
-# -DINCLUDE_EXOS205-Include EXOS205 support
-#
-# SMC9000 options:
-# -DINCLUDE_SMC9000 - Include SMC9000 driver
-# -DSMC9000_SCAN=list - List of I/O addresses to probe
-#
-# TIARA (Fujitsu Etherstar) options:
-# -DINCLUDE_TIARA - Include Tiara support
-#
-# NI5010 options:
-# -DINCLUDE_NI5010 - Include NI5010 support
-#
-# TULIP options:
-# -DINCLUDE_TULIP - Include Tulip support
-# -DUSE_INTERNAL_BUFFER - receuve and transmit buffers within program
-# space, not below 0x10000, in case that region is used
-#
-# RTL8139 options:
-# -DINCLUDE_RTL8139 - Include RTL8139 support
-# -DUSE_INTERNAL_BUFFER - 8 kB receive buffer within program space,
-# not at 0x10000 - 8kB, in case that region is used
-#
-
-include Config
-
-GCC= gcc
-CPP= gcc -E
-VERSION= 4.6.12
-CFLAGS16+= -DVERSION=\"$(VERSION)\" -DRELOC=$(RELOCADDR)
-CFLAGS32+= -DVERSION=\"$(VERSION)\" -DRELOC=$(RELOCADDR) $(OLDGAS)
-LCONFIG+= -DRELOC=$(RELOCADDR)
-
-IDENT16= 'Etherboot/16 $(VERSION) (GPL) $(@F)'
-IDENT32= 'Etherboot/32 $(VERSION) (GPL) $(@F)'
-
-# Find out if we're using binutils 2.9.1 which uses a different syntax in some
-# places (most prominently in the opcode prefix area).
-OLDGAS:= $(shell $(AS) --version | grep -q '2\.9\.1' && echo -DGAS291)
-
-# Check the requested type of build (32, 16 or both families)
-ifeq ($(ETHERBOOT),16)
-BUILD_LIBS= $(BLIB16)
-BUILD_BINS= $(BINS16)
-endif
-ifeq ($(ETHERBOOT),32)
-BUILD_LIBS= $(BLIB32)
-BUILD_BINS= $(BINS32)
-endif
-ifeq ($(ETHERBOOT),both)
-BUILD_LIBS= $(BLIB16) $(BLIB32)
-BUILD_BINS= $(BINS16) $(BINS32)
-endif
-
-3C503FLAGS= -DINCLUDE_3C503 # -DT503_SHMEM
-# Note that the suffix to MAKEROM_ is the (mixed case) basename of the ROM file
-MAKEROM_3c503= -3
-3C507FLAGS= -DINCLUDE_3C507
-3C509FLAGS= -DINCLUDE_3C509
-3C529FLAGS= -DINCLUDE_3C529
-3C595FLAGS= -DINCLUDE_3C595
-3C90XFLAGS= -DINCLUDE_3C90X
-CS89X0FLAGS= -DINCLUDE_CS89X0
-EEPROFLAGS= -DINCLUDE_EEPRO
-EEPRO100FLAGS= -DINCLUDE_EEPRO100
-EPIC100FLAGS= -DINCLUDE_EPIC100
-EXOS205FLAGS= -DINCLUDE_EXOS205
-LANCEFLAGS= -DINCLUDE_LANCE # Lance/PCI!
-NE2100FLAGS= -DINCLUDE_NE2100
-NEFLAGS= -DINCLUDE_NE -DNE_SCAN=0x300,0x280,0x320,0x340,0x380
-NS8390FLAGS= -DINCLUDE_NS8390 # NE2000/PCI!
-NI5010FLAGS= -DINCLUDE_NI5010
-NI5210FLAGS= -DINCLUDE_NI5210
-NI6510FLAGS= -DINCLUDE_NI6510
-RTL8139FLAGS= -DINCLUDE_RTL8139
-SK_G16FLAGS= -DINCLUDE_SK_G16
-SMC9000FLAGS= -DINCLUDE_SMC9000
-TIARAFLAGS= -DINCLUDE_TIARA
-DEPCAFLAGS= -DINCLUDE_DEPCA # -DDEPCA_MODEL=DEPCA -DDEPCA_RAM_BASE=0xd0000
-TULIPFLAGS= -DINCLUDE_TULIP
-OTULIPFLAGS= -DINCLUDE_OTULIP
-VIA_RHINEFLAGS= -DINCLUDE_VIA_RHINE
-WDFLAGS= -DINCLUDE_WD -DWD_DEFAULT_MEM=0xCC000
-W89C840FLAGS= -DINCLUDE_W89C840
-
-# If you have not made any changes to the *.S files, AS86 need not be set.
-# (most people)
-# If you have made changes to the *.S files and you want to rebuild *loader.bin
-# and {floppy,com}load.bin and you have as86 from the ELKS Dev86 package (not
-# the one that normally comes with Linux) (not most people)
-#AS86= as86
-# If you have made changes to the *.S files and you want to rebuild *loader.bin
-# and {floppy,com}load.bin and you have nasm (not most people)
-#AS86= nasm
-
-# if your as has trouble with the data32 directive, uncomment this
-# but note that the premade start*.o will be larger than necessary because it
-# contains some routines which may not be used
-#AS_PSEUDOS= n
-
-SRCS= floppyload.S comload.S liloprefix.S loader.S start16.S start32.S serial.S startmpcc.S
-SRCS+= main.c pci.c osloader.c nfs.c misc.c ansiesc.c bootmenu.c config.c
-SRCS+= md5.c floppy.c
-
-# ROM loaders: LZ version (prefix Z), PCI header version (prefix P)
-ifndef AS86
-RLOADER= rloader.bin.pre
-PRLOADER= prloader.bin.pre
-RZLOADER= rzloader.bin.pre
-PRZLOADER= przloader.bin.pre
-FLOPPYLOAD= floppyload.bin.pre
-COMLOAD= comload.bin.pre
-LILOPREFIX= liloprefix.bin.pre
-else
-RLOADER= bin/rloader.bin
-PRLOADER= bin/prloader.bin
-RZLOADER= bin/rzloader.bin
-PRZLOADER= bin/przloader.bin
-FLOPPYLOAD= bin/floppyload.bin
-COMLOAD= bin/comload.bin
-LILOPREFIX= bin/liloprefix.bin
-endif
-
-ifeq ($(AS86),as86)
-LCPPFLAGS+= -DUSE_AS86
-LASFLAGS+= $(AS86FLAGS) -0
-LASBINARY:= -b
-endif
-ifeq ($(AS86),nasm)
-LCPPFLAGS+= -DUSE_NASM
-LASFLAGS+= $(NASMFLAGS) -fbin
-LASBINARY:= -o
-endif
-
-ifeq ($(AS_PSEUDOS),n)
-START16= start16.o.pre
-START32= start32.o.pre
-else
-START16= bin16/start16.o
-START32= bin32/startmpcc.o
-endif
-
-BOBJS16= bin16/main.o bin16/osloader.o bin16/misc.o bin16/bootmenu.o
-BOBJS16+= bin16/floppy.o bin16/timer.o
-BOBJS32= bin32/main.o bin32/osloader.o bin32/nfs.o bin32/misc.o
-BOBJS32+= bin32/ansiesc.o bin32/bootmenu.o bin32/md5.o bin32/floppy.o
-BOBJS32+= bin32/serial.o bin32/timer.o
-BLIB16= bin16/bootlib.a
-BLIB32= bin32/bootlib.a
-LIBS16= $(BLIB16) $(LIBC16)
-LIBS32= $(BLIB32) $(LIBC32) /usr/lib/gcc-lib/i386-redhat-linux/2.96/libgcc.a
-UTIL_LZHUF:= $(shell if [ -d ../contrib/compressor ]; then echo bin/lzhuf; fi)
-UTILS+= bin/makerom $(UTIL_LZHUF) bin/organon
-STDDEPS16= $(START16) $(BLIB16) $(UTILS)
-STDDEPS32= $(START32) $(BLIB32) $(UTILS)
-MAKEDEPS= Makefile Config Roms
-
-CHECKSIZE= { read d1; read d1 d2 d3 size d4; [ $$size -gt $(ROMLIMIT) ] &&\
- { $(RM) $@; echo "ERROR: code size exceeds limit!"; exit 1; }; exit 0; }
-
-# Make sure that the relocation address is acceptable for all ROM sizes.
-# Setting it to 0x98000 leaves about 29kB of space for the Etherboot program.
-# The check is done based running 'size' on the binary, not ROM size, but
-# roughly this means a ROM of 16kB or a partially used ROM of 32kB,
-# remembering to compressed ROM images into account.
-# You may also set RELOCADDR to 0x88000 to avoid using 0x98000
-# because of other drivers (e.g. Disk On Chip). In that case, you may
-# only load 512kB of OS, or load in memory above 1MB.
-# Don't forget to choose an assembler because the loaders have to be rebuilt.
-ifndef RELOCADDR
-RELOCADDR=0x98000
-#RELOCADDR=0xe0000
-endif
-
-# Evaluate ROMLIMIT only once - it is constant during the make run.
-# Note that the 3K safety margin below is for the 1K extended BIOS data area
-# and for the Etherboot runtime stack. Under normal situations, 2K of stack
-# are rarely needed. If you experience strange behaviour in functions that use
-# many local variables or that call functions that do, check for stack overrun!
-# Make sure that the normal case needs no perl interpreter - if someone uses a
-# different RELOCADDR, then he has perl installed anyways (the shell cannot
-# deal with hex numbers, as test/eval don't support non-decimal integers).
-ifeq ($(RELOCADDR),0x98000)
-ROMLIMIT=29696
-else
-ROMLIMIT:=$(shell perl -e 'print 0x10000 - 3072 - ($(RELOCADDR) & 0xFFFF), "\n";')
-endif
-
-# Start of targets
-
-all: $(UTILS) $(BUILD_LIBS) allbins
-
-include Roms
-
-# We need allbins because $(BINS16) and $(BINS32) are not defined until
-# the Makefile fragment "Roms" is read.
-
-allbins: $(BUILD_BINS)
-
-# Common files
-
-$(BLIB16): $(BOBJS16)
- $(AR16) rv $@ $(BOBJS16)
- $(RANLIB16) $@
-
-$(BLIB32): $(BOBJS32)
- $(AR32) rv $@ $(BOBJS32)
- $(RANLIB32) $@
-
-bin16/main.o: main.c etherboot.h osdep.h nic.h
-bin32/main.o: main.c etherboot.h osdep.h nic.h
-
-bin16/osloader.o: osloader.c etherboot.h osdep.h
-bin32/osloader.o: osloader.c etherboot.h osdep.h
-
-# NFS currently makes no sense for Etherboot/16
-bin32/nfs.o: nfs.c etherboot.h osdep.h nic.h
-
-bin16/misc.o: misc.c etherboot.h osdep.h
-bin32/misc.o: misc.c etherboot.h osdep.h
-
-# ANSIESC is not supported for Etherboot/16
-bin32/ansiesc.o: ansiesc.c etherboot.h osdep.h
-
-bin16/bootmenu.o: bootmenu.c etherboot.h osdep.h
-bin32/bootmenu.o: bootmenu.c etherboot.h osdep.h
-
-# Password support is not available for Etherboot/16
-bin32/md5.o: md5.c etherboot.h osdep.h
-
-bin16/floppy.o: floppy.c etherboot.h osdep.h
-bin32/floppy.o: floppy.c etherboot.h osdep.h
-
-bin16/timer.o: timer.c timer.h etherboot.h osdep.h
-bin32/timer.o: timer.c timer.h etherboot.h osdep.h
-
-bin32/inthw.o: inthw.c
-
-# PCI support code (common to all PCI drivers)
-
-bin32/pci.o: pci.c pci.h
-
-# Do not add driver specific dependencies here unless it's something the
-# genrules.pl script *can't* deal with, i.e. if it is not C code.
-
-# Prepended loaders
-
-#ifndef AS86
-#$(RLOADER) $(RZLOADER) $(PRLOADER) $(PRZLOADER): $(MAKEDEPS)
-# @if [ $(RELOCADDR) != 0x98000 ]; then echo Non-standard RELOCADDR, must assemble $@; exit 1; fi
-# $(TOUCH) $@
-#else
-#bin/rloader.s: loader.S $(MAKEDEPS)
-# $(CPP) $(LCPPFLAGS) $(LCONFIG) -o $@ $<
-#
-#bin/rzloader.s: loader.S $(MAKEDEPS)
-# $(CPP) $(LCPPFLAGS) $(LCONFIG) -DZLOADER -o $@ $<
-#
-#bin/prloader.s: loader.S $(MAKEDEPS)
-# $(CPP) $(LCPPFLAGS) $(LCONFIG) -DPCI_PNP_HEADER -o $@ $<
-#
-#bin/przloader.s: loader.S $(MAKEDEPS)
-# $(CPP) $(LCPPFLAGS) $(LCONFIG) -DPCI_PNP_HEADER -DZLOADER -o $@ $<
-#endif
-
-# Floppy loader
-
-ifdef AS86
-bin/floppyload.s: floppyload.S $(MAKEDEPS)
- $(CPP) $(LCPPFLAGS) -o $@ $<
-endif
-
-# COM loader
-
-ifdef AS86
-bin/comload.s: comload.S $(MAKEDEPS)
- $(CPP) $(LCPPFLAGS) -o $@ $<
-endif
-
-# LILO prefix:
-
-ifdef AS86
-bin/liloprefix.s: liloprefix.S $(MAKEDEPS)
- $(CPP) $(LCPPFLAGS) -o $@ $<
-endif
-
-# Utilities
-
-bin/makerom: makerom.c
- $(GCC) -O2 -o $@ makerom.c
-
-bin/organon: organon.c
- $(GCC) -o $@ organon.c
-
-bin/lzhuf: ../contrib/compressor/lzhuf.c
- $(GCC) -O2 -DENCODE -DDECODE -DMAIN -DVERBOSE -o $@ $<
-
-# Roms file
-
-Roms: NIC genrules.pl
- @chmod +x genrules.pl
- ./genrules.pl NIC > $@
-
-# Pattern Rules
-
-# general rules for compiling/assembling source files
-bin16/%.o: %.c $(MAKEDEPS)
- $(CC16) $(CFLAGS16) -o $@ -c $<
-
-bin32/%.o: %.c $(MAKEDEPS)
- $(CC32) $(CFLAGS32) -o $@ -c $<
-
-bin16/%.o: %.S $(MAKEDEPS)
- $(CC16) $(CFLAGS16) $(ASFLAGS16) -c -o $@ $<
-
-bin32/%.o: %.S $(MAKEDEPS)
- $(CPP) $(CFLAGS32) $< | $(AS) $(ASFLAGS32) -o $@
-
-# general rule for .bin (plain binary loader code), may be overridden
-ifdef AS86
-bin/%.bin: bin/%.s
- $(AS86) $(LASFLAGS) $(LASBINARY) $@ $<
-endif
-
-# general rule for .huf (compressed binary code), may be overridden
-%.huf: %.img
- bin/lzhuf e $< $@
-
-# general rules for normal/compressed ROM images, may be overridden
-bin16/%.rom: bin16/%.img $(RLOADER)
- cat $(RLOADER) $< > $@
- bin/makerom $(MAKEROM_$*) -i$(IDENT16) $@
-
-bin32/%.rom: bin32/%.img $(RLOADER)
- cat $(RLOADER) $< > $@
- bin/makerom $(MAKEROM_$*) -i$(IDENT32) $@
-
-bin16/%.lzrom: bin16/%.huf $(RZLOADER)
- cat $(RZLOADER) $< > $@
- bin/makerom $(MAKEROM_$*) -i$(IDENT16) $@
-
-bin32/%.lzrom: bin32/%.huf $(RZLOADER)
- cat $(RZLOADER) $< > $@
- bin/makerom $(MAKEROM_$*) -i$(IDENT32) $@
-
-# rules to write the .rom/.lzrom image onto a blank floppy
-# You must give the directory name, e.g. use bin32/rtl8139.lzfd0 as the target.
-%.fd0: %.rom $(FLOPPYLOAD)
- cat $(FLOPPYLOAD) $< > /dev/fd0
-
-%.lzfd0: %.lzrom $(FLOPPYLOAD)
- cat $(FLOPPYLOAD) $< > /dev/fd0
-
-# rules to generate a .com executable
-# You must give the directory name, e.g. use bin32/rtl8139.com as the target.
-%.com: %.lzrom $(COMLOAD)
- cat $(COMLOAD) $< > $@
-
-# rules to make a floppy image (padding to fill an even number of cylinders).
-# VMware reports floppy image read errors if it cannot read ahead 36 sectors,
-# probably because the floppyload.S code reads up to that number of sectors in
-# a single request. Not that 18k matters much these days...
-# You must give the directory name, e.g. use bin32/rtl8139.fdimg as the target.
-%.fdimg: %.rom $(FLOPPYLOAD)
- cat $(FLOPPYLOAD) $< > $@.x
- dd if=$@.x of=$@ bs=36k conv=sync 2> /dev/null
- $(RM) $@.x
-
-%.lzfdimg: %.lzrom $(FLOPPYLOAD)
- cat $(FLOPPYLOAD) $< > $@.x
- dd if=$@.x of=$@ bs=36k conv=sync 2> /dev/null
- $(RM) $@.x
-
-# rules to make a LILO-bootable image
-%.lilo: %.rom $(LILOPREFIX)
- cat $(LILOPREFIX) $< /dev/zero | head -c 64k > $@
-
-%.lzlilo: %.lzrom $(LILOPREFIX)
- cat $(LILOPREFIX) $< /dev/zero | head -c 64k > $@
-
-# Housekeeping
-
-# To make sure that this actually builds a start32.o.pre with all options set,
-# you have to make sure that -DFLOPPY -DANSIESC -DCONSOLE_DUAL are in CFLAGS32.
-precompiled: bin/rloader.bin bin/rzloader.bin bin/prloader.bin bin/przloader.bin bin/floppyload.bin bin/comload.bin bin16/start16.o bin32/start32.o bin/liloprefix.bin
- cp -p bin/rloader.bin rloader.bin.pre
- cp -p bin/rzloader.bin rzloader.bin.pre
- cp -p bin/prloader.bin prloader.bin.pre
- cp -p bin/przloader.bin przloader.bin.pre
- cp -p bin/floppyload.bin floppyload.bin.pre
- cp -p bin/comload.bin comload.bin.pre
- cp -p bin16/start16.o start16.o.pre
- cp -p bin32/start32.o start32.o.pre
- cp -p bin/liloprefix.bin liloprefix.bin.pre
-
-clean:
- $(RM) $(UTILS) bin/*.s bin/*.bin
- $(RM) $(BLIB16) $(BLIB32)
- $(RM) bin16/*.o bin32/*.o bin16/*.tmp bin32/*.tmp
- $(RM) bin16/*.img bin32/*.img bin16/*.huf bin32/*.huf
- $(RM) bin16/*.rom bin32/*.rom bin16/*.lzrom bin32/*.lzrom
- $(RM) bin16/*.com bin32/*.com
- $(RM) bin16/*.fdimg bin32/*.fdimg bin16/*.lzfdimg bin32/*.lzfdimg
- $(RM) bin16/*.lilo bin32/*.lilo bin16/*.lzlilo bin32/*.lzlilo
- $(RM) bin32/*.hex
- $(RM) bin32/*.asm
- $(RM) bin32/*.map
-
-tarball:
- (echo -n $(VERSION) ''; date -u +'%Y-%m-%d') > ../VERSION
- (cd ..; tar cf /tmp/mpccboot-$(VERSION).tar --exclude CVS mpccboot)
- bzip2 -9 < /tmp/mpccboot-$(VERSION).tar > /tmp/mpccboot-$(VERSION).tar.bz2
- gzip -9 < /tmp/mpccboot-$(VERSION).tar > /tmp/mpccboot-$(VERSION).tar.gz
-
-version:
- @echo $(VERSION)
diff --git a/contrib/baremetal/main.c b/contrib/baremetal/main.c
deleted file mode 100644
index 7b0de44c..00000000
--- a/contrib/baremetal/main.c
+++ /dev/null
@@ -1,1119 +0,0 @@
-/**************************************************************************
-ETHERBOOT - BOOTP/TFTP Bootstrap Program
-
-Author: Martin Renters
- Date: Dec/93
-
-Literature dealing with the network protocols:
- ARP - RFC826
- RARP - RFC903
- UDP - RFC768
- BOOTP - RFC951, RFC2132 (vendor extensions)
- DHCP - RFC2131, RFC2132 (options)
- TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize)
- RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper)
- NFS - RFC1094, RFC1813 (v3, useful for clarifications, not implemented)
-
-**************************************************************************/
-
-/* #define MDEBUG */
-
-#include "etherboot.h"
-#include "nic.h"
-
-int jmp_bootmenu[10];
-
-struct arptable_t arptable[MAX_ARP];
-
-const char *kernel;
-char kernel_buf[128];
-struct rom_info rom;
-
-#ifdef IMAGE_MENU
-static char *imagelist[RFC1533_VENDOR_NUMOFIMG];
-static int useimagemenu;
-int menutmo,menudefault;
-unsigned char *defparams = NULL;
-int defparams_max = 0;
-#endif
-#ifdef MOTD
-char *motd[RFC1533_VENDOR_NUMOFMOTD];
-#endif
-#ifdef IMAGE_FREEBSD
-int freebsd_howto = 0;
-#endif
-int vendorext_isvalid;
-char config_buffer[TFTP_MAX_PACKET+1]; /* +1 for null byte */
-unsigned long netmask;
-char *hostname = "";
-int hostnamelen = 0;
-#if defined(ETHERBOOT16) || defined(INTERNAL_BOOTP_DATA)
-struct bootpd_t bootp_data;
-#endif
-unsigned long xid;
-unsigned char *end_of_rfc1533 = NULL;
-#ifndef NO_DHCP_SUPPORT
-int dhcp_reply;
-in_addr dhcp_server = { 0L };
-in_addr dhcp_addr = { 0L };
-#endif /* NO_DHCP_SUPPORT */
-
-unsigned char vendorext_magic[] = {0xE4,0x45,0x74,0x68}; /* äEth */
-#ifdef NO_DHCP_SUPPORT
-char rfc1533_cookie[5] = { RFC1533_COOKIE, RFC1533_END };
-#else
-char rfc1533_cookie[] = { RFC1533_COOKIE};
-char rfc1533_end[]={RFC1533_END };
-static const char dhcpdiscover[]={
- RFC2132_MSG_TYPE,1,DHCPDISCOVER,
- RFC2132_MAX_SIZE,2, /* request as much as we can */
- sizeof(struct bootpd_t) / 256, sizeof(struct bootpd_t) % 256,
- RFC2132_PARAM_LIST,4,RFC1533_NETMASK,RFC1533_GATEWAY,
- RFC1533_HOSTNAME
- };
-static const char dhcprequest []={
- RFC2132_MSG_TYPE,1,DHCPREQUEST,
- RFC2132_SRV_ID,4,0,0,0,0,
- RFC2132_REQ_ADDR,4,0,0,0,0,
- RFC2132_MAX_SIZE,2, /* request as much as we can */
- sizeof(struct bootpd_t) / 256, sizeof(struct bootpd_t) % 256,
- /* request parameters */
- RFC2132_PARAM_LIST,
-#ifdef IMAGE_FREEBSD
- /* 4 standard + 6 vendortags + 8 motd + 16 menu items */
- 4 + 6 + 8 + 16,
-#else
- /* 4 standard + 5 vendortags + 8 motd + 16 menu items */
- 4 + 5 + 8 + 16,
-#endif
- /* Standard parameters */
- RFC1533_NETMASK, RFC1533_GATEWAY,
- RFC1533_HOSTNAME,
- RFC1533_ROOTPATH, /* only passed to the booted image */
- /* Etherboot vendortags */
- RFC1533_VENDOR_MAGIC,
- RFC1533_VENDOR_ADDPARM,
- RFC1533_VENDOR_ETHDEV,
-#ifdef IMAGE_FREEBSD
- RFC1533_VENDOR_HOWTO,
-#endif
- RFC1533_VENDOR_MNUOPTS, RFC1533_VENDOR_SELECTION,
- /* 8 MOTD entries */
- RFC1533_VENDOR_MOTD,
- RFC1533_VENDOR_MOTD+1,
- RFC1533_VENDOR_MOTD+2,
- RFC1533_VENDOR_MOTD+3,
- RFC1533_VENDOR_MOTD+4,
- RFC1533_VENDOR_MOTD+5,
- RFC1533_VENDOR_MOTD+6,
- RFC1533_VENDOR_MOTD+7,
- /* 16 image entries */
- RFC1533_VENDOR_IMG,
- RFC1533_VENDOR_IMG+1,
- RFC1533_VENDOR_IMG+2,
- RFC1533_VENDOR_IMG+3,
- RFC1533_VENDOR_IMG+4,
- RFC1533_VENDOR_IMG+5,
- RFC1533_VENDOR_IMG+6,
- RFC1533_VENDOR_IMG+7,
- RFC1533_VENDOR_IMG+8,
- RFC1533_VENDOR_IMG+9,
- RFC1533_VENDOR_IMG+10,
- RFC1533_VENDOR_IMG+11,
- RFC1533_VENDOR_IMG+12,
- RFC1533_VENDOR_IMG+13,
- RFC1533_VENDOR_IMG+14,
- RFC1533_VENDOR_IMG+15,
- };
-
-#endif /* NO_DHCP_SUPPORT */
-static const char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
-
-/**************************************************************************
-MAIN - Kick off routine
-**************************************************************************/
-int main(void)
-{
- char *p;
- static int card_retries = 0;
- int i;
-
- for (p=_edata; p<_end; p++)
- *p = 0; /* Zero BSS */
-
-#ifdef CONSOLE_SERIAL
- (void)serial_init();
-#endif
-
-#ifdef DELIMITERLINES
- for (i=0; i<80; i++) putchar('=');
-#endif
-
-#ifdef ETHERBOOT32
- rom = *(struct rom_info *)ROM_INFO_LOCATION;
- printf("ROM segment %#x length %#x reloc %#x\n", rom.rom_segment,
- rom.rom_length << 1, ((unsigned long)_start) >> 4);
-#endif
-#ifdef ETHERBOOT16
- fmemcpy(&rom, (Address)ROM_INFO_LOCATION, sizeof(rom));
- printf("ROM segment %#x length %#x\n", rom.rom_segment,
- rom.rom_length << 1);
-#endif
-#ifdef ASK_BOOT
- while (1) {
- int c;
- unsigned long time;
- printf(ASK_PROMPT);
-#if ASK_BOOT > 0
- for (time = currticks() + ASK_BOOT*TICKS_PER_SEC; !iskey(); )
- if (currticks() > time) {
- c = ANS_DEFAULT;
- goto done;
- }
-#endif
- c = getchar();
- if ((c >= 'a') && (c <= 'z')) c &= 0x5F;
- if (c == '\n') c = ANS_DEFAULT;
-done:
- if ((c >= ' ') && (c <= '~')) putchar(c);
- putchar('\n');
- if (c == ANS_LOCAL)
- exit(0);
- if (c == ANS_NETWORK)
- break;
- }
-#endif
-#if (TRY_FLOPPY_FIRST > 0) && defined(FLOPPY)
- disk_init();
- printf("Trying floppy");
- for (i = TRY_FLOPPY_FIRST; i-- > 0; ) {
- putchar('.');
- if (disk_read(0, 0, 0, 0, ((char *) FLOPPY_BOOT_LOCATION)) != 0x8000) {
- printf("using floppy\n");
- exit(0);
- }
- }
- printf("no floppy\n");
-#endif /* TRY_FLOPPY_FIRST && FLOPPY */
- print_config();
- gateA20_set();
-#ifdef EMERGENCYDISKBOOT
- if (!eth_probe()) {
- printf("No adapter found\n");
- exit(0);
- }
-#else
- while (!eth_probe()) {
- printf("No adapter found");
- if (!setjmp(jmp_bootmenu))
- rfc951_sleep(++card_retries);
- }
-#endif
- kernel = DEFAULT_BOOTFILE;
- while (1) {
- if ((i = setjmp(jmp_bootmenu)) != 0) {
-#if defined(ANSIESC) && defined(CONSOLE_CRT)
- ansi_reset();
-#endif
- bootmenu(--i);
- } else {
- load();
- }
-#if defined(ANSIESC) && defined(CONSOLE_CRT)
- ansi_reset();
-#endif
- }
-}
-
-/**************************************************************************
-LOADKERNEL - Try to load kernel image
-**************************************************************************/
-#ifndef FLOPPY
-#define loadkernel(s) download((s),downloadkernel)
-#else
-static int loadkernel(const char *fname)
-{
- if (!memcmp(fname,"/dev/",5) && fname[6] == 'd') {
- int dev, part = 0;
- if (fname[5] == 'f') {
- if ((dev = fname[7] - '0') < 0 || dev > 3)
- goto nodisk; }
- else if (fname[5] == 'h' || fname[5] == 's') {
- if ((dev = 0x80 + fname[7] - 'a') < 0x80 || dev > 0x83)
- goto nodisk;
- if (fname[8]) {
- part = fname[8] - '0';
- if (fname[9])
- part = 10*part + fname[9] - '0'; }
- /* bootdisk cannot cope with more than eight partitions */
- if (part < 0 || part > 8)
- goto nodisk; }
- else
- goto nodisk;
- return(bootdisk(dev,part)); }
-nodisk:
- return download(fname, downloadkernel);
-}
-#endif
-
-/**************************************************************************
-LOAD - Try to get booted
-**************************************************************************/
-void load()
-{
- static int bootp_completed = 0;
-
- /* Find a server to get BOOTP reply from */
- if (!bootp_completed ||
- !arptable[ARP_CLIENT].ipaddr.s_addr || !arptable[ARP_SERVER].ipaddr.s_addr) {
-retry:
- bootp_completed = 0;
-#ifdef RARP_NOT_BOOTP
- printf("Searching for server (RARP)...\n");
-#else
-#ifndef NO_DHCP_SUPPORT
- printf("Searching for server (DHCP)...\n");
-#else
- printf("Searching for server (BOOTP)...\n");
-#endif
-#endif
-
-#ifdef RARP_NOT_BOOTP
- if (!rarp()) {
-#else
- if (!bootp()) {
-#endif
- printf("No Server found\n");
-#ifdef EMERGENCYDISKBOOT
- exit(0);
-#else
- goto retry;
-#endif
- }
- bootp_completed++;
- }
- printf("Me: %I, Server: %I",
- arptable[ARP_CLIENT].ipaddr.s_addr,
- arptable[ARP_SERVER].ipaddr.s_addr);
- if (BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr)
- printf(", Relay: %I",
- BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr);
- if (arptable[ARP_GATEWAY].ipaddr.s_addr)
- printf(", Gateway %I", arptable[ARP_GATEWAY].ipaddr.s_addr);
- putchar('\n');
-
-#ifdef MDEBUG
- printf("\n=>>"); getchar();
-#endif
-
-#ifdef MOTD
- if (vendorext_isvalid)
- show_motd();
-#endif
- /* Now use TFTP to load file */
-#ifdef IMAGE_MENU
- if (vendorext_isvalid && useimagemenu) {
- selectImage(imagelist);
- bootp_completed = 0;
- }
-#endif
-#ifdef DOWNLOAD_PROTO_NFS
- rpc_init();
-#endif
- for (;;) {
- printf("Loading %s ",kernel);
- while (!loadkernel(kernel)) {
- printf("Unable to load file.\n");
- sleep(2); /* lay off server for a while */
- }
- }
-}
-
-/**************************************************************************
-DEFAULT_NETMASK - Return default netmask for IP address
-**************************************************************************/
-static inline unsigned long default_netmask(void)
-{
- int net = ntohl(arptable[ARP_CLIENT].ipaddr.s_addr) >> 24;
- if (net <= 127)
- return(htonl(0xff000000));
- else if (net < 192)
- return(htonl(0xffff0000));
- else
- return(htonl(0xffffff00));
-}
-
-/**************************************************************************
-UDP_TRANSMIT - Send a UDP datagram
-**************************************************************************/
-int udp_transmit(unsigned long destip, unsigned int srcsock,
- unsigned int destsock, int len, const void *buf)
-{
- struct iphdr *ip;
- struct udphdr *udp;
- struct arprequest arpreq;
- int arpentry, i;
- int retry;
-
- ip = (struct iphdr *)buf;
- udp = (struct udphdr *)((long)buf + sizeof(struct iphdr));
- ip->verhdrlen = 0x45;
- ip->service = 0;
- ip->len = htons(len);
- ip->ident = 0;
- ip->frags = 0;
- ip->ttl = 60;
- ip->protocol = IP_UDP;
- ip->chksum = 0;
- ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
- ip->dest.s_addr = destip;
- ip->chksum = ipchksum((unsigned short *)buf, sizeof(struct iphdr));
- udp->src = htons(srcsock);
- udp->dest = htons(destsock);
- udp->len = htons(len - sizeof(struct iphdr));
- udp->chksum = 0;
- if (destip == IP_BROADCAST) {
- eth_transmit(broadcast, IP, len, buf);
- } else {
- if (((destip & netmask) !=
- (arptable[ARP_CLIENT].ipaddr.s_addr & netmask)) &&
- arptable[ARP_GATEWAY].ipaddr.s_addr)
- destip = arptable[ARP_GATEWAY].ipaddr.s_addr;
- for(arpentry = 0; arpentry<MAX_ARP; arpentry++)
- if (arptable[arpentry].ipaddr.s_addr == destip) break;
- if (arpentry == MAX_ARP) {
- printf("%I is not in my arp table!\n", destip);
- return(0);
- }
- for (i = 0; i<ETHER_ADDR_SIZE; i++)
- if (arptable[arpentry].node[i]) break;
- if (i == ETHER_ADDR_SIZE) { /* Need to do arp request */
- arpreq.hwtype = htons(1);
- arpreq.protocol = htons(IP);
- arpreq.hwlen = ETHER_ADDR_SIZE;
- arpreq.protolen = 4;
- arpreq.opcode = htons(ARP_REQUEST);
- memcpy(arpreq.shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
- memcpy(arpreq.sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
- memset(arpreq.thwaddr, 0, ETHER_ADDR_SIZE);
- memcpy(arpreq.tipaddr, &destip, sizeof(in_addr));
- for (retry = 1; retry <= MAX_ARP_RETRIES; retry++) {
- eth_transmit(broadcast, ARP, sizeof(arpreq),
- &arpreq);
- if (await_reply(AWAIT_ARP, arpentry,
- arpreq.tipaddr, TIMEOUT)) goto xmit;
- rfc951_sleep(retry);
- /* We have slept for a while - the packet may
- * have arrived by now. If not, we have at
- * least some room in the Rx buffer for the
- * next reply. */
- if (await_reply(AWAIT_ARP, arpentry,
- arpreq.tipaddr, 0)) goto xmit;
- }
- return(0);
- }
-xmit:
- eth_transmit(arptable[arpentry].node, IP, len, buf);
- }
- return(1);
-}
-
-/**************************************************************************
-DOWNLOADKERNEL - Try to load file
-**************************************************************************/
-int downloadkernel(data, block, len, eof)
- unsigned char *data;
- int block, len, eof;
-{
-#ifdef SIZEINDICATOR
- static int rlen = 0;
-
- if (!(block % 4) || eof) {
- int size;
- size = ((block-1) * rlen + len) / 1024;
-
- putchar('\b');
- putchar('\b');
- putchar('\b');
- putchar('\b');
-
- putchar('0' + (size/1000)%10);
- putchar('0' + (size/100)%10);
- putchar('0' + (size/10)%10);
- putchar('0' + (size/1)%10);
- }
-#endif
- if (block == 1)
- {
-#ifdef SIZEINDICATOR
- rlen=len;
-#endif
- if (!eof && (
-#ifdef TAGGED_IMAGE
- *((unsigned long *)data) == 0x1B031336L ||
-#endif
-#ifdef ELF_IMAGE
- *((unsigned long *)data) == 0x464C457FL ||
-#endif
-#ifdef AOUT_IMAGE
- *((unsigned short *)data) == 0x010BL ||
-#endif
- ((unsigned short *)data)[255] == 0xAA55))
- {
- ;
- }
- else if (eof)
- {
- memcpy(config_buffer, data, len);
- config_buffer[len] = 0;
- return (1); /* done */
- }
- else
- {
- printf("error: not a tagged image\n");
- return(0); /* error */
- }
- }
- if (len != 0) {
- if (!os_download(block, data, len))
- return(0); /* error */
- }
- if (eof) {
- os_download(block+1, data, 0); /* does not return */
- return(0); /* error */
- }
- return(-1); /* there is more data */
-}
-
-#ifdef DOWNLOAD_PROTO_TFTP
-/**************************************************************************
-TFTP - Download extended BOOTP data, or kernel image
-**************************************************************************/
-int tftp(const char *name, int (*fnc)(unsigned char *, int, int, int))
-{
- int retry = 0;
- static unsigned short iport = 2000;
- unsigned short oport;
- unsigned short len, block = 0, prevblock = 0;
- int bcounter = 0;
- struct tftp_t *tr;
- struct tftp_t tp;
- int rc;
- int packetsize = TFTP_DEFAULTSIZE_PACKET;
-
- /* Clear out the Rx queue first. It contains nothing of interest,
- * except possibly ARP requests from the DHCP/TFTP server. We use
- * polling throughout Etherboot, so some time may have passed since we
- * last polled the receive queue, which may now be filled with
- * broadcast packets. This will cause the reply to the packets we are
- * about to send to be lost immediately. Not very clever. */
- await_reply(AWAIT_QDRAIN, 0, NULL, 0);
-
- tp.opcode = htons(TFTP_RRQ);
- len = (sprintf((char *)tp.u.rrq, "%s%coctet%cblksize%c%d",
- name, 0, 0, 0, TFTP_MAX_PACKET) - ((char *)&tp)) + 1;
- if (!udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
- TFTP_PORT, len, &tp))
- return (0);
- for (;;)
- {
-#ifdef CONGESTED
- if (!await_reply(AWAIT_TFTP, iport, NULL, (block ? TFTP_REXMT : TIMEOUT)))
-#else
- if (!await_reply(AWAIT_TFTP, iport, NULL, TIMEOUT))
-#endif
- {
- if (!block && retry++ < MAX_TFTP_RETRIES)
- { /* maybe initial request was lost */
- rfc951_sleep(retry);
- if (!udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,
- ++iport, TFTP_PORT, len, &tp))
- return (0);
- continue;
- }
-#ifdef CONGESTED
- if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))
- { /* we resend our last ack */
-#ifdef MDEBUG
- printf("<REXMT>\n");
-#endif
- udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,
- iport, oport,
- TFTP_MIN_PACKET, &tp);
- continue;
- }
-#endif
- break; /* timeout */
- }
- tr = (struct tftp_t *)&nic.packet[ETHER_HDR_SIZE];
- if (tr->opcode == ntohs(TFTP_ERROR))
- {
- printf("TFTP error %d (%s)\n",
- ntohs(tr->u.err.errcode),
- tr->u.err.errmsg);
- break;
- }
-
- if (tr->opcode == ntohs(TFTP_OACK)) {
- char *p = tr->u.oack.data, *e;
-
- if (prevblock) /* shouldn't happen */
- continue; /* ignore it */
- len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 2;
- if (len > TFTP_MAX_PACKET)
- goto noak;
- e = p + len;
- while (*p != '\000' && p < e) {
- if (!strcasecmp("blksize", p)) {
- p += 8;
- if ((packetsize = getdec(&p)) <
- TFTP_DEFAULTSIZE_PACKET)
- goto noak;
- while (p < e && *p) p++;
- if (p < e)
- p++;
- }
- else {
- noak:
- tp.opcode = htons(TFTP_ERROR);
- tp.u.err.errcode = 8;
- len = (sprintf((char *)tp.u.err.errmsg,
- "RFC1782 error")
- - ((char *)&tp)) + 1;
- udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr,
- iport, ntohs(tr->udp.src),
- len, &tp);
- return (0);
- }
- }
- if (p > e)
- goto noak;
- block = tp.u.ack.block = 0; /* this ensures, that */
- /* the packet does not get */
- /* processed as data! */
- }
- else if (tr->opcode == ntohs(TFTP_DATA)) {
- len = ntohs(tr->udp.len) - sizeof(struct udphdr) - 4;
- if (len > packetsize) /* shouldn't happen */
- continue; /* ignore it */
- block = ntohs(tp.u.ack.block = tr->u.data.block); }
- else /* neither TFTP_OACK nor TFTP_DATA */
- break;
-
- if ((block || bcounter) && (block != prevblock+1)) {
- /* Block order should be continuous */
- tp.u.ack.block = htons(block = prevblock);
- }
- tp.opcode = htons(TFTP_ACK);
- oport = ntohs(tr->udp.src);
- udp_transmit(arptable[ARP_SERVER].ipaddr.s_addr, iport,
- oport, TFTP_MIN_PACKET, &tp); /* ack */
- if ((unsigned short)(block-prevblock) != 1) {
- /* Retransmission or OACK, don't process via callback
- * and don't change the value of prevblock. */
- continue;
- }
- prevblock = block;
- retry = 0; /* It's the right place to zero the timer? */
- if ((rc = fnc(tr->u.data.download,
- ++bcounter, len, len < packetsize)) >= 0)
- return(rc);
- if (len < packetsize) /* End of data */
- return (1);
- }
- return (0);
-}
-#endif /* DOWNLOAD_PROTO_TFTP */
-
-#ifdef RARP_NOT_BOOTP
-/**************************************************************************
-RARP - Get my IP address and load information
-**************************************************************************/
-int rarp()
-{
- int retry;
-
- /* arp and rarp requests share the same packet structure. */
- struct arprequest rarpreq;
-
- memset(&rarpreq, 0, sizeof(rarpreq));
-
- rarpreq.hwtype = htons(1);
- rarpreq.protocol = htons(IP);
- rarpreq.hwlen = ETHER_ADDR_SIZE;
- rarpreq.protolen = 4;
- rarpreq.opcode = htons(RARP_REQUEST);
- memcpy(&rarpreq.shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
- /* sipaddr is already zeroed out */
- memcpy(&rarpreq.thwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
- /* tipaddr is already zeroed out */
-
- for (retry = 0; retry < MAX_ARP_RETRIES; rfc951_sleep(++retry)) {
- eth_transmit(broadcast, RARP, sizeof(rarpreq), &rarpreq);
-
- if (await_reply(AWAIT_RARP, 0, rarpreq.shwaddr, TIMEOUT))
- break;
- }
-
- if (retry < MAX_ARP_RETRIES) {
- sprintf(kernel = kernel_buf, "/tftpboot/kernel.%I", arptable[ARP_CLIENT].ipaddr);
-
- return (1);
- }
- return (0);
-}
-
-#else
-
-/**************************************************************************
-BOOTP - Get my IP address and load information
-**************************************************************************/
-int bootp()
-{
- int retry;
-#ifndef NO_DHCP_SUPPORT
- int retry1;
-#endif /* NO_DHCP_SUPPORT */
- struct bootp_t bp;
- unsigned long starttime;
-#ifdef T509HACK
- int flag;
-
- flag = 1;
-#endif
- memset(&bp, 0, sizeof(struct bootp_t));
- bp.bp_op = BOOTP_REQUEST;
- bp.bp_htype = 1;
- bp.bp_hlen = ETHER_ADDR_SIZE;
- bp.bp_xid = xid = starttime = currticks();
- memcpy(bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
-#ifdef NO_DHCP_SUPPORT
- memcpy(bp.bp_vend, rfc1533_cookie, 5); /* request RFC-style options */
-#else
- memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie); /* request RFC-style options */
- memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcpdiscover, sizeof dhcpdiscover);
- memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcpdiscover, rfc1533_end, sizeof rfc1533_end);
-#endif /* NO_DHCP_SUPPORT */
-
- for (retry = 0; retry < MAX_BOOTP_RETRIES; ) {
-
- /* Clear out the Rx queue first. It contains nothing of
- * interest, except possibly ARP requests from the DHCP/TFTP
- * server. We use polling throughout Etherboot, so some time
- * may have passed since we last polled the receive queue,
- * which may now be filled with broadcast packets. This will
- * cause the reply to the packets we are about to send to be
- * lost immediately. Not very clever. */
- await_reply(AWAIT_QDRAIN, 0, NULL, 0);
-
- udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
- sizeof(struct bootp_t), &bp);
-#ifdef T509HACK
- if (flag) {
- flag--;
- } else {
- if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))
- return(1);
- rfc951_sleep(++retry);
-
- }
-#else
-#ifdef NO_DHCP_SUPPORT
- if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))
-#else
- if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT)){
- if (dhcp_reply==DHCPOFFER){
- dhcp_reply=0;
- memcpy(bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
- memcpy(bp.bp_vend+sizeof rfc1533_cookie, dhcprequest, sizeof dhcprequest);
- memcpy(bp.bp_vend+sizeof rfc1533_cookie +sizeof dhcprequest, rfc1533_end, sizeof rfc1533_end);
- memcpy(bp.bp_vend+9, &dhcp_server, sizeof(in_addr));
- memcpy(bp.bp_vend+15, &dhcp_addr, sizeof(in_addr));
- for (retry1 = 0; retry1 < MAX_BOOTP_RETRIES;) {
- udp_transmit(IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
- sizeof(struct bootp_t), &bp);
- dhcp_reply=0;
- if (await_reply(AWAIT_BOOTP, 0, NULL, TIMEOUT))
- if (dhcp_reply==DHCPACK)
- return(1);
- rfc951_sleep(++retry1);
- }
- } else
-#endif /* NO_DHCP_SUPPORT */
- return(1);
-#ifndef NO_DHCP_SUPPORT
- }
- rfc951_sleep(++retry);
-
-#endif /* NO_DHCP_SUPPORT */
-#endif
- bp.bp_secs = htons((currticks()-starttime)/20);
- }
- return(0);
-}
-#endif /* RARP_NOT_BOOTP */
-
-/**************************************************************************
-AWAIT_REPLY - Wait until we get a response for our request
-**************************************************************************/
-int await_reply(int type, int ival, void *ptr, int timeout)
-{
- unsigned long time;
- struct iphdr *ip;
- struct udphdr *udp;
- struct arprequest *arpreply;
- struct bootp_t *bootpreply;
- struct rpc_t *rpc;
- unsigned short ptype;
-
- unsigned int protohdrlen = ETHER_HDR_SIZE + sizeof(struct iphdr) +
- sizeof(struct udphdr);
- time = timeout + currticks();
- /* The timeout check is done below. The timeout is only checked if
- * there is no packet in the Rx queue. This assumes that eth_poll()
- * needs a negligible amount of time. */
- for (;;) {
- if (eth_poll()) { /* We have something! */
- /* Check for ARP - No IP hdr */
- if (nic.packetlen >= ETHER_HDR_SIZE) {
- ptype = ((unsigned short) nic.packet[12]) << 8
- | ((unsigned short) nic.packet[13]);
- } else continue; /* what else could we do with it? */
- if ((nic.packetlen >= ETHER_HDR_SIZE +
- sizeof(struct arprequest)) &&
- (ptype == ARP) ) {
- unsigned long tmp;
-
- arpreply = (struct arprequest *)
- &nic.packet[ETHER_HDR_SIZE];
- if ((arpreply->opcode == ntohs(ARP_REPLY)) &&
- !memcmp(arpreply->sipaddr, ptr, sizeof(in_addr)) &&
- (type == AWAIT_ARP)) {
- memcpy(arptable[ival].node, arpreply->shwaddr, ETHER_ADDR_SIZE);
- return(1);
- }
- memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
- if ((arpreply->opcode == ntohs(ARP_REQUEST)) &&
- (tmp == arptable[ARP_CLIENT].ipaddr.s_addr)) {
- arpreply->opcode = htons(ARP_REPLY);
- memcpy(arpreply->tipaddr, arpreply->sipaddr, sizeof(in_addr));
- memcpy(arpreply->thwaddr, arpreply->shwaddr, ETHER_ADDR_SIZE);
- memcpy(arpreply->sipaddr, &arptable[ARP_CLIENT].ipaddr, sizeof(in_addr));
- memcpy(arpreply->shwaddr, arptable[ARP_CLIENT].node, ETHER_ADDR_SIZE);
- eth_transmit(arpreply->thwaddr, ARP,
- sizeof(struct arprequest),
- arpreply);
-#ifdef MDEBUG
- memcpy(&tmp, arpreply->tipaddr, sizeof(in_addr));
- printf("Sent ARP reply to: %I\n",tmp);
-#endif MDEBUG
- }
- continue;
- }
-
- if (type == AWAIT_QDRAIN) {
- continue;
- }
-
- /* Check for RARP - No IP hdr */
- if ((type == AWAIT_RARP) &&
- (nic.packetlen >= ETHER_HDR_SIZE +
- sizeof(struct arprequest)) &&
- (ptype == RARP)) {
- arpreply = (struct arprequest *)
- &nic.packet[ETHER_HDR_SIZE];
- if ((arpreply->opcode == ntohs(RARP_REPLY)) &&
- !memcmp(arpreply->thwaddr, ptr, ETHER_ADDR_SIZE)) {
- memcpy(arptable[ARP_SERVER].node, arpreply->shwaddr, ETHER_ADDR_SIZE);
- memcpy(& arptable[ARP_SERVER].ipaddr, arpreply->sipaddr, sizeof(in_addr));
- memcpy(& arptable[ARP_CLIENT].ipaddr, arpreply->tipaddr, sizeof(in_addr));
- return(1);
- }
- continue;
- }
-
- /* Anything else has IP header */
- if ((nic.packetlen < protohdrlen) ||
- (ptype != IP) ) continue;
- ip = (struct iphdr *)&nic.packet[ETHER_HDR_SIZE];
- if ((ip->verhdrlen != 0x45) ||
- ipchksum((unsigned short *)ip, sizeof(struct iphdr)) ||
- (ip->protocol != IP_UDP)) continue;
- udp = (struct udphdr *)&nic.packet[ETHER_HDR_SIZE +
- sizeof(struct iphdr)];
-
- /* BOOTP ? */
- bootpreply = (struct bootp_t *)&nic.packet[ETHER_HDR_SIZE];
- if ((type == AWAIT_BOOTP) &&
- (nic.packetlen >= (ETHER_HDR_SIZE +
-#ifdef NO_DHCP_SUPPORT
- sizeof(struct bootp_t))) &&
-#else
- sizeof(struct bootp_t))-DHCP_OPT_LEN) &&
-#endif /* NO_DHCP_SUPPORT */
- (ntohs(udp->dest) == BOOTP_CLIENT) &&
- (bootpreply->bp_op == BOOTP_REPLY) &&
- (bootpreply->bp_xid == xid)) {
- arptable[ARP_CLIENT].ipaddr.s_addr =
- bootpreply->bp_yiaddr.s_addr;
-#ifndef NO_DHCP_SUPPORT
- dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;
-#endif /* NO_DHCP_SUPPORT */
- netmask = default_netmask();
- arptable[ARP_SERVER].ipaddr.s_addr =
- bootpreply->bp_siaddr.s_addr;
- memset(arptable[ARP_SERVER].node, 0, ETHER_ADDR_SIZE); /* Kill arp */
- arptable[ARP_GATEWAY].ipaddr.s_addr =
- bootpreply->bp_giaddr.s_addr;
- memset(arptable[ARP_GATEWAY].node, 0, ETHER_ADDR_SIZE); /* Kill arp */
- if (bootpreply->bp_file[0]) {
- memcpy(kernel_buf, bootpreply->bp_file, 128);
- kernel = kernel_buf;
- }
- memcpy((char *)BOOTP_DATA_ADDR, (char *)bootpreply, sizeof(struct bootpd_t));
- decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend,
-#ifdef NO_DHCP_SUPPORT
- 0, BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 1);
-#else
- 0, DHCP_OPT_LEN + MAX_BOOTP_EXTLEN, 1);
-#endif /* NO_DHCP_SUPPORT */
- return(1);
- }
-
-#ifdef DOWNLOAD_PROTO_TFTP
- /* TFTP ? */
- if ((type == AWAIT_TFTP) &&
- (ntohs(udp->dest) == ival)) return(1);
-#endif /* DOWNLOAD_PROTO_TFTP */
-
-#ifdef DOWNLOAD_PROTO_NFS
- /* RPC ? */
- rpc = (struct rpc_t *)&nic.packet[ETHER_HDR_SIZE];
- if ((type == AWAIT_RPC) &&
- (ntohs(udp->dest) == ival) &&
- (*(unsigned long *)ptr == ntohl(rpc->u.reply.id)) &&
- (ntohl(rpc->u.reply.type) == MSG_REPLY)) {
- return (1);
- }
-#endif /* DOWNLOAD_PROTO_NFS */
-
- } else {
- /* Check for abort key only if the Rx queue is empty -
- * as long as we have something to process, don't
- * assume that something failed. It is unlikely that
- * we have no processing time left between packets. */
- if (iskey() && (getchar() == ESC))
-#ifdef EMERGENCYDISKBOOT
- exit(0);
-#else
- longjmp(jmp_bootmenu,1);
-#endif
- /* Do the timeout after at least a full queue walk. */
- if ((timeout == 0) || (currticks() > time)) {
- break;
- }
- }
- }
- return(0);
-}
-
-/**************************************************************************
-DECODE_RFC1533 - Decodes RFC1533 header
-**************************************************************************/
-int decode_rfc1533(p, block, len, eof)
- register unsigned char *p;
- int block, len, eof;
-{
- static unsigned char *extdata = NULL, *extend = NULL;
- unsigned char *extpath = NULL;
- unsigned char *endp;
-
- if (block == 0) {
-#ifdef IMAGE_MENU
- memset(imagelist, 0, sizeof(imagelist));
- menudefault = useimagemenu = 0;
- menutmo = -1;
-#endif
-#ifdef MOTD
- memset(motd, 0, sizeof(motd));
-#endif
- end_of_rfc1533 = NULL;
- vendorext_isvalid = 0;
- if (memcmp(p, rfc1533_cookie, 4))
- return(0); /* no RFC 1533 header found */
- p += 4;
- endp = p + len; }
- else {
- if (block == 1) {
- if (memcmp(p, rfc1533_cookie, 4))
- return(0); /* no RFC 1533 header found */
- p += 4;
- len -= 4; }
- if (extend + len <= (unsigned char *)&(BOOTP_DATA_ADDR->bootp_extension[MAX_BOOTP_EXTLEN])) {
- memcpy(extend, p, len);
- extend += len;
- } else {
- printf("Overflow in vendor data buffer! Aborting...\n");
- *extdata = RFC1533_END;
- return(0);
- }
- p = extdata; endp = extend;
- }
- if (eof) {
- while(p < endp) {
- unsigned char c = *p;
- if (c == RFC1533_PAD) {p++; continue;}
- else if (c == RFC1533_END) {
- end_of_rfc1533 = endp = p; continue; }
- else if (c == RFC1533_NETMASK) {memcpy(&netmask, p+2, sizeof(in_addr));}
-
- else if (c == RFC1533_GATEWAY) {
- /* This is a little simplistic, but it will
- usually be sufficient.
- Take only the first entry */
- if (TAG_LEN(p) >= sizeof(in_addr))
- memcpy(&arptable[ARP_GATEWAY].ipaddr, p+2, sizeof(in_addr));
- }
- else if (c == RFC1533_EXTENSIONPATH)
- extpath = p;
-#ifndef NO_DHCP_SUPPORT
- else if (c == RFC2132_MSG_TYPE)
- { dhcp_reply=*(p+2);
- }
- else if (c == RFC2132_SRV_ID)
- {
- memcpy(&dhcp_server, p+2, sizeof(in_addr));
- }
-#endif /* NO_DHCP_SUPPORT */
- else if (c == RFC1533_HOSTNAME)
- {
- hostname = p + 2;
- hostnamelen = *(p + 1);
- }
- else if (c == RFC1533_VENDOR_MAGIC
-#ifndef IMAGE_FREEBSD /* since FreeBSD uses tag 128 for swap definition */
- && TAG_LEN(p) >= 6 &&
- !memcmp(p+2,vendorext_magic,4) &&
- p[6] == RFC1533_VENDOR_MAJOR
-#endif
- )
- vendorext_isvalid++;
-#ifdef IMAGE_FREEBSD
- else if (c == RFC1533_VENDOR_HOWTO) {
- freebsd_howto = ((p[2]*256+p[3])*256+p[4])*256+p[5];
- }
-#endif
-#ifdef IMAGE_MENU
- else if (c == RFC1533_VENDOR_MNUOPTS) {
- parse_menuopts(p+2, TAG_LEN(p));
- }
- else if (c >= RFC1533_VENDOR_IMG &&
- c<RFC1533_VENDOR_IMG+RFC1533_VENDOR_NUMOFIMG){
- imagelist[c - RFC1533_VENDOR_IMG] = p;
- useimagemenu++;
- }
-#endif
-#ifdef MOTD
- else if (c >= RFC1533_VENDOR_MOTD &&
- c < RFC1533_VENDOR_MOTD +
- RFC1533_VENDOR_NUMOFMOTD)
- motd[c - RFC1533_VENDOR_MOTD] = p;
-#endif
- else {
-#if 0
- unsigned char *q;
- printf("Unknown RFC1533-tag ");
- for(q=p;q<p+2+TAG_LEN(p);q++)
- printf("%x ",*q);
- putchar('\n');
-#endif
- }
- p += TAG_LEN(p) + 2;
- }
- extdata = extend = endp;
- if (block == 0 && extpath != NULL) {
- char fname[64];
- memcpy(fname, extpath+2, TAG_LEN(extpath));
- fname[(int)TAG_LEN(extpath)] = '\000';
- printf("Loading BOOTP-extension file: %s\n",fname);
- download(fname,decode_rfc1533);
- }
- }
- return(-1); /* proceed with next block */
-}
-
-/**************************************************************************
-IPCHKSUM - Checksum IP Header
-**************************************************************************/
-unsigned short ipchksum(ip, len)
- register unsigned short *ip;
- register int len;
-{
- unsigned long sum = 0;
- len >>= 1;
- while (len--) {
- sum += *(ip++);
- if (sum > 0xFFFF)
- sum -= 0xFFFF;
- }
- return((~sum) & 0x0000FFFF);
-}
-
-/**************************************************************************
-RFC951_SLEEP - sleep for expotentially longer times
-**************************************************************************/
-void rfc951_sleep(exp)
- int exp;
-{
- static long seed = 0;
- long q;
- unsigned long tmo;
-
-#ifdef BACKOFF_LIMIT
- if (exp > BACKOFF_LIMIT)
- exp = BACKOFF_LIMIT;
-#endif
- if (!seed) /* Initialize linear congruential generator */
- seed = currticks() + *(long *)&arptable[ARP_CLIENT].node
- + ((short *)arptable[ARP_CLIENT].node)[2];
- /* simplified version of the LCG given in Bruce Scheier's
- "Applied Cryptography" */
- q = seed/53668;
- if ((seed = 40014*(seed-53668*q) - 12211*q) < 0) seed += 2147483563l;
- /* compute mask */
- for (tmo = 63; tmo <= 60*TICKS_PER_SEC && --exp > 0; tmo = 2*tmo+1);
- /* sleep */
- printf("<sleep>\n");
-
- for (tmo = (tmo&seed)+currticks(); currticks() < tmo; )
- if (iskey() && (getchar() == ESC)) longjmp(jmp_bootmenu,1);
- return;
-}
-
-/**************************************************************************
-CLEANUP_NET - shut down networking
-**************************************************************************/
-void cleanup_net(void)
-{
-#ifdef DOWNLOAD_PROTO_NFS
- nfs_umountall(ARP_SERVER);
-#endif
- eth_disable();
- eth_reset();
-}
-
-/**************************************************************************
-CLEANUP - shut down etherboot so that the OS may be called right away
-**************************************************************************/
-void cleanup(void)
-{
-#if defined(ANSIESC) && defined(CONSOLE_CRT)
- ansi_reset();
-#endif
-}
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/contrib/baremetal/marini.txt b/contrib/baremetal/marini.txt
deleted file mode 100644
index 464f1488..00000000
--- a/contrib/baremetal/marini.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-From: "Paolo Marini" <paolom@prisma-eng.it>
-Subject: Etherboot on bare metal
-Date: Tue, 10 Apr 2001 23:19:19 +0200
-Organization: Prisma Engineering srl
-
-Hi Ken,
-I have ported Etherboot on an embedded, biosless platform and would like
-to contribute the code.
-
-Essentially, the hardware I was running Etherboot is a Pentium based
-embedded system, with an Intel Chipset, *but* without serial, VGA,
-keyboard etc., only an 82559 Intel (custom) Ethernet controller (I debug
-it with the etheral Ethernet packet analyser and an emulator).
-
-What I did was:
-
- a.. integrate the init.s file within the firmware, with GDT
-(re)initialisation (a simple and single entry point taking control of
-the boot process)
- b.. provide some stupid BIOS stubs in order to let the OS boot and
-still belive that an INT10 call goes to the BIOS
- c.. provide some basic functions to Etherboot, like timer (I used the
-Pentium TSC internal counter)
- d.. hardwire in the code information about the RAM size
-The BIOS stubs are enough to boot Linux, pSOS and QNX with bootp. QNX is
-somewhat difficult to load, because the i82559 driver tries to find the
-component using the BIOS32 calls, so I had to patch it.
-
-what i I got from the original firmware is the PCI initialisation and
-resource (I/O, interrupts, memory) allocation.
-
-I send you what I changed, that is, the initialisation code and the
-misc.c file containing the timer, and the makefile (I don't remember
-exactly the options I used to compile all).
-
-Of course, it is only a good starting point for anyone wanting to
-implement a bootp client on a biosless platform; some integration work
-still needs to be done.
-
-Ciao
-Paolo
-
-And in a subsequent email:
-
-I worked with version 4.6.12, but the real modifications involve the
-init.S file, which I think is quite sstable between releases. I forgot
-to say that my entry point (symbol _start in init.s) assumes the
-processor is already in protected mode.
-
-[The only difference between main.c and misc.c from those in Etherboot
-4.6.12 seems to be the deletion of eth_reset(). This may be of use to
-others trying to make these changes work on more recent releases. Ken]
diff --git a/contrib/baremetal/misc.c b/contrib/baremetal/misc.c
deleted file mode 100644
index 924ccd6d..00000000
--- a/contrib/baremetal/misc.c
+++ /dev/null
@@ -1,351 +0,0 @@
-/**************************************************************************
-MISC Support Routines
-**************************************************************************/
-
-#include "etherboot.h"
-
-/**************************************************************************
-SLEEP
-**************************************************************************/
-void sleep(int secs)
-{
- unsigned long tmo;
-
- for (tmo = currticks()+secs*TICKS_PER_SEC; currticks() < tmo; )
- /* Nothing */;
-}
-
-/**************************************************************************
-TWIDDLE
-**************************************************************************/
-void twiddle()
-{
- static unsigned long lastticks = 0;
- static int count=0;
- static const char tiddles[]="-\\|/";
- unsigned long ticks;
- if ((ticks = currticks()) == lastticks)
- return;
- lastticks = ticks;
- putchar(tiddles[(count++)&3]);
- putchar('\b');
-}
-
-/**************************************************************************
-STRCASECMP (not entirely correct, but this will do for our purposes)
-**************************************************************************/
-int strcasecmp(a,b)
- char *a, *b;
-{
- while (*a && *b && (*a & ~0x20) == (*b & ~0x20)) {a++; b++; }
- return((*a & ~0x20) - (*b & ~0x20));
-}
-
-/**************************************************************************
-PRINTF and friends
-
- Formats:
- %[#]X - 4 bytes long (8 hex digits)
- %[#]x - 2 bytes int (4 hex digits)
- - optional # prefixes 0x
- %b - 1 byte int (2 hex digits)
- %d - decimal int
- %c - char
- %s - string
- %I - Internet address in x.x.x.x notation
- Note: width specification not supported
-**************************************************************************/
-static char *do_printf(char *buf, const char *fmt, const int *dp)
-{
- register char *p;
- int alt;
- char tmp[16];
- static const char hex[]="0123456789ABCDEF";
-
- while (*fmt) {
- if (*fmt == '%') { /* switch() uses more space */
- alt = 0;
- fmt++;
- if (*fmt == '#') {
- alt = 1;
- fmt++;
- }
- if (*fmt == 'X') {
- const long *lp = (const long *)dp;
- register long h = *lp++;
- dp = (const int *)lp;
- if (alt) {
- *buf++ = '0';
- *buf++ = 'x';
- }
- *(buf++) = hex[(h>>28)& 0x0F];
- *(buf++) = hex[(h>>24)& 0x0F];
- *(buf++) = hex[(h>>20)& 0x0F];
- *(buf++) = hex[(h>>16)& 0x0F];
- *(buf++) = hex[(h>>12)& 0x0F];
- *(buf++) = hex[(h>>8)& 0x0F];
- *(buf++) = hex[(h>>4)& 0x0F];
- *(buf++) = hex[h& 0x0F];
- }
- if (*fmt == 'x') {
- register int h = *(dp++);
- if (alt) {
- *buf++ = '0';
- *buf++ = 'x';
- }
- *(buf++) = hex[(h>>12)& 0x0F];
- *(buf++) = hex[(h>>8)& 0x0F];
- *(buf++) = hex[(h>>4)& 0x0F];
- *(buf++) = hex[h& 0x0F];
- }
- if (*fmt == 'b') {
- register int h = *(dp++);
- *(buf++) = hex[(h>>4)& 0x0F];
- *(buf++) = hex[h& 0x0F];
- }
- if (*fmt == 'd') {
- register int dec = *(dp++);
- p = tmp;
- if (dec < 0) {
- *(buf++) = '-';
- dec = -dec;
- }
- do {
- *(p++) = '0' + (dec%10);
- dec = dec/10;
- } while(dec);
- while ((--p) >= tmp) *(buf++) = *p;
- }
- if (*fmt == 'I') {
- union {
- long l;
- unsigned char c[4];
- } u;
- const long *lp = (const long *)dp;
- u.l = *lp++;
- dp = (const int *)lp;
- buf = sprintf(buf,"%d.%d.%d.%d",
- u.c[0], u.c[1], u.c[2], u.c[3]);
- }
- if (*fmt == 'c')
- *(buf++) = *(dp++);
- if (*fmt == 's') {
- p = (char *)*dp++;
- while (*p) *(buf++) = *p++;
- }
- } else *(buf++) = *fmt;
- fmt++;
- }
- *buf = '\0';
- return(buf);
-}
-
-char *sprintf(char *buf, const char *fmt, ...)
-{
- return do_printf(buf, fmt, ((const int *)&fmt)+1);
-}
-
-void printf(const char *fmt, ...)
-{
- char buf[120], *p;
-
- p = buf;
- do_printf(buf, fmt, ((const int *)&fmt)+1);
- while (*p) putchar(*p++);
-}
-
-#ifdef IMAGE_MENU
-/**************************************************************************
-INET_ATON - Convert an ascii x.x.x.x to binary form
-**************************************************************************/
-int inet_aton(char *p, in_addr *i)
-{
- unsigned long ip = 0;
- int val;
- if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
- if (*p != '.') return(0);
- p++;
- ip = val;
- if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
- if (*p != '.') return(0);
- p++;
- ip = (ip << 8) | val;
- if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
- if (*p != '.') return(0);
- p++;
- ip = (ip << 8) | val;
- if (((val = getdec(&p)) < 0) || (val > 255)) return(0);
- i->s_addr = htonl((ip << 8) | val);
- return(1);
-}
-
-#endif /* IMAGE_MENU */
-
-int getdec(char **ptr)
-{
- char *p = *ptr;
- int ret=0;
- if ((*p < '0') || (*p > '9')) return(-1);
- while ((*p >= '0') && (*p <= '9')) {
- ret = ret*10 + (*p - '0');
- p++;
- }
- *ptr = p;
- return(ret);
-}
-
-#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */
-#define K_STATUS 0x64 /* keyboard status */
-#define K_CMD 0x64 /* keybd ctlr command (write-only) */
-
-#define K_OBUF_FUL 0x01 /* output buffer full */
-#define K_IBUF_FUL 0x02 /* input buffer full */
-
-#define KC_CMD_WIN 0xd0 /* read output port */
-#define KC_CMD_WOUT 0xd1 /* write output port */
-#define KB_SET_A20 0xdf /* enable A20,
- enable output buffer full interrupt
- enable data line
- disable clock line */
-#define KB_UNSET_A20 0xdd /* enable A20,
- enable output buffer full interrupt
- enable data line
- disable clock line */
-#ifndef IBM_L40
-static void empty_8042(void)
-{
- unsigned long time;
- char st;
-
- time = currticks() + TICKS_PER_SEC; /* max wait of 1 second */
- while ((((st = inb(K_CMD)) & K_OBUF_FUL) ||
- (st & K_IBUF_FUL)) &&
- currticks() < time)
- inb(K_RDWR);
-}
-#endif IBM_L40
-
-/*
- * Gate A20 for high memory
- */
-void gateA20_set(void)
-{
-#ifdef IBM_L40
- outb(0x2, 0x92);
-#else /* IBM_L40 */
- empty_8042();
- outb(KC_CMD_WOUT, K_CMD);
- empty_8042();
- outb(KB_SET_A20, K_RDWR);
- empty_8042();
-#endif /* IBM_L40 */
-}
-
-#ifdef TAGGED_IMAGE
-/*
- * Unset Gate A20 for high memory - some operating systems (mainly old 16 bit
- * ones) don't expect it to be set by the boot loader.
- */
-void gateA20_unset(void)
-{
-#ifdef IBM_L40
- outb(0x0, 0x92);
-#else /* IBM_L40 */
- empty_8042();
- outb(KC_CMD_WOUT, K_CMD);
- empty_8042();
- outb(KB_UNSET_A20, K_RDWR);
- empty_8042();
-#endif /* IBM_L40 */
-}
-#endif
-
-#ifdef ETHERBOOT32
-/* Serial console is only implemented in ETHERBOOT32 for now */
-void
-putchar(int c)
-{
-#ifndef ANSIESC
- if (c == '\n')
- putchar('\r');
-#endif
-
-#ifdef CONSOLE_CRT
-#ifdef ANSIESC
- handleansi(c);
-#else
- putc(c);
-#endif
-#endif
-#ifdef CONSOLE_SERIAL
-#ifdef ANSIESC
- if (c == '\n')
- serial_putc('\r');
-#endif
- serial_putc(c);
-#endif
-}
-
-/**************************************************************************
-GETCHAR - Read the next character from the console WITHOUT ECHO
-**************************************************************************/
-int
-getchar(void)
-{
- int c = 256;
-
-#if defined CONSOLE_CRT || defined CONSOLE_SERIAL
- do {
-#ifdef CONSOLE_CRT
- if (ischar())
- c = getc();
-#endif
-#ifdef CONSOLE_SERIAL
- if (serial_ischar())
- c = serial_getc();
-#endif
- } while (c==256);
- if (c == '\r')
- c = '\n';
-#endif
- return c;
-}
-
-int
-iskey(void)
-{
-#ifdef CONSOLE_CRT
- if (ischar())
- return 1;
-#endif
-#ifdef CONSOLE_SERIAL
- if (serial_ischar())
- return 1;
-#endif
- return 0;
-}
-#endif /* ETHERBOOT32 */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
-
-#include <asm/msr.h>
-
-#define CPUCLOCK 166
-
-unsigned long currticks(void)
-{
- register unsigned long l, h;
- long long unsigned p;
- long long unsigned hh,ll;
-
- rdtsc(l, h);
- ll = l, hh = h;
-
- p = (ll + hh * 0x100000000LL) * 182 / (CPUCLOCK * 100000LL);
- return (unsigned)p;
-}
-
diff --git a/contrib/baremetal/startmpcc.S b/contrib/baremetal/startmpcc.S
deleted file mode 100644
index 07486ce5..00000000
--- a/contrib/baremetal/startmpcc.S
+++ /dev/null
@@ -1,756 +0,0 @@
-/* #defines because ljmp wants a number, probably gas bug */
-/* .equ KERN_CODE_SEG,_pmcs-_gdt */
-#define KERN_CODE_SEG 0x08
- .equ KERN_DATA_SEG,_pmds-_gdt
-/* .equ REAL_CODE_SEG,_rmcs-_gdt */
-#define REAL_CODE_SEG 0x18
- .equ REAL_DATA_SEG,_rmds-_gdt
- .equ CR0_PE,1
-
-#ifdef GAS291
-#define DATA32 data32;
-#define ADDR32 addr32;
-#define LJMPI(x) ljmp x
-#else
-#define DATA32 data32
-#define ADDR32 addr32
-/* newer GAS295 require #define LJMPI(x) ljmp *x */
-#define LJMPI(x) ljmp x
-#endif
-
-#define PIC1_VBS 0x08 /* PIC1 interrupts start at vector 64 */
-#define PIC2_VBS 0x70 /* PIC1 interrupts start at vector 112 */
-
-/*
- * NOTE: if you write a subroutine that is called from C code (gcc/egcs),
- * then you only have to take care of %ebx, %esi, %edi and %ebp. These
- * registers must not be altered under any circumstance. All other registers
- * may be clobbered without any negative side effects. If you don't follow
- * this rule then you'll run into strange effects that only occur on some
- * gcc versions (because the register allocator may use different registers).
- *
- * All the data32 prefixes for the ljmp instructions are necessary, because
- * the assembler emits code with a relocation address of 0. This means that
- * all destinations are initially negative, which the assembler doesn't grok,
- * because for some reason negative numbers don't fit into 16 bits. The addr32
- * prefixes are there for the same reasons, because otherwise the memory
- * references are only 16 bit wide. Theoretically they are all superfluous.
- * One last note about prefixes: the data32 prefixes on all call _real_to_prot
- * instructions could be removed if the _real_to_prot function is changed to
- * deal correctly with 16 bit return addresses. I tried it, but failed.
- */
-
-/**************************************************************************
-START - Where all the fun begins....
-**************************************************************************/
-/* this must be the first thing in the file because we enter from the top */
- .global _start
- .code32
-_start:
- cli
-
- /* load new IDT and GDT */
- lgdt gdtarg
- lidt Idt_Reg
- /* flush prefetch queue, and reload %cs:%eip */
- ljmp $KERN_CODE_SEG,$1f
-1:
-
- /* reload other segment registers */
- movl $KERN_DATA_SEG,%eax
- movl %eax,%ds
- movl %eax,%es
- movl %eax,%ss
- movl $stktop,%esp
-
- /* program the PITs in order to stop them */
- mov $0x30,%al
- out %al,$0x43
- out %al,$0x40
- mov $0x70,%al
- out %al,$0x43
- out %al,$0x41
- mov $0xf0,%al
- out %al,$0x43
- out %al,$0x42
-
- call main
- /* fall through */
-
- .globl exit
-exit:
-2:
- ljmp $KERN_CODE_SEG,$2b
-
-/**************************************************************************
-MEMSIZE - Determine size of extended memory
-**************************************************************************/
- .globl memsize
-memsize:
-#if 0
- pushl %ebx
- pushl %esi
- pushl %edi
- call _prot_to_real
- .code16
- movw $0xe801,%ax
- stc
- int $0x15
- jc 1f
- andl $0xffff,%eax
- andl $0xffff,%ebx
- shll $6,%ebx
- addl %ebx,%eax
- jmp 2f
-1:
- movw $0x8800,%ax
- int $0x15
- andl $0xffff,%eax
-2:
- movl %eax,%esi
- DATA32 call _real_to_prot
- .code32
- movl %esi,%eax
- popl %edi
- popl %esi
- popl %ebx
-#else
- mov $32768,%eax
-#endif
- ret
-
-/**************************************************************************
-XSTART - Transfer control to the kernel just loaded
-**************************************************************************/
- .code16
-
- .globl _int08_handler
-_int08_handler:
- movb $0x20, %al
- outb %al, $0x20
- iret
-
- .globl _int10_handler
-_int10_handler:
- cmp $0x3, %ah
- jnz _int10_04
- mov $0x0, %dx
- mov $0x0, %cx
- iret
-_int10_04:
- cmp $0x4, %ah
- jnz _int10_05
- mov $0x0, %ah
- iret
-_int10_05:
- cmp $0x5, %ah
- jnz _int10_08
- mov $0x0, %al
- iret
-_int10_08:
- cmp $0x8, %ah
- jnz _int10_0D
- mov $0x20, %al
- mov $0x7, %ah
- iret
-_int10_0D:
- cmp $0xD, %ah
- jnz _int10_0F
- mov $0x0, %al
- iret
-_int10_0F:
- cmp $0xF, %ah
- jnz _int10_XX
- mov $0xb, %al
- mov $80, %ah
- mov $0, %bh
-_int10_XX:
- iret
-
- .globl _int11_handler
-_int11_handler:
- mov $0x22, %ax
- iret
-
- .globl _int12_handler
-_int12_handler:
- mov $640, %ax
- iret
-
- .globl _int13_handler
-_int13_handler:
- clc
- mov $0, %ah
- iret
-
- .globl _int14_handler
-_int14_handler:
- iret
-
- .globl _int15_handler
-_int15_handler:
- cmp $0xe801,%ax
- jz _int15_008
- cmp $0x0, %ah
- jz _int15_000
- cmp $0x1, %ah
- jz _int15_000
- cmp $0x2, %ah
- jz _int15_000
- cmp $0x3, %ah
- jz _int15_000
- cmp $0xf, %ah
- jz _int15_000
- cmp $0x21, %ah
- jz _int15_000
- cmp $0x40, %ah
- jz _int15_000
- cmp $0x41, %ah
- jz _int15_000
- cmp $0x42, %ah
- jz _int15_000
- cmp $0x43, %ah
- jz _int15_000
- cmp $0x44, %ah
- jz _int15_000
- cmp $0x80, %ah
- jz _int15_001
- cmp $0x81, %ah
- jz _int15_001
- cmp $0x82, %ah
- jz _int15_002
- cmp $0x83, %ah
- jz _int15_003
- cmp $0x84, %ah
- jz _int15_000
- cmp $0x85, %ah
- jz _int15_004
- cmp $0x86, %ah
- jz _int15_003
- cmp $0x87, %ah
- jz _int15_005
- cmp $0x88, %ah
- jz _int15_006
- cmp $0x89, %ah
- jz _int15_005
- cmp $0x90, %ah
- jz _int15_007
- cmp $0xc0, %ah
- jz _int15_000
- cmp $0xc1, %ah
- jz _int15_000
- cmp $0xc2, %ah
- jz _int15_000
- cmp $0xc3, %ah
- jz _int15_000
- cmp $0xc4, %ah
- jz _int15_000
- iret
-
-_int15_000:
- mov $0x86, %ah
- stc
- iret
-
-_int15_001:
- mov $0, %bx
- mov $0, %cx
- iret
-
-_int15_002:
- mov $0, %bx
- iret
-
-_int15_003:
- clc
- iret
-
-_int15_004:
- mov $0, %al
- iret
-
-_int15_005:
- mov $0, %ah
- clc
- cmp $0, %ah
- iret
-
-_int15_006:
- mov $0xf000, %ax
- iret
-
-_int15_007:
- stc
- iret
-
-_int15_008:
- clc
- mov $1024, %dx /* dx -> extended memory size (in 64K chuncks) */
- mov $640, %cx /* cx -> conventional memory size (in 1 Kbytes chuncks) */
- iret
-
- .globl _int16_handler
-_int16_handler:
- cmp $0x0, %ah
- jnz _int16_01
- mov $0x20, %al
- mov $0x39, %ah
- iret
-_int16_01:
- cmp $0x1, %ah
- jnz _int16_02
- iret
-_int16_02:
- cmp $0x2, %ah
- jnz _int16_05
- mov $0, %al
- iret
-_int16_05:
- cmp $0x5, %ah
- jnz _int16_10
- mov $0, %al
- iret
-_int16_10:
- cmp $0x10, %ah
- jnz _int16_11
- mov $0x20, %al
- mov $0x39, %ah
- iret
-_int16_11:
- cmp $0x11, %ah
- jnz _int16_12
- iret
-_int16_12:
- cmp $0x12, %ah
- jnz _int16_XX
- mov $0, %ax
- iret
-_int16_XX:
- iret
-
- .globl _int17_handler
-_int17_handler:
- mov $0xd0, %ah
- iret
-
- .globl _int19_handler
-_int19_handler:
- hlt
- iret
-
- .globl _int1A_handler
-_int1A_handler:
- stc
- iret
-
- .code32
- .globl xstart
-xstart:
- /* reprogram the PICs so that interrupt are masked */
- movb $0x11,%al /* ICW1 [ICW4 NEEDED, EDGE TRIGGERED]*/
- outb %al,$0x20
- movb $PIC1_VBS, %al
- outb %al,$0x21
- movb $0x4,%al
- outb %al,$0x21
- movb $0x1,%al
- outb %al,$0x21
- movb $0xff,%al
- outb %al,$0x21
-
- movb $0x11,%al /* ICW1 [ICW4 NEEDED, EDGE TRIGGERED]*/
- outb %al,$0xa0
- movb $PIC2_VBS, %al
- outb %al,$0xa1
- movb $0x2,%al
- outb %al,$0xa1
- movb $0x1,%al
- outb %al,$0xa1
- movb $0xff,%al
- outb %al,$0xa1
-
- pushl %ebp
- movl %esp,%ebp
- pushl %ebx
- pushl %esi
- pushl %edi
- movl 8(%ebp),%eax
- movl %eax,_execaddr
- movl 12(%ebp),%ebx
- movl 16(%ebp),%ecx /* bootp record (32bit pointer) */
- addl $28,%ecx /* ip, udp header */
- shll $12,%ecx
- shrw $12,%cx
- call _prot_to_real
- .code16
-/* MP: add int10 handler */
- push %eax
- push %ebx
- push %es
- mov $0,%ax
- mov %ax,%es
- mov %cs,%ax
- shl $16,%eax
-
- ADDR32 mov $(_int08_handler-_start),%ax
- mov $0x20,%ebx
- mov %eax,%es:(%bx)
-
- ADDR32 mov $(_int10_handler-_start),%ax
- mov $0x40,%ebx
- mov %eax,%es:(%bx)
-
- ADDR32 mov $(_int11_handler-_start),%ax
- mov $0x44,%ebx
- mov %eax,%es:(%bx)
-
- ADDR32 mov $(_int12_handler-_start),%ax
- mov $0x48,%ebx
- mov %eax,%es:(%bx)
-
- ADDR32 mov $(_int13_handler-_start),%ax
- mov $0x4c,%ebx
- mov %eax,%es:(%bx)
-
- ADDR32 mov $(_int14_handler-_start),%ax
- mov $0x50,%ebx
- mov %eax,%es:(%bx)
-
- ADDR32 mov $(_int15_handler-_start),%ax
- mov $0x54,%ebx
- mov %eax,%es:(%bx)
-
- ADDR32 mov $(_int16_handler-_start),%ax
- mov $0x58,%ebx
- mov %eax,%es:(%bx)
-
- ADDR32 mov $(_int17_handler-_start),%ax
- mov $0x5c,%ebx
- mov %eax,%es:(%bx)
-
- ADDR32 mov $(_int19_handler-_start),%ax
- mov $0x64,%ebx
- mov %eax,%es:(%bx)
-
- ADDR32 mov $(_int1A_handler-_start),%ax
- mov $0x68,%ebx
- mov %eax,%es:(%bx)
-
- pop %es
- pop %ebx
- pop %eax
-/* */
- pushl %ecx /* bootp record */
- pushl %ebx /* file header */
- movl $((RELOC<<12)+(1f-RELOC)),%eax
- pushl %eax
- ADDR32 LJMPI(_execaddr-_start)
-1:
- addw $8,%sp /* XXX or is this 10 in case of a 16bit "ret" */
- DATA32 call _real_to_prot
- .code32
- popl %edi
- popl %esi
- popl %ebx
- popl %ebp
- ret
-
-_execaddr:
- .long 0
-
-#ifdef IMAGE_MULTIBOOT
-/**************************************************************************
-XEND - Restart Etherboot from the beginning (from protected mode)
-**************************************************************************/
-
- .globl xend
-xend:
- cs
- lidt idtarg_realmode-_start+RELOC
- cs
- lgdt gdtarg-_start+RELOC
-#ifdef GAS291
- ljmp $REAL_CODE_SEG,$1f-RELOC /* jump to a 16 bit segment */
-#else
- ljmp $REAL_CODE_SEG,$1f-_start /* jump to a 16 bit segment */
-#endif /* GAS291 */
-1:
- .code16
- movw $REAL_DATA_SEG,%ax
- movw %ax,%ds
- movw %ax,%ss
- movw %ax,%es
-
- /* clear the PE bit of CR0 */
- movl %cr0,%eax
- andl $0!CR0_PE,%eax
- movl %eax,%cr0
-
- /* make intersegment jmp to flush the processor pipeline
- * and reload %cs:%eip (to clear upper 16 bits of %eip).
- */
- DATA32 ljmp $(RELOC)>>4,$2f-_start
-2:
- /* we are in real mode now
- * set up the real mode segment registers : %ds, %ss, %es
- */
- movw %cs,%ax
- movw %ax,%ds
- movw %ax,%es
- movw %ax,%ss
- xorl %esp,%esp
- ADDR32 movw initsp-RELOC,%sp
-
- movw $0,%ax
- movw %ax,%fs
- movw %ax,%gs
-
- sti
- jmp _start
-
- .code32
-#endif /* IMAGE_MULTIBOOT */
-
-.global get_cs
-get_cs:
- xorl %eax,%eax
- movw %cs,%ax
- ret
-
-.global get_ds
-get_ds:
- xorl %eax,%eax
- movw %ds,%ax
- ret
-
-.global getsp
-getsp:
- movl %esp,%eax /* GET STACK POINTER */
- subl $4, %eax /* ACCOUNT FOR RETURN ADDRESS ON */
- ret
-
-.global get_gdtbase
-get_gdtbase:
- sub $8,%esp /* ALLOCATE ROOM ON THE STACK */
- sgdt (%esp,1) /*STORE IGDT REGISTER ON STACK */
- mov 2(%esp),%eax /* READ GDT BASE ADDRESS */
- mov $KERN_DATA_SEG,%dx /* ASSUME UNIVERSAL DS. */
- add $8,%esp /* RESTORE STACK */
- ret /* DONE */
-
-.global get_gdtsize
-get_gdtsize:
- sub $8,%esp /* ALLOCATE ROOM ON THE STACK */
- sgdt (%esp,1) /*STORE IGDT REGISTER ON STACK */
- xor %eax,%eax
- mov 2(%esp),%eax /* READ GDT BASE ADDRESS */
- mov (%ESP),%ax
- shr $3,%ax
- add $8,%esp /* RESTORE STACK */
- ret /* DONE */
-
-.global get_idtbase
-get_idtbase:
- sub $8,%esp
- sidt (%esp,1) /* STORE IIDT REGISTER ON STACK */
- mov 2(%esp),%eax
- mov $KERN_DATA_SEG,%dx
- add $8,%esp
- ret
-
-.global get_lw
-get_lw:
- xor %edx,%edx
- mov 8(%esp),%eax
- mov 4(%esp),%dx
- ret
-
-/**************************************************************************
-SETJMP - Save stack context for non-local goto
-**************************************************************************/
- .globl setjmp
-setjmp:
- mov 4(%esp),%ecx
- mov 0(%esp),%edx
- mov %edx,0(%ecx)
- mov %ebx,4(%ecx)
- mov %esp,8(%ecx)
- mov %ebp,12(%ecx)
- mov %esi,16(%ecx)
- mov %edi,20(%ecx)
- mov %eax,24(%ecx)
- mov $0,%eax
- ret
-
-/**************************************************************************
-LONGJMP - Non-local jump to a saved stack context
-**************************************************************************/
- .globl longjmp
-longjmp:
- mov 4(%esp),%edx
- mov 8(%esp),%eax
- mov 0(%edx),%ecx
- mov 4(%edx),%ebx
- mov 8(%edx),%esp
- mov 12(%edx),%ebp
- mov 16(%edx),%esi
- mov 20(%edx),%edi
- cmp $0,%eax
- jne 1f
- mov $1,%eax
-1: mov %ecx,0(%esp)
- ret
-
-/**************************************************************************
-_REAL_TO_PROT - Go from REAL mode to Protected Mode
-**************************************************************************/
- .globl _real_to_prot
-_real_to_prot:
- .code16
- cli
- cs
- ADDR32 lgdt gdtarg-_start
- movl %cr0,%eax
- orl $CR0_PE,%eax
- movl %eax,%cr0 /* turn on protected mode */
-
- /* flush prefetch queue, and reload %cs:%eip */
- DATA32 ljmp $KERN_CODE_SEG,$1f
-1:
- .code32
- /* reload other segment registers */
- movl $KERN_DATA_SEG,%eax
- movl %eax,%ds
- movl %eax,%es
- movl %eax,%ss
- addl $RELOC,%esp /* Fix up stack pointer */
- xorl %eax,%eax
- movl %eax,%fs
- movl %eax,%gs
- popl %eax /* Fix up return address */
- addl $RELOC,%eax
- pushl %eax
- ret
-
-/**************************************************************************
-_PROT_TO_REAL - Go from Protected Mode to REAL Mode
-**************************************************************************/
- .globl _prot_to_real
-_prot_to_real:
- .code32
- popl %eax
- subl $RELOC,%eax /* Adjust return address */
- pushl %eax
- subl $RELOC,%esp /* Adjust stack pointer */
-#ifdef GAS291
- ljmp $REAL_CODE_SEG,$1f-RELOC /* jump to a 16 bit segment */
-#else
- ljmp $REAL_CODE_SEG,$1f-_start /* jump to a 16 bit segment */
-#endif /* GAS291 */
-1:
- .code16
- movw $REAL_DATA_SEG,%ax
- movw %ax,%ds
- movw %ax,%ss
- movw %ax,%es
- movw %ax,%fs
- movw %ax,%gs
- cli
-
- /* clear the PE bit of CR0 */
- movl %cr0,%eax
- andl $0!CR0_PE,%eax
- movl %eax,%cr0
-
- /* make intersegment jmp to flush the processor pipeline
- * and reload %cs:%eip (to clear upper 16 bits of %eip).
- */
- DATA32 ljmp $(RELOC)>>4,$2f-_start
-2:
- /* we are in real mode now
- * set up the real mode segment registers : %ds, $ss, %es
- */
- movw %cs,%ax
- movw %ax,%ds
- movw %ax,%es
- movw %ax,%ss
-#if 0
- sti
-#endif
- DATA32 ret /* There is a 32 bit return address on the stack */
- .code32
-
-/**************************************************************************
-GLOBAL DESCRIPTOR TABLE
-**************************************************************************/
- .align 4
-Idt_Reg:
- .word 0x3ff
- .long 0
-
- .align 4
-_gdt:
-gdtarg:
-Gdt_Table:
- .word 0x27 /* limit */
- .long _gdt /* addr */
- .word 0
-_pmcs:
- /* 32 bit protected mode code segment */
- .word 0xffff,0
- .byte 0,0x9f,0xcf,0
-
-_pmds:
- /* 32 bit protected mode data segment */
- .word 0xffff,0
- .byte 0,0x93,0xcf,0
-
-_rmcs:
- /* 16 bit real mode code segment */
- .word 0xffff,(RELOC&0xffff)
- .byte (RELOC>>16),0x9b,0x00,(RELOC>>24)
-
-_rmds:
- /* 16 bit real mode data segment */
- .word 0xffff,(RELOC&0xffff)
- .byte (RELOC>>16),0x93,0x00,(RELOC>>24)
-
- .align 4
-RUN_GDT: /* POINTER TO GDT IN RAM */
- .byte 0x7f,0 /* [BSP_GDT_NUM*8]-1 */
- .long Gdt_Table
-
- .align 4
-
- .section ".rodata"
-err_not386:
- .ascii "Etherboot/32 requires 386+"
- .byte 0x0d, 0x0a
-err_not386_end:
-
-days: .long 0
-irq_num: .long
-
- .data
- .align 4
- .org 2048
-.global stktop
-stktop:
- .long
-
-.section ".armando"
-/*                1:::::::::2:::::::::3:::::::3 */
-/*        12345678901234567890123456789012345678 */
-/*       v----+----v----+----v----+----v----+--- */
-
-.global EtherbootString
-EtherbootString:
-.ascii "EtherBoot MPCC " /* fw identifier */
-
-.byte 0, 0 /* mandatory hole */
-
-.long _start /* entry point */
-.word 0
-.byte 'E' /* type */
-.byte 0 /* selector */
-.word 0 /* CRC */