Fix serious first32.c bug. Various improvements. Mknbi_1_4_3
authorKen Yap <ken_yap@users.sourceforge.net>
Thu, 4 Dec 2003 21:38:00 +0000 (21:38 +0000)
committerKen Yap <ken_yap@users.sourceforge.net>
Thu, 4 Dec 2003 21:38:00 +0000 (21:38 +0000)
LOG
Makefile
README
first-dos.S
first32.c
mknbi.pl
nfl.c

diff --git a/LOG b/LOG
index c66a7b3..a11b2bf 100644 (file)
--- a/LOG
+++ b/LOG
@@ -203,3 +203,18 @@ Released as mknbi-1.4.1 (production)
 broken by introduction of LUA interpreter.
 
 Released as mknbi-1.4.2 (production)
+
++ first32.c can now be conditionally compiled as a DOS trampoline. Not
+tested, have to postpone to 1.4.4.
+
++ Add Quit Etherboot entry to nfl.c.
+
++ Add mkelf-img program.
+
++ Use perl instead of sed to substitute variables. If they have perl
+for execution they should have perl for building.
+
++ Fix a serious error in mkelf-linux where a reference to a memory location
+in Etherboot was used after moving the initrd up in memory.
+
+Released as mknbi-1.4.3 (production)
index 1fbb91e..635e26c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
-VERSION=1.4.2
+VERSION=1.4.3
 EXTRAVERSION=
-TARVERSION=1.4.2
+TARVERSION=1.4.3
 # spec file can override
 RPMVERSION=$(VERSION)
 
@@ -23,6 +23,9 @@ CFLAGS=               -I. -Os -ffreestanding -fstrength-reduce -fomit-frame-pointer \
 LDBINARYFLAG=  --oformat binary
 FIRST32SIZE=   6144
 
+# for first32dos
+F32DRELOC=0x93000
+
 # for FreeDOS
 FDKSEG=        0x60
 
@@ -60,7 +63,7 @@ all:  $(PROG) $(FIRSTS) $(RMRD) $(DOCS)
 
 # Tagged image builder
 mknbi: mknbi.pl Nbi.pm TruncFD.pm
-       sed -e 's:@@VERSION@@:$(VERSION):' -e 's:@@LIBDIR@@:$(LIBDIR):' -e 's/@@FDKSEG@@/$(FDKSEG)/' mknbi.pl > $@
+       perl -ne 's|\@\@VERSION\@\@|$(VERSION)|; s|\@\@LIBDIR\@\@|$(LIBDIR)|; s|\@\@FDKSEG\@\@|$(FDKSEG)|; print $$_;' mknbi.pl > $@
        chmod 755 $@
 
 # Tagged image display and disassemble
@@ -93,6 +96,10 @@ first32elf@%.linux:  start32@%.o first32elf.o memsizes.o printf.o
        $(LD) -N -Ttext $* -e _start $(LDBINARYFLAG) -o $@ start32@$*.o first32elf.o memsizes.o printf.o
        @if [ `wc -c < $@` -gt $(FIRST32SIZE) ]; then echo Binary too large; fi
 
+# 32-bit first stage ELF DOS setup program
+first32elf@%.dos:      start32@%.o first32dos.o printf.o
+       $(LD) -N -Ttext $* -e _start $(LDBINARYFLAG) -o $@ start32@$*.o first32dos.o printf.o
+
 start32@%.o:   start32.S
        gcc -E -DRELOC=$* $(OLDGAS) start32.S | $(AS) -o start32@$*.o
 
@@ -102,6 +109,9 @@ first32.o:  first32.c etherboot.h start32.h
 first32elf.o:  first32.c etherboot.h start32.h
        gcc $(CFLAGS) -DFIRST32ELF -o first32elf.o -c first32.c
 
+first32dos.o:  first32.c etherboot.h start32.h
+       gcc $(CFLAGS) -DRELOC=$(F32DRELOC) -DFIRST32DOS -DFIRST32ELF -o first32dos.o -c first32.c
+
 memsizes.o:            memsizes.c
        gcc $(CFLAGS) -c $*.c
 
@@ -128,6 +138,12 @@ else
        nasm -f bin first-fdos.s -o first.fdos
 endif
 
+first-elf.dos: first.dos first32elf@$(F32DRELOC).dos
+       cat first.dos first32elf@$(F32DRELOC).dos > first-elf.dos
+
+first-elf.fdos:        first.fdos first32elf@$(F32DRELOC).dos
+       cat first.fdos first32elf@$(F32DRELOC).dos > first-elf.fdos
+
 # Menu first stage program
 menu:  startmenu.o menu.o bootmenu.o string.o printf.o ansiesc.o md5.o misc.o serial.o
        $(LD) -N -Ttext $(MENURELOC) -e _start $(LDBINARYFLAG) -o $@ startmenu.o menu.o bootmenu.o string.o printf.o ansiesc.o md5.o misc.o serial.o
@@ -216,7 +232,7 @@ install:    all $(ALTBOOT)
        do \
                ln -sf ../lib/mknbi/mknbi mknbi-$$i; \
        done; \
-       for i in linux menu nfl lua; \
+       for i in linux img menu nfl lua; \
        do \
                ln -sf ../lib/mknbi/mknbi mkelf-$$i; \
        done
@@ -227,7 +243,7 @@ install:    all $(ALTBOOT)
        -mkdir -p $(MANDIR)
        $(INSTALL) -m 644 mknbi.1 disnbi.1 $(MANDIR)/
        cd $(MANDIR); \
-       for i in mknbi-linux mkelf-linux mknbi-rom mknbi-menu mkelf-menu mknbi-nfl mkelf-nfl mknbi-dos mknbi-fdos; \
+       for i in mkelf mknbi-linux mkelf-linux mknbi-rom mkelf-img mknbi-menu mkelf-menu mknbi-nfl mkelf-nfl mkelf-lua mknbi-dos mknbi-fdos; \
        do \
                ln -sf mknbi.1 $$i.1; \
        done
@@ -240,7 +256,7 @@ tarball:
        (cd ..; tar zcf /tmp/mknbi-$(TARVERSION).tar.gz --exclude CVS --exclude lua-4.0.1 mknbi-$(TARVERSION))
 
 clean:
-       $(RM) -f $(PROG) start32*.o first32*.o first32elf*.o \
+       $(RM) -f $(PROG) start32*.o first32*.o \
        printf.o menu.o menu-simple.o nfl.o startmenu.o \
        bootmenu.o md5.o misc.o serial.o ansiesc.o string.o memsizes.o \
        first-dos.s first-fdos.s rmrd.s rmrd.map *.l pod2htm*
diff --git a/README b/README
index 9b42197..9b597c2 100644 (file)
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-mknbi.pl 1.4.1
+mknbi.pl 1.4.3
 
 mknbi is a utility for building a tagged image for a kernel for various
 operating systems. It can also build a tagged images for an Etherboot ROM
index 1a5a2a3..76acbca 100644 (file)
@@ -66,7 +66,7 @@
 #ifdef USE_NASM
        text
 #endif
-
+_start:
        mov     dx,ds
        mov     ax,cs                   ; set DS
        mov     ds,ax
@@ -2052,3 +2052,5 @@ dpb_end:
 btplen:                dw      0               ; length of bootp block
 btpnew:                                        ; bootp block has to be at the very end
 
+_end:
+               SPACE(4096-(_end-_start))
index 2d8533f..cf6f008 100644 (file)
--- a/first32.c
+++ b/first32.c
@@ -5,6 +5,11 @@
 #include       "start32.h"
 #include       "elf_boot.h"
 
+#ifndef        FIRST32DOS
+#define        FIRST32LINUX    1
+#endif
+
+#ifdef FIRST32LINUX
 #define SERIAL_CONSOLE 0
 /*
  * This program is free software; you can redistribute it and/or
@@ -631,6 +636,90 @@ int first(struct ebinfo *eb, union infoblock *header, struct bootp_t *bootp)
        for (i = 0; i < 0x7ffffff; i++)
                ;
 #endif
-       xstart(seg[S_SETUP]->p_paddr);
+       xstart((unsigned long)setup);
+       return (0);
+}
+#endif /* FIRST32LINUX */
+
+#ifdef FIRST32DOS
+extern void printf(const char *, ...);
+extern void xstart(unsigned long, union infoblock *, struct bootp_t *);
+extern void exit(int);
+
+struct bootp_t bpcopy;
+
+void putchar(int c)
+{
+       if (c == '\n')
+               putchar('\r');
+       console_putc(c);
+}
+
+static inline void quit(void)
+{
+       printf("Bad argument\n");
+       exit(0);
+}
+
+static void parse_elf_boot_notes(
+       void *notes, union infoblock **rheader, struct bootp_t **rbootp)
+{
+       unsigned char *note, *end;
+       Elf_Bhdr *bhdr;
+       Elf_Nhdr *hdr;
+
+       bhdr = notes;
+       if (bhdr->b_signature != ELF_BHDR_MAGIC) {
+               return;
+       }
+
+       note = ((char *)bhdr) + sizeof(*bhdr);
+       end  = ((char *)bhdr) + bhdr->b_size;
+       while (note < end) {
+               unsigned char *n_name, *n_desc, *next;
+               hdr = (Elf_Nhdr *)note;
+               n_name = note + sizeof(*hdr);
+               n_desc = n_name + ((hdr->n_namesz + 3) & ~3);
+               next = n_desc + ((hdr->n_descsz + 3) & ~3);
+               if (next > end) 
+                       break;
+#if 0
+               printf("n_type: %x n_name(%d): n_desc(%d): \n", 
+                       hdr->n_type, hdr->n_namesz, hdr->n_descsz);
+#endif
+
+               if ((hdr->n_namesz == 10) &&
+                       (memcmp(n_name, "Etherboot", 10) == 0)) {
+                       switch(hdr->n_type) {
+                       case EB_BOOTP_DATA:
+                               *rbootp = *((void **)n_desc);
+                               break;
+                       case EB_HEADER:
+                               *rheader = *((void **)n_desc);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               note = next;
+       }
+}
+
+int first(struct ebinfo *eb, union infoblock *header, struct bootp_t *bootp)
+{
+#if DEBUG > 1
+       printf("&eb = %#X\n", &eb);
+#endif
+       printf(MKNBI_VERSION "/" __FILE__ " (ELF)" " (GPL)\n");
+#if DEBUG > 1
+       printf("eb = %#X, header = %#X, bootp = %#X\n", eb, header, bootp);
+#endif
+       /* Sanity checks */
+       parse_elf_boot_notes(eb, &header, &bootp);
+       if (header->img.magic != ELF_MAGIC || bootp->bp_op != BOOTP_REPLY)
+               quit();
+       memcpy(&bpcopy, bootp, sizeof(bpcopy));
+       xstart(RELOC - 0x1000, header, &bpcopy);
        return (0);
 }
+#endif /* FIRST32DOS */
index 4429e17..daf1370 100644 (file)
--- a/mknbi.pl
+++ b/mknbi.pl
@@ -12,7 +12,7 @@ BEGIN {
 
 use strict;
 use Getopt::Long;
-use Fcntl qw(SEEK_SET);
+use IO::Seekable;
 use Socket;
 
 use TruncFD;
@@ -51,20 +51,38 @@ sub check_file
 
 sub mknbi_rom ($)
 {
-       my ($format) = @_;
+       my ($module) = @_;
        my ($romdesc);
 
        $#ARGV >= 0 or die "Usage: $0 romimage\n";
        return unless check_file($ARGV[0]);
-       $format->add_header("mknbi-rom-$version", $relocseg + 0x3E0, 0x6000, 6);
+       $module->add_header("mknbi-rom-$version", $relocseg + 0x3E0, 0x6000, 6);
        $romdesc = { file => $ARGV[0],
                segment => 0x6000,
                maxlen => 0x10000,
                id => 16,
                end => 1 };
-       $format->add_segment($romdesc);
-       $format->dump_segments();
-       $format->copy_file($romdesc);
+       $module->add_segment($romdesc);
+       $module->dump_segments();
+       $module->copy_file($romdesc);
+}
+
+sub mkelf_img ($)
+{
+       my ($module) = @_;
+       my ($romdesc);
+
+       $#ARGV >= 0 or die "Usage: $0 .img-file\n";
+       return unless check_file($ARGV[0]);
+       $module->add_pm_header("mkelf-img-$version", $relocseg + 0x3E0, 0x60000, 0);
+       $romdesc = { file => $ARGV[0],
+               segment => 0x6000,
+               maxlen => 0x10000,
+               id => 16,
+               end => 1 };
+       $module->add_segment($romdesc);
+       $module->dump_segments();
+       $module->copy_file($romdesc);
 }
 
 sub inet_aton_warn
@@ -138,7 +156,7 @@ use constant PARAM_MAX_LENGTH => 1024;
 
 sub mknbi_linux ($)
 {
-       my ($format) = @_;
+       my ($module) = @_;
        my ($startaddr, $setupfile, $setupfile32, $libfile, $kernelfile, $setupdesc);
        my ($paramseg, $paramstring, $bootseg, $block);
        my ($setupseg, $kernelseg, $kernellen, $ramdiskseg, $rdloc);
@@ -146,7 +164,7 @@ sub mknbi_linux ($)
                $ramsize, $vidmode, $rootdev, $sig, $ver, $bigker);
 
        $startaddr = sprintf("%#x", ($relocseg + START_OFFSET) * 0x10);
-       $libfile = ($main::format eq 'elf') ? "first32elf\@${startaddr}.linux" : "first32\@${startaddr}.linux";
+       $libfile = ($format eq 'elf') ? "first32elf\@${startaddr}.linux" : "first32\@${startaddr}.linux";
        # if empty, use default
        $setupfile = $first32 eq '' ? "$libdir/$libfile" : $first32;
        $#ARGV >= 0 or die "Usage: $0 kernelimage [ramdisk]\n";
@@ -155,7 +173,7 @@ sub mknbi_linux ($)
        if (defined($ramdisk = $ARGV[1])) {
                return unless check_file($ramdisk);
        }
-       $format->add_pm_header("mknbi-linux-$version", $relocseg + HEADER_SEG_OFFSET, hex($startaddr), $progreturns);
+       $module->add_pm_header("mknbi-linux-$version", $relocseg + HEADER_SEG_OFFSET, hex($startaddr), $progreturns);
        $setupdesc = { file => $setupfile,
                segment => hex($startaddr) / 0x10,
                maxlen => START_MAX_LENGTH,
@@ -170,7 +188,7 @@ sub mknbi_linux ($)
                len => 512,
                maxlen => 512,
                id => 18 };
-       $format->peek_file($bootseg, \$block, 512) == 512
+       $module->peek_file($bootseg, \$block, 512) == 512
                or die "Error reading boot sector of $kernelfile\n";
        (undef, $setupsects, $flags, $syssize, $swapdev, $ramsize, $vidmode,
                $rootdev, $sig) = unpack('a497Cv7', $block);
@@ -186,7 +204,7 @@ sub mknbi_linux ($)
                len => $setupsects * 512,
                maxlen => 8192,
                id => 19 };
-       $format->peek_file($setupseg, \$block, 512) == 512
+       $module->peek_file($setupseg, \$block, 512) == 512
                or die "Error reading first setup sector of $kernelfile\n";
        (undef, $sig, $ver, undef, undef, undef, undef, undef, $flags) =
                unpack('va4v5C2', $block);
@@ -209,25 +227,25 @@ sub mknbi_linux ($)
                id => 21,
                end => 1 };
        $$kernelseg{'end'} = 0 if (defined($ramdisk));
-       $format->add_segment($setupdesc);
-       $format->add_segment($paramseg);
-       $format->add_segment($bootseg);
-       $format->add_segment($setupseg);
-       $kernellen = $format->add_segment($kernelseg);
+       $module->add_segment($setupdesc);
+       $module->add_segment($paramseg);
+       $module->add_segment($bootseg);
+       $module->add_segment($setupseg);
+       $kernellen = $module->add_segment($kernelseg);
        if (!$bigker and $kernellen > (($relocseg - 0x1000) * 16)) {
                print STDERR "Warning, zImage kernel may collide with Etherboot\n";
        }
        # Put ramdisk following kernel at next 4096 byte boundary
        $$ramdiskseg{'segment'} += (($kernellen + 0xFFF) & ~0xFFF) >> 4 if ($bigker);
        # should be 0, 1 or 2 depending on rdbase
-       $format->add_segment($ramdiskseg, "\x00") if (defined($ramdisk));
-       $format->dump_segments();
-       $format->copy_file($setupdesc);
-       $format->copy_string($paramseg);
-       $format->copy_file($bootseg);
-       $format->copy_file($setupseg);
-       $format->copy_file($kernelseg);
-       $format->copy_file($ramdiskseg) if (defined($ramdisk));
+       $module->add_segment($ramdiskseg, "\x00") if (defined($ramdisk));
+       $module->dump_segments();
+       $module->copy_file($setupdesc);
+       $module->copy_string($paramseg);
+       $module->copy_file($bootseg);
+       $module->copy_file($setupseg);
+       $module->copy_file($kernelseg);
+       $module->copy_file($ramdiskseg) if (defined($ramdisk));
 }
 
 sub get_geom ($$)
@@ -312,18 +330,19 @@ sub make_mbr ($$)
 
 sub mknbi_fdos ($)
 {
-       my ($format) = @_;
+       my ($module) = @_;
        my ($setupfile, $bootblock);
        my ($usedsize, $declsize, $firsttracksize, $geom_string, $fstype);
        my ($setupdesc, $kerneldesc, $firsttrackdesc, $bootdesc, $floppydesc);
+       my $elfformat = ($format eq 'elf');
 
-       $setupfile = "$libdir/first.fdos";
+       $setupfile = "$libdir/" . ($elfformat ? "first-elf.fdos" : "first.fdos");
        $#ARGV >= 1 or die "Usage: $0 kernel.sys floppyimage\n";
        return unless check_file($setupfile, $ARGV[0], $ARGV[1]);
-       $format->add_header("mknbi-fdos-$version", $relocseg + 0x200, $relocseg + 0x300, 0);
+       $module->add_header("mknbi-fdos-$version", $relocseg, $relocseg + ($elfformat ? 0x300 : 0x200), 0);
        $setupdesc = { file => $setupfile,
-               segment => $relocseg + 0x300,
-               maxlen => 4096,
+               segment => $relocseg + 0x200,
+               maxlen => 8192,
                id => 16 };
        $kerneldesc = { file => $ARGV[0],
                segment => @@FDKSEG@@,
@@ -334,9 +353,9 @@ sub mknbi_fdos ($)
                segment => (defined($rdbase) ? (hex($rdbase) >> 4) : 0x11000),
                id => 18,
                end => 1 };
-       $format->add_segment($setupdesc);
-       $format->add_segment($kerneldesc);
-       $format->peek_file($floppydesc, \$bootblock, 512) == 512
+       $module->add_segment($setupdesc);
+       $module->add_segment($kerneldesc);
+       $module->peek_file($floppydesc, \$bootblock, 512) == 512
                or die "Error reading boot sector of $ARGV[1]\n";
        ($usedsize, $declsize, $firsttracksize, $geom_string, $fstype)
                = &get_geom($ARGV[1], \$bootblock);
@@ -346,36 +365,37 @@ sub mknbi_fdos ($)
        $$floppydesc{'len'} += $firsttracksize if $simhd;
        $$floppydesc{'maxlen'} = $declsize;
        $geom_string = &mod_geom_string($geom_string) if $simhd;
-       $format->add_segment($floppydesc, $geom_string);
-       $format->dump_segments();
-       $format->copy_file($setupdesc);
-       $format->copy_file($kerneldesc);
+       $module->add_segment($floppydesc, $geom_string);
+       $module->dump_segments();
+       $module->copy_file($setupdesc);
+       $module->copy_file($kerneldesc);
        if ($simhd) {
                $$firsttrackdesc{'string'} = &make_mbr($geom_string, $fstype);
-               $format->copy_string($firsttrackdesc);
+               $module->copy_string($firsttrackdesc);
        }
        # write out modified bootblock, not the one in the file
        $bootdesc = { string => $bootblock };
-       $format->copy_string($bootdesc);
+       $module->copy_string($bootdesc);
        # Restore correct value of len and account for bootblock skipped
        $$floppydesc{'len'} = $usedsize - 512;
-       $format->copy_file($floppydesc);
+       $module->copy_file($floppydesc);
 }
 
 sub mknbi_dos ($)
 {
-       my ($format) = @_;
+       my ($module) = @_;
        my ($setupfile, $bootblock);
        my ($usedsize, $declsize, $firsttracksize, $geom_string, $fstype);
        my ($setupdesc, $firsttrackdesc, $bootdesc, $floppydesc);
+       my $elfformat = ($format eq 'elf');
 
-       $setupfile = "$libdir/first.dos";
+       $setupfile = "$libdir/" . ($elfformat ? "first-elf.dos" : "first.dos");
        $#ARGV >= 0 or die "Usage: $0 floppyimage\n";
        return unless check_file($setupfile, $ARGV[0]);
-       $format->add_header("mknbi-dos-$version", 0x1000, 0x1040, 0);
+       $module->add_header("mknbi-dos-$version", $relocseg, $relocseg + ($elfformat ? 0x300 : 0x200), 0);
        $setupdesc = { file => $setupfile,
-               segment => 0x1040,
-               maxlen => 64512,
+               segment => $relocseg + 0x200,
+               maxlen => 8192,
                id => 16 };
        die "Ramdisk base should be of the form 0xNNNNNNNN (linear hex address)\n"
                if (defined($rdbase) and $rdbase !~ /^0x[\da-fA-F]{1,8}$/);
@@ -383,8 +403,8 @@ sub mknbi_dos ($)
                segment => (defined($rdbase) ? (hex($rdbase) >> 4) : 0x11000),
                id => 17,
                end => 1 };
-       $format->add_segment($setupdesc);
-       $format->peek_file($floppydesc, \$bootblock, 512) == 512
+       $module->add_segment($setupdesc);
+       $module->peek_file($floppydesc, \$bootblock, 512) == 512
                or die "Error reading boot sector of $ARGV[0]\n";
        ($usedsize, $declsize, $firsttracksize, $geom_string, $fstype)
                = &get_geom($ARGV[0], \$bootblock);
@@ -394,19 +414,19 @@ sub mknbi_dos ($)
        $$floppydesc{'len'} += $firsttracksize if $simhd;
        $$floppydesc{'maxlen'} = $declsize;
        $geom_string = &mod_geom_string($geom_string) if $simhd;
-       $format->add_segment($floppydesc, $geom_string);
-       $format->dump_segments();
-       $format->copy_file($setupdesc);
+       $module->add_segment($floppydesc, $geom_string);
+       $module->dump_segments();
+       $module->copy_file($setupdesc);
        if ($simhd) {
                $$firsttrackdesc{'string'} = &make_mbr($geom_string, $fstype);
-               $format->copy_string($firsttrackdesc);
+               $module->copy_string($firsttrackdesc);
        }
        # write out modified bootblock, not the one in the file
        $bootdesc = { string => $bootblock };
-       $format->copy_string($bootdesc);
+       $module->copy_string($bootdesc);
        # Restore correct value of len and account for bootblock skipped
        $$floppydesc{'len'} = $usedsize - 512;
-       $format->copy_file($floppydesc);
+       $module->copy_file($floppydesc);
 }
 
 sub mknbi_menu ($)
@@ -595,6 +615,8 @@ if ($relocsegstr eq '0x9000' or $relocsegstr eq '0x8000') {
 }
 if ($target eq 'rom') {
        &mknbi_rom($module);
+} elsif ($target eq 'img') {
+       &mkelf_img($module);
 } elsif ($target eq 'linux') {
        &mknbi_linux($module);
 } elsif ($target eq 'fdos') {
@@ -637,7 +659,9 @@ B<mkelf-linux> [--output=I<outputfile>] I<kernelimage> [I<ramdisk>]
 
 B<mknbi-linux> [--output=I<outputfile>] I<kernelimage> [I<ramdisk>]
 
-B<mknbi-rom> [--output=I<outputfile>] I<ROM-image>
+B<mknbi-rom> [--output=I<outputfile>] I<.z?rom-file>
+
+B<mkelf-img> [--output=I<outputfile>] I<.z?img-file>
 
 B<mkelf-menu> [--output=I<outputfile>] [I<dataimage>]
 
@@ -807,7 +831,7 @@ suffixes are uppercase. This kernel parameter can be specified in
 
 Run the program thus:
 
-C<mkelf-linux> I<kernel-image> [I<ramdisk-image>] > C<linux.nb>
+mkelf-linux I<kernel-image> [I<ramdisk-image>] > linux.nb
 
 Then move F<linux.nb> to where the network booting process expects to
 find it.
@@ -815,20 +839,28 @@ find it.
 =head1 MKELF-LINUX BOOTP/DHCP VENDOR TAGS
 
 B<mkelf-linux> includes a startup code at the beginning of the Linux
-kernel which is able to detect certain BOOTP vendor defined tags. These
-can be used to modify the kernel loading process at runtime. To use
-these tags with bootpd, a publicly available BOOTP server daemon, you
-can use the following syntax in the F</etc/bootptab> file:
+kernel which is able to detect certain DHCP vendor defined options.
+These can be used to modify the kernel loading process at runtime. To
+use these options with ISC DHCPD v3, a popular DHCP daemon, the syntax
+is as below. You will need to adjust the syntax for other DHCP or BOOTP
+daemons.
 
-C<T>I<number>C<=">I<string>C<">
+option etherboot-signature code 128 = string;
 
-For example, to specify a different root NFS device, you can use:
+option kernel-parameters code 129 = text;
 
-C<T130="eth1">
+...
 
-The following tags are presently supported by B<mkelf-linux>:
+               option etherboot-signature E4:45:74:68:00:00;
 
-B<129> The I<string> value given with this tag is appended verbatim to
+               option kernel-parameters "INITRD_DBG=6 NIC=3c509";
+
+Option 128 is required to be the six byte signature above. See the
+vendortags appendix of the Etherboot user manual for details.
+
+The following option is presently supported by B<mkelf-linux>:
+
+B<129> The I<string> value given with this option is appended verbatim to
 the end of the kernel command line.  It can be used to specify arguments
 like I/O addresses or DMA channels required for special hardware
 like SCSI adapters, network cards etc. Please consult the Linux kernel
@@ -836,20 +868,13 @@ documentation about the syntax required by those options. It is the same
 as the B<--append> command line option to B<mkelf-linux>, but works at
 boot time instead of image build time.
 
-B<130> With this tag it is possible to the select the network adapter
+B<130> With this option it is possible to the select the network adapter
 used for mounting root via NFS on a multihomed diskless client. The
 syntax for the I<string> value is the same as for the C<dev> entry used
 with the B<--ip=> option as described above. However note that the
 B<mkelf-linux> runtime setup routine does not check the syntax of the
 string.
 
-The same tags will work in DHCP with the appropriate syntax for your
-DHCP server configuration file.
-
-Remember that you need to specify tag 128 in the correct format in order
-for the previous tags to be valid. See the documentation file
-vendortags.
-
 =head1 MKNBI-ROM
 
 B<mknbi-rom> makes a boot image from an Etherboot C<.rom> or C<.zrom>
@@ -857,14 +882,32 @@ boot ROM image.  This allows it to be netbooted using an existing
 ROM. This is useful for developing Etherboot drivers or to load a newer
 version of Etherboot with an older one.
 
-Run mknbi like this:
+Run mknbi-rom like this:
 
-C<mknbi-rom nic.zrom> > C<nic.nb>
+mknbi-rom nic.zrom > nic.nb
 
 Move F<nic.nb> to where the network booting process expects to find it.
 The boot ROM will load this as the I<operating system> and execute the
 ROM image.
 
+=head1 MKELF-IMG
+
+B<mkelf-img> makes a boot image from an Etherboot C<.img> or C<.zimg>
+image.  This allows it to be netbooted using an existing ROM. This is
+useful for developing Etherboot drivers or to load a newer version of
+Etherboot with an older one.
+
+Run mkelf-img like this:
+
+mkelf-img nic.zimg > nic.nb
+
+Move F<nic.nb> to where the network booting process expects to find it.
+The boot ROM will load this as the I<operating system> and execute the
+image.
+
+Note that this does not test the ROM loader portion that's in a C<.z?rom>
+image, but not in a C<.z?img>.
+
 =head1 MKELF-MENU
 
 B<mkelf-menu> and B<mknbi-menu> make a boot image from an auxiliary menu
@@ -885,14 +928,14 @@ of Etherboot with the exception of a couple of small differences: no
 server or gateway specifications are used and nested TFTP loads don't
 work. You should not have MOTD or IMAGE_MENU defined in your Etherboot
 build to be able to use this external menu binary. The specifications of
-the DHCP tags required is in the vendortags document in the Etherboot
-documentation.
+the DHCP option required is in the vendortags document in the Etherboot
+user manual.
 
 Typical usage is like this:
 
-C<mkelf-menu> > C<menu.nb>
+mkelf-menu > menu.nb
 
-Then put menu.nb in the TFTP boot directory and edit your DHCP tags
+Then put menu.nb in the TFTP boot directory and edit your DHCP options
 according to the documentation.
 
 Alternate user interface programs are highly encouraged.
@@ -904,11 +947,14 @@ program. This menu program takes the names of images from a
 menu-text-file file which just contains lines with the filenames
 (relative to the tftpd root directory) of images to load. The
 user-interface is a light-bar, similar to that used in GRUB.  There is a
-sample menu-text-file in C<menu-nfl.eg>.
+sample menu-text-file in C<menu-nfl.eg>. The special entry "Quit
+Etherboot" (without quotes, of course) can be used in menu-text-files
+as an entry that causes Etherboot to quit and return to the invoking
+environment, which is the BIOS in the case of ROMs.
 
 Typical usage is:
 
-C<mkelf-nfl> C<menu-text-file> > C<nfl.nb>
+mkelf-nfl I<menu-text-file> > nfl.nb
 
 Then put nfl.nb in the TFTP boot directory and specify as the boot
 image. Chaining to other menus works.
@@ -923,11 +969,11 @@ B<mkelf-lua> makes an ELF image from a precompiled Lua
 
 Typical usage is:
 
-C<mkelf-lua> C<hello.lb> > C<luaprog.nb>
+mkelf-lua hello.lb > luaprog.nb
 
 where C<hello.lb> was generated from a Lua program by:
 
-C<luac -o hello.lb hello.lua>
+luac -o hello.lb hello.lua
 
 The functions available to Lua programs in this environment is described
 in a separate document.
@@ -950,21 +996,21 @@ C<http://freedos.sourceforge.net/>
 Follow the instructions to make a bootable floppy. Then get an image
 of the floppy with:
 
-C<dd if=/dev/fd0 of=/tmp/floppyimage>
+dd if=/dev/fd0 of=/tmp/floppyimage
 
 Also extract F<kernel.sys> from the floppy. You can do this from the
 image using the mtools package, by specifying a file as a I<drive>
 with a declaration like this in F<~/.mtoolsrc>:
 
-C<drive x: file="/tmp/floppyimage">
+drive x: file="/tmp/floppyimage"
 
 Then run:
 
-C<mcopy x:kernel.sys .>
+mcopy x:kernel.sys .
 
 Then run mknbi by:
 
-C<mknbi-fdos kernel.sys /tmp/floppyimage> > C<freedos.nb>
+mknbi-fdos kernel.sys /tmp/floppyimage > freedos.nb
 
 where F<kernel.sys> and F</tmp/floppyimage> are the files extracted above.
 Then move F<freedos.nb> to where the network booting process expects to
@@ -1011,22 +1057,22 @@ bootable floppy of any size to start with. First extract the boot block
 from the floppy, this boot block must match the DOS kernel files you
 will copy in the next step:
 
-C<dd if=/dev/fd0 of=bootblock bs=512 count=1>
+dd if=/dev/fd0 of=bootblock bs=512 count=1
 
 Then get the DOS kernel files (this is correct for DR-DOS, the names
 are different in MS-DOS, IO.SYS and MSDOS.SYS):
 
-C<mcopy a:IBMBIO.COM a:IBMDOS.COM a:COMMAND.COM .>
+mcopy a:IBMBIO.COM a:IBMDOS.COM a:COMMAND.COM .
 
 Next make an entry in F<~/.mtoolsrc> to declare a floppy to be mapped
 to a file:
 
-C<drive x: file="/tmp/floppyimage">
+drive x: file="/tmp/floppyimage"
 
 Now format a floppy of the desired size, in this example a 2.88 MB floppy,
 at the same time writing the bootblock onto it:
 
-C<mformat -C -t 80 -s 36 -h 2 -B bootblock x:>
+mformat -C -t 80 -s 36 -h 2 -B bootblock x:
 
 The size of the "floppy" is only limited by the limits on the number of
 cylinders, sectors and heads, which are 1023, 63 and 255 respectively,
@@ -1036,13 +1082,13 @@ needed to hold your "floppy" files.
 
 Finally, copy all your desired files onto the floppy:
 
-C<mcopy IBMBIO.COM x:>
+mcopy IBMBIO.COM x:
 
-C<mcopy IBMDOS.COM x:>
+mcopy IBMDOS.COM x:
 
-C<mcopy COMMAND.COM x:>
+mcopy COMMAND.COM x:
 
-C<mcopy CONFIG.SYS AUTOEXEC.BAT APP.EXE APP.DAT ... x:>
+mcopy CONFIG.SYS AUTOEXEC.BAT APP.EXE APP.DAT ... x:
 
 For MS-DOS substitute IO.SYS for IBMIO.COM, and MSDOS.SYS for
 IBMDOS.COM.  The case of the files must be preserved, it may not work if
@@ -1062,12 +1108,12 @@ disk, or this bootblock will not work.
 If you happen to have a media of the same size you could test if the
 image is bootable by copying it onto the media, and then booting it:
 
-C<dd if=/tmp/floppyimage of=/dev/fd0>
+dd if=/tmp/floppyimage of=/dev/fd0
 
 Then run mknbi-dos over the image F</tmp/floppyimage> to create a
 boot image:
 
-C<mknbi-dos /tmp/floppyimage> > C<dos.nb>
+mknbi-dos /tmp/floppyimage > dos.nb
 
 Move F<dos.nb> to where the network booting process expects to find it.
 
@@ -1099,7 +1145,8 @@ not a segment address, the last 4 bits are not used and should be 0.
 
 =head1 BUGS
 
-Please report all bugs to the author.
+Please report all bugs to Etherboot users mailing list:
+<https://sourceforge.net/mail/?group_id=4233>
 
 =head1 SEE ALSO
 
@@ -1114,7 +1161,7 @@ B<mknbi> is under the GNU Public License
 
 =head1 AUTHOR
 
-Ken Yap (C<ken_yap@users.sourceforge.net>)
+Ken Yap
 
 mk{elf,nbi}-nfl was contributed by Robb Main of Genedyne.
 
diff --git a/nfl.c b/nfl.c
index 304323b..00394c6 100644 (file)
--- a/nfl.c
+++ b/nfl.c
@@ -728,6 +728,8 @@ int menu(struct ebinfo *eb, union infoblock *header, struct bootp_t *bootp)
 #else
        console_cls();
 #endif
+       if (memcmp(menu_entries[i], "Quit Etherboot", sizeof("Quit Etherboot")) == 0)
+               return (255);
        set_file_to_load ( bootp,  menu_entries[ i ] );
        return ( 1 );
 }