Various patches, see request ID 1393646 in the Etherboot patch list. Amongst others...
authorespenlaub <espenlaub>
Mon, 13 Feb 2006 16:40:36 +0000 (16:40 +0000)
committerespenlaub <espenlaub>
Mon, 13 Feb 2006 16:40:36 +0000 (16:40 +0000)
17 files changed:
src/arch/i386/core/elf.c
src/arch/i386/core/multiboot_loader.c
src/arch/i386/core/realmode_asm.S
src/arch/i386/core/start32.S
src/arch/i386/core/tagged_loader.c
src/arch/i386/firmware/pcbios/basemem.c
src/arch/i386/prefix/floppyprefix.S
src/arch/ia64/core/efi.c
src/core/elf_loader.c
src/core/main.c
src/core/nfs.c
src/core/nic.c
src/core/osloader.c
src/core/pxe_export.c
src/core/vsprintf.c
src/drivers/net/pcnet32.c
src/include/etherboot.h

index 6ef78c7..bcaeb55 100644 (file)
@@ -73,7 +73,7 @@ struct Elf_Bhdr *prepare_boot_params(void *header)
        notes.nf1.n_descsz = sizeof(notes.nf1_bootp_data);
        notes.nf1.n_type   = EB_BOOTP_DATA;
        CP(notes.nf1_name,   EB_PARAM_NOTE);
-       notes.nf1_bootp_data = virt_to_phys(BOOTP_DATA_ADDR);
+       notes.nf1_bootp_data = virt_to_phys(&bootp_data);
 
        notes.nf2.n_namesz = sizeof(EB_PARAM_NOTE);
        notes.nf2.n_descsz = sizeof(notes.nf2_header);
index e9785f1..5622524 100644 (file)
@@ -56,28 +56,82 @@ struct multiboot_header {
 };
 
 static struct multiboot_header *mbheader;
+static unsigned int mbimgoffset, mboffset;
+static unsigned char mbbuffer[12];
 
 static struct multiboot_info mbinfo;
 
-static void multiboot_probe(unsigned char *data, int len)
+static void multiboot_init(void)
+{
+       mbheader = NULL;
+       mbimgoffset = 0;
+       mboffset = 0;
+}
+
+/* Remember this probing function is actually different from the usual probing
+ * functions, since the Multiboot header is somewhere in the first 8KB of the
+ * image and it is byte aligned, but there is not much more known about how to
+ * find it.  In the Etherboot context the most complicated issue is that the
+ * image has to be processed block-by-block, with unknown block size and no
+ * guarantees about block alignment with respect to the image.  */
+static void multiboot_peek(unsigned char *data, int len)
 {
-    int offset;
     struct multiboot_header *h;
 
-    /* Multiboot spec requires the header to be in first 8KB of the image */
-    if (len > 8192)
-           len = 8192;
+       /* If we have already searched the first 8KB of the image or if we have
+        * already found a valid Multiboot header, skip this code.  */
+    if ((mboffset == 12) || (mbimgoffset >= 8192))
+               return;
+
+       if (mbimgoffset + len >= 8192)
+           len = 8192 - mbimgoffset;
 
-    for (offset = 0; offset < len; offset += 4) {
-           h = (struct multiboot_header *) (data + offset);
-           if (h->magic == MULTIBOOT_HEADER_MAGIC
-                           && h->magic + h->flags + h->checksum == 0) {
-                   printf("/Multiboot");
-                   mbheader = h;
-                   return;
-           }
-    }
-    mbheader = 0;
+       /* This piece of code is pretty stupid, since it always copies data, even
+        * if it is word aligned.  This shouldn't matter too much on platforms that
+        * use the Multiboot spec, since the processors are usually reasonably fast
+        * and this code is only executed for the first 8KB of the image.  Feel
+        * free to improve it, but be prepared to write quite a lot of code that
+        * deals with non-aligned data with respect to the image to load.  */
+       while (len > 0) {
+               mbimgoffset++;
+               memcpy(mbbuffer + mboffset, data, 1);
+               mboffset++;
+               data++;
+               len--;
+               if (mboffset == 4) {
+                       /* Accumulated a word into the buffer.  */
+                       h = (struct multiboot_header *)mbbuffer;
+                       if (h->magic != MULTIBOOT_HEADER_MAGIC) {
+                               /* Wrong magic, this cannot be the start of the header.  */
+                               mboffset = 0;
+                       }
+               } else if (mboffset == 12) {
+                       /* Accumulated the minimum header data into the buffer.  */
+                       h = (struct multiboot_header *)mbbuffer;
+                       if (h->magic + h->flags + h->checksum != 0) {
+                               /* Checksum error, not a valid header.  Check for a possible
+                                * header starting in the current flag/checksum field.  */
+                               if (h->flags == MULTIBOOT_HEADER_MAGIC) {
+                                       mboffset -= 4;
+                                       memmove(mbbuffer, mbbuffer + 4, mboffset);
+                               } else if (h->checksum == MULTIBOOT_HEADER_MAGIC) {
+                                       mboffset -= 8;
+                                       memmove(mbbuffer, mbbuffer + 8, mboffset);
+                               } else {
+                                       mboffset = 0;
+                               }
+                       } else {
+                           printf("Multiboot... ");
+                           mbheader = h;
+                               if ((h->flags & 0xfffc) != 0) {
+                                       printf("\nERROR: Unsupported Multiboot requirements flags\n");
+                                       longjmp(restart_etherboot, -2);
+                               }
+                               break;
+                       }
+               }
+       }
+       mbimgoffset += len;
 }
 
 static inline void multiboot_boot(unsigned long entry)
@@ -94,7 +148,7 @@ static inline void multiboot_boot(unsigned long entry)
         * strings of the maximum size are possible.  Note this buffer
         * can overrun if a stupid file name is chosen.  Oh well.  */
        c = cmdline;
-       for (i = 0; KERNEL_BUF[i] != 0; i++) {
+       for (i = 0; KERNEL_BUF[i] != '\0'; i++) {
                switch (KERNEL_BUF[i]) {
                case ' ':
                case '\\':
@@ -106,6 +160,11 @@ static inline void multiboot_boot(unsigned long entry)
                }
                *c++ = KERNEL_BUF[i];
        }
+       if (addparam != NULL) {
+               *c++ = ' ';
+               memcpy(c, addparam, addparamlen);
+               c += addparamlen;
+       }
        (void)sprintf(c, " -retaddr %#lX", virt_to_phys(xend32));
 
        mbinfo.flags = MULTIBOOT_MMAP_VALID | MULTIBOOT_MEM_VALID |MULTIBOOT_CMDLINE_VALID;
@@ -139,5 +198,11 @@ static inline void multiboot_boot(unsigned long entry)
        os_regs.eax = 0x2BADB002;
        os_regs.ebx = virt_to_phys(&mbinfo);
        xstart32(entry);
-       longjmp(restart_etherboot, -2);
+       /* A Multiboot kernel by default never returns - there is nothing in the
+        * specification about what happens to the boot loader after the kernel has
+        * been started.  Thus if the kernel returns it is definitely aware of the
+        * semantics involved (i.e. the "-retaddr" parameter).  Do not treat this
+        * as an error, but restart with a fresh DHCP request in order to activate
+        * the menu again in case one is used.  */
+       longjmp(restart_etherboot, 2);
 }
index 28a5bfe..4baa450 100644 (file)
@@ -521,7 +521,7 @@ _real_to_prot:
        movl    %eax, %cr0
 
        /* flush prefetch queue, and reload %cs:%eip */
-       DATA32 ljmp %ds:(r2p_paddr-1b)(%bx)
+       DATA32 ljmp %ds:*(r2p_paddr-1b)(%bx)
        .code32
 2:
        
index 6dc3f20..519471d 100644 (file)
@@ -129,12 +129,11 @@ _in_call_far:
        pushl   %eax
        /* IC_OFFSET_*(%esp) are now valid */
 
-       /* Switch to virtual addresses */
-       call    _phys_to_virt
-
-       /* Fixup the va_list pointer */
-       movl    virt_offset, %ebp
-       subl    %ebp, IC_OFFSET_VA_LIST_PTR(%esp)
+       /* Determine the offset between physical and virtual address */
+       call    1f
+1:     popl    %ebp
+       subl    $1b, %ebp
+       movl    %ebp, virt_offset(%ebp)
 
        /* Check opcode for EB_USE_INTERNAL_STACK flag */
        movl    IC_OFFSET_OPCODE(%esp), %eax
@@ -142,8 +141,8 @@ _in_call_far:
        je      2f
        /* Use internal stack flag set */
        /* Check %esp is not already in internal stack range */
-       leal    _stack, %esi            /* %esi = bottom of internal stack */
-       leal    _estack, %edi           /* %edi = top of internal stack */
+       leal    _stack(%ebp), %esi      /* %esi = bottom of internal stack */
+       leal    _estack(%ebp), %edi     /* %edi = top of internal stack */
        cmpl    %esi, %esp
        jb      1f
        cmpl    %edi, %esp
@@ -156,6 +155,13 @@ _in_call_far:
        rep movsb                       /* Copy data to internal stack */
 2:
 
+       /* Switch to virtual addresses */
+       call    _phys_to_virt
+
+       /* Fixup the va_list pointer */
+       movl    virt_offset, %ebp
+       subl    %ebp, IC_OFFSET_VA_LIST_PTR(%esp)
+
        /* Call to C code */
        call    i386_in_call
 
@@ -347,8 +353,9 @@ os_regs_ptr:
        movl    %esp, %ebp
        subl    $os_regs, %ebp
        
-       /* Load the stack pointer */
+       /* Load the stack pointer and convert it to physical address */
        movl    52(%esp), %esp
+       addl    %ebp, %esp
 
        /* Enable the virtual addresses */
        leal    _phys_to_virt(%ebp), %eax
@@ -604,7 +611,6 @@ _virt_to_phys:
        popfl
        ret
 
-
 /**************************************************************************
 _PHYS_TO_VIRT - Transition from using physical to virtual addresses
                Preserves all preservable registers and flags
@@ -618,7 +624,6 @@ _phys_to_virt:
        call    1f
 1:     popl    %ebp
        subl    $1b, %ebp
-       movl    %ebp, virt_offset(%ebp)
 
        /* Fixup the gdt */
        leal    _pmcs(%ebp), %eax
@@ -650,7 +655,6 @@ _phys_to_virt:
        popl    %ebp
        popfl
        ret
-       
 
 /**************************************************************************
 SET_SEG_BASE - Set the base address of a segment register
index 9c6d6c2..7ec10f2 100644 (file)
@@ -123,7 +123,7 @@ static sector_t tagged_download(unsigned char *data, unsigned int len, int eof)
                                        result = xstart32(tctx.img.execaddr,
                                                virt_to_phys(&loaderinfo),
                                                tctx.linlocation,
-                                               virt_to_phys(BOOTP_DATA_ADDR));
+                                               virt_to_phys(&bootp_data));
                                        printf("Secondary program returned %d\n",
                                                result);
                                        if (!TAGGED_PROGRAM_RETURNS) {
@@ -138,7 +138,7 @@ static sector_t tagged_download(unsigned char *data, unsigned int len, int eof)
                                        gateA20_unset();
                                        xstart16(tctx.img.execaddr, 
                                                 tctx.img.u.segoff,
-                                                BOOTP_DATA_ADDR);
+                                                &bootp_data);
                                        longjmp(restart_etherboot, -2);
                                }
                        }
index c93b19e..24c9050 100644 (file)
@@ -16,8 +16,9 @@
 #define FREE_BASE_MEMORY ( (uint32_t) ( *fbms << 10 ) )
 
 /* Prototypes */
-void * _allot_base_memory ( size_t size );
-void _forget_base_memory ( void *ptr, size_t size );
+static void * _allot_base_memory ( size_t size );
+static void _forget_base_memory ( void *ptr, size_t size );
+static void free_unused_base_memory ( void );
 
 typedef struct free_base_memory_block {
        uint32_t        magic;
index 18bed4c..e759393 100644 (file)
@@ -1,9 +1,12 @@
 /* NOTE: this boot sector contains instructions that need at least an 80186.
  * Yes, as86 has a bug somewhere in the valid instruction set checks.
  *
- * SYS_SIZE is the number of clicks (16 bytes) to be loaded.
+ * SYS_SIZE is the number of clicks (16 bytes) to be loaded.  For Etherboot
+ * purposes, we need to load everything but the boot sector itself, i.e. 32
+ * clicks less than the size of the entire (verbatim) image.  The image size
+ * is practically limited only by the available base memory size.
  */
-.equ   SYSSIZE, 8192   # 8192 * 16 bytes = 128kB maximum size of .ROM file
+.equ   SYSSIZE, _verbatim_size_pgh - 32
 
 /*     floppyload.S Copyright (C) 1991, 1992 Linus Torvalds
  *     modified by Drew Eckhardt
@@ -37,7 +40,7 @@ go:
        movw    $BOOTSEG, %ax
        movw    %ax,%ds
        movw    %ax,%es
-       movw    %ax,%ss                 /* put stack at BOOTSEG:0x4000-12. */
+       movw    %ax,%ss                 /* put stack at initial position */
        movw    %di,%sp
 
 /* Many BIOS's default disk parameter tables will not recognize multi-sector
index 97e585f..2da7685 100644 (file)
@@ -898,7 +898,7 @@ struct Elf_Bhdr *prepare_boot_params(void *header)
        notes.nf1.n_descsz = sizeof(notes.nf1_bootp_data);
        notes.nf1.n_type   = EB_BOOTP_DATA;
        CP(notes.nf1_name,   EB_PARAM_NOTE);
-       notes.nf1_bootp_data = virt_to_phys(BOOTP_DATA_ADDR);
+       notes.nf1_bootp_data = virt_to_phys(&bootp_data);
 
        notes.nf2.n_namesz = sizeof(EB_PARAM_NOTE);
        notes.nf2.n_descsz = sizeof(notes.nf2_header);
index c1906d8..8cb14cd 100644 (file)
@@ -160,7 +160,6 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
        }
        printf("(ELF");
        elf_freebsd_probe();
-       multiboot_probe(data, len);
        printf(")... ");
        phdr_size = estate.e.elf32.e_phnum * estate.e.elf32.e_phentsize;
        if (estate.e.elf32.e_phoff + phdr_size > len) {
@@ -168,7 +167,7 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
                return dead_download;
        }
        if (phdr_size > sizeof(estate.p.dummy)) {
-               printf("Program header to big\n");
+               printf("Program header too big\n");
                return dead_download;
        }
        memcpy(&estate.p.phdr32, data + estate.e.elf32.e_phoff, phdr_size);
@@ -212,6 +211,7 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
        }
 #if ELF_NOTES
        /* Load ELF notes from the image */
+       estate.check_ip_checksum = 0;
        for(estate.segment = 0; estate.segment < estate.e.elf32.e_phnum; estate.segment++) {
                if (estate.p.phdr32[estate.segment].p_type != PT_NOTE)
                        continue;
@@ -250,6 +250,7 @@ static inline os_download_t elf32_probe(unsigned char *data, unsigned int len)
        estate.loc = 0;
        estate.skip = 0;
        estate.toread = 0;
+       multiboot_init();
        return elf32_download;
 }
 
@@ -477,6 +478,7 @@ static inline os_download_t elf64_probe(unsigned char *data, unsigned int len)
        }
 #if ELF_NOTES
        /* Load ELF notes from the image */
+       estate.check_ip_checksum = 0;
        for(estate.segment = 0; estate.segment < estate.e.elf64.e_phnum; estate.segment++) {
                if (estate.p.phdr64[estate.segment].p_type != PT_NOTE)
                        continue;
index 1722053..e8597c7 100644 (file)
@@ -38,11 +38,6 @@ int  url_port;
 
 char as_main_program = 1;
 
-#ifdef IMAGE_FREEBSD
-int freebsd_howto = 0;
-char freebsd_kernel_env[FREEBSD_KERNEL_ENV_SIZE];
-#endif
-
 /* in_call(): the entry point to Etherboot.  Generally called from
  * arch_in_call(), which in turn will have been invoked from
  * platform-specific assembly code.
@@ -296,6 +291,16 @@ static int main_loop(int state)
                        if (dev->how_probe == PROBE_FAILED) {
                                state = -1;
                        }
+                       if (state == 1) {
+                               /* The bootp reply might have been changed, re-parse.  */
+                               decode_rfc1533(bootp_data.bootp_reply.bp_vend, 0,
+#ifdef NO_DHCP_SUPPORT
+                                              BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 
+#else
+                                              DHCP_OPT_LEN + MAX_BOOTP_EXTLEN, 
+#endif /* NO_DHCP_SUPPORT */
+                                              1);
+                       }
                }
        }
        switch(state) {
index cbda6ab..0289d59 100644 (file)
@@ -60,9 +60,13 @@ static void rpc_printerror(struct rpc_t *rpc)
 AWAIT_RPC - Wait for an rpc packet
 **************************************************************************/
 static int await_rpc(int ival, void *ptr,
-       unsigned short ptype, struct iphdr *ip, struct udphdr *udp)
+       unsigned short ptype, struct iphdr *ip, struct udphdr *udp, struct tcphdr *tcp)
 {
        struct rpc_t *rpc;
+
+       (void)ptype;
+       (void)tcp;
+
        if (!udp) 
                return 0;
        if (arptable[ARP_CLIENT].ipaddr.s_addr != ip->dest.s_addr)
@@ -305,6 +309,7 @@ static int nfs_readlink(int server, int port, char *fh, char *path, char *nfh,
        int retries;
        int pathlen = strlen(path);
 
+       (void)fh;
        id = rpc_id++;
        buf.u.call.id = htonl(id);
        buf.u.call.type = htonl(MSG_CALL);
@@ -518,7 +523,7 @@ nfssymlink:
                fname--;
        }
        if (fname < dirname) {
-               printf("can't parse file name %s\n", name);
+               printf("\nError: can't parse file name %s\n", name);
                return 0;
        }
 
@@ -529,14 +534,14 @@ nfssymlink:
                nfs_port = rpc_lookup(ARP_SERVER, PROG_NFS, 2, sport);
        }
        if (nfs_port == -1 || mount_port == -1) {
-               printf("can't get nfs/mount ports from portmapper\n");
+               printf("\nError: can't get nfs/mount ports from portmapper\n");
                return 0;
        }
 
 
        err = nfs_mount(ARP_SERVER, mount_port, dirname, dirfh, sport);
        if (err) {
-               printf("mounting %s: ", dirname);
+               printf("\nError mounting %s: ", dirname);
                nfs_printerror(err);
                /* just to be sure... */
                nfs_umountall(ARP_SERVER);
@@ -545,7 +550,7 @@ nfssymlink:
 
        err = nfs_lookup(ARP_SERVER, nfs_port, dirfh, fname, filefh, sport);
        if (err) {
-               printf("looking up %s: ", fname);
+               printf("\nError looking up %s: ", fname);
                nfs_printerror(err);
                nfs_umountall(ARP_SERVER);
                return 0;
@@ -572,7 +577,7 @@ nfssymlink:
                        return 0;
                }
                if (err) {
-                       printf("reading at offset %d: ", offs);
+                       printf("\nError reading at offset %d: ", offs);
                        nfs_printerror(err);
                        nfs_umountall(ARP_SERVER);
                        return 0;
index 82567dd..95998de 100644 (file)
@@ -31,6 +31,14 @@ char *hostname = "";
 int hostnamelen = 0;
 static uint32_t xid;
 unsigned char *end_of_rfc1533 = NULL;
+unsigned char *addparam;
+int addparamlen;
+
+#ifdef IMAGE_FREEBSD
+int freebsd_howto = 0;
+char freebsd_kernel_env[FREEBSD_KERNEL_ENV_SIZE];
+#endif /* IMAGE_FREEBSD */
+
 static int vendorext_isvalid;
 static const unsigned char vendorext_magic[] = {0xE4,0x45,0x74,0x68}; /* √§Eth */
 static const unsigned char broadcast[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
@@ -353,9 +361,8 @@ int eth_load(struct dev *dev __unused)
 #endif /* PXE_EXPORT */
 #endif /* ! NO_DHCP_SUPPORT */
        printf(", TFTP: %@", arptable[ARP_SERVER].ipaddr.s_addr);
-       if (BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr)
-               printf(", Relay: %@",
-                       BOOTP_DATA_ADDR->bootp_reply.bp_giaddr.s_addr);
+       if (bootp_data.bootp_reply.bp_giaddr.s_addr)
+               printf(", Relay: %@", bootp_data.bootp_reply.bp_giaddr.s_addr);
        if (arptable[ARP_GATEWAY].ipaddr.s_addr)
                printf(", Gateway %@", arptable[ARP_GATEWAY].ipaddr.s_addr);
 #ifdef DNS_RESOLVER
@@ -903,8 +910,8 @@ static int await_bootp(int ival __unused, void *ptr __unused,
 #endif /* NO_DHCP_SUPPORT */
                netmask = default_netmask();
                /* bootpreply->bp_file will be copied to KERNEL_BUF in the memcpy */
-               memcpy((char *)BOOTP_DATA_ADDR, (char *)bootpreply, sizeof(struct bootpd_t));
-               decode_rfc1533(BOOTP_DATA_ADDR->bootp_reply.bp_vend, 0,
+               memcpy((char *)&bootp_data, (char *)bootpreply, sizeof(struct bootpd_t));
+               decode_rfc1533(bootp_data.bootp_reply.bp_vend, 0,
 #ifdef NO_DHCP_SUPPORT
                               BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 
 #else
@@ -988,6 +995,8 @@ static int bootp(void)
 #else
                while ( remaining_time > 0 ) {
                        if (await_reply(await_bootp, 0, NULL, remaining_time)){
+                               if (arptable[ARP_CLIENT].ipaddr.s_addr)
+                                       break;
                        }
                        remaining_time = stop_time - currticks();
                }
@@ -1646,6 +1655,8 @@ int decode_rfc1533(unsigned char *p, unsigned int block, unsigned int len, int e
 #else
                vendorext_isvalid = 0;
 #endif
+               addparam = NULL;
+               addparamlen = 0;
                if (memcmp(p, rfc1533_cookie, 4))
                        return(0); /* no RFC 1533 header found */
                p += 4;
@@ -1656,7 +1667,7 @@ int decode_rfc1533(unsigned char *p, unsigned int block, unsigned int len, int e
                                return(0); /* no RFC 1533 header found */
                        p += 4;
                        len -= 4; }
-               if (extend + len <= (unsigned char *)&(BOOTP_DATA_ADDR->bootp_extension[MAX_BOOTP_EXTLEN])) {
+               if (extend + len <= (unsigned char *)&(bootp_data.bootp_extension[MAX_BOOTP_EXTLEN])) {
                        memcpy(extend, p, len);
                        extend += len;
                } else {
@@ -1713,6 +1724,17 @@ int decode_rfc1533(unsigned char *p, unsigned int block, unsigned int len, int e
                          p[6] == RFC1533_VENDOR_MAJOR
                        )
                        vendorext_isvalid++;
+               else if (c == RFC1533_VENDOR_ADDPARM) {
+                       /* This tag intentionally works for BOTH the encapsulated and
+                        * non-encapsulated case, since the current menu code (in mknbi)
+                        * creates this tag without encapsulation.  In the future both the
+                        * menu from mknbi and this code should learn about the proper
+                        * encapsulation (which will require substantial changes to various
+                        * stuff from mknbi, which will break compatibility with older
+                        * versions of Etherboot).  */
+                       addparam = p + 2;
+                       addparamlen = *(p + 1);
+               }
                else if (NON_ENCAP_OPT c == RFC1533_VENDOR_ETHERBOOT_ENCAP) {
                        in_encapsulated_options = 1;
                        decode_rfc1533(p+2, 0, TAG_LEN(p), -1);
index 7e0a998..5e92a8e 100644 (file)
@@ -77,7 +77,8 @@ static sector_t dead_download ( unsigned char *data __unused, unsigned int len _
 #ifdef IMAGE_MULTIBOOT
 #include "../arch/i386/core/multiboot_loader.c"
 #else
-#define multiboot_probe(data, len) do {} while(0)
+#define multiboot_init() do {} while(0)
+#define multiboot_peek(data, len) do {} while(0)
 #define multiboot_boot(entry) do {} while(0)
 #endif
 
@@ -337,6 +338,12 @@ int load_block(unsigned char *data, unsigned int block, unsigned int len, int eo
                }
        } /* end of block zero processing */
 
+#if defined(ELF_IMAGE) && defined(IMAGE_MULTIBOOT)
+       if (os_download == elf32_download) {
+               multiboot_peek(data, len);
+       }
+#endif /* defined(ELF_IMAGE) && defined(IMAGE_MULTIBOOT) */
+
        /* Either len is greater or the skip is greater */
        if ((skip_sectors > (len >> 9)) ||
                ((skip_sectors == (len >> 9)) && (skip_bytes >= (len & 0x1ff)))) {
index 0199de2..ac9489e 100644 (file)
@@ -1120,7 +1120,7 @@ PXENV_EXIT_t pxenv_get_cached_info ( t_PXENV_GET_CACHED_INFO
        memcpy ( cached_info->bootfile, KERNEL_BUF,
                 sizeof(cached_info->bootfile) );
        /* Copy DHCP vendor options */
-       memcpy ( &cached_info->vendor.d, BOOTP_DATA_ADDR->bootp_reply.bp_vend,
+       memcpy ( &cached_info->vendor.d, bootp_data.bootp_reply.bp_vend,
                 sizeof(cached_info->vendor.d) );
        
        /* Copy to user-specified buffer, or set pointer to our buffer */
index b22ae31..6909d9d 100644 (file)
@@ -12,8 +12,8 @@ PRINTF and friends
        Formats:
                %[#]x   - 4 bytes int (8 hex digits, lower case)
                %[#]X   - 4 bytes int (8 hex digits, upper case)
-               %[#]lx  - 8 bytes long (16 hex digits, lower case)
-               %[#]lX  - 8 bytes long (16 hex digits, upper case)
+               %[#]lx  - 8 bytes long (16 hex digits, lower case)
+               %[#]lX  - 8 bytes long (16 hex digits, upper case)
                %[#]hx  - 2 bytes int (4 hex digits, lower case)
                %[#]hX  - 2 bytes int (4 hex digits, upper case)
                %[#]hhx - 1 byte int (2 hex digits, lower case)
@@ -44,7 +44,7 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                while (*fmt >= '0' && *fmt <= '9')
                        fmt++;
                if (*fmt == 's') {
-                       for(p = va_arg(args, char *); *p != '\0'; p++) 
+                       for(p = va_arg(args, char *); *p != '\0'; p++)
                                buf ? *s++ = *p : putchar(*p);
                }
                else {  /* Length of item is bounded */
@@ -67,7 +67,7 @@ static int vsprintf(char *buf, const char *fmt, va_list args)
                                        fmt++;
                                }
                        }
-                       
+
                        /*
                         * Before each format q points to tmp buffer
                         * After each format q points past end of item
@@ -156,11 +156,12 @@ int sprintf(char *buf, const char *fmt, ...)
        return i;
 }
 
-void printf(const char *fmt, ...)
+int printf(const char *fmt, ...)
 {
        va_list args;
        int i;
        va_start(args, fmt);
        i=vsprintf(0, fmt, args);
        va_end(args);
+       return i;
 }
index b3ac0d6..88382d3 100644 (file)
@@ -444,6 +444,7 @@ static void pcnet32_reset(struct nic *nic)
        if (lp->options & PCNET32_PORT_ASEL)
                val |= 2;
        lp->a.write_bcr(ioaddr, 2, val);
+
        /* handle full duplex setting */
        if (lp->full_duplex) {
                val = lp->a.read_bcr(ioaddr, 9) & ~3;
@@ -646,10 +647,10 @@ static void pcnet32_disable(struct dev *dev __unused)
        lp->a.write_csr(ioaddr, 0, 0x0004);
 
        /*
-        * Switch back to 16-bit mode to avoid problesm with dumb 
+        * Switch back to 16-bit mode to avoid problems with dumb 
         * DOS packet driver after a warm reboot
         */
-       lp->a.write_bcr(ioaddr, 20, 4);
+       lp->a.write_bcr(ioaddr, 20, 0);
 }
 
 /**************************************************************************
@@ -712,7 +713,7 @@ static int pcnet32_probe(struct dev *dev, struct pci_device *pci)
        chip_version =
            a->read_csr(ioaddr, 88) | (a->read_csr(ioaddr, 89) << 16);
 
-       dprintf(("PCnet chip version is %0xhX\n", chip_version));
+       dprintf(("PCnet chip version is 0x%X\n", chip_version));
        if ((chip_version & 0xfff) != 0x003)
                return 0;
 
@@ -774,6 +775,7 @@ static int pcnet32_probe(struct dev *dev, struct pci_device *pci)
                mii = 1;
                break;
        default:
+               chipname = "UNKNOWN";
                printf("PCnet version %#x, no PCnet32 chip.\n",
                       chip_version);
                return 0;
@@ -806,7 +808,7 @@ static int pcnet32_probe(struct dev *dev, struct pci_device *pci)
                nic->node_addr[i] = promaddr[i];
        }
        /* Print out some hardware info */
-       printf("%s: %! at ioaddr %hX, ", pci->name, nic->node_addr,
+       printf("%s: %! at ioaddr 0x%hX, ", chipname, nic->node_addr,
               ioaddr);
 
        /* Set to pci bus master */
@@ -893,7 +895,6 @@ static int pcnet32_probe(struct dev *dev, struct pci_device *pci)
        /* switch pcnet32 to 32bit mode */
        a->write_bcr(ioaddr, 20, 2);
 
-
        a->write_csr(ioaddr, 1, (virt_to_bus(&lp->init_block)) & 0xffff);
        a->write_csr(ioaddr, 2, (virt_to_bus(&lp->init_block)) >> 16);
 
@@ -912,8 +913,8 @@ static int pcnet32_probe(struct dev *dev, struct pci_device *pci)
 
        /* point to NIC specific routines */
        pcnet32_reset(nic);
-       if (1) {
-               int tmp;
+       if (mii) {
+               int tmp;
                int phy, phy_idx = 0;
                u16 mii_lpa;
                lp->phys[0] = 1;        /* Default Setting */
@@ -950,6 +951,13 @@ static int pcnet32_probe(struct dev *dev, struct pci_device *pci)
                        printf("10Mbps Half-Duplex\n");
                else
                        printf("\n");
+       } else {
+               /* The older chips are fixed 10Mbps, and some support full duplex,
+                * although not via autonegotiation, but only via configuration.  */
+               if (fdx)
+                       printf("10Mbps Full-Duplex\n");
+               else
+                       printf("10Mbps Half-Duplex\n");
        }
 
        nic->poll     = pcnet32_poll;
@@ -996,9 +1004,9 @@ static void mdio_write(struct nic *nic __unused, int phy_id, int reg_num,
 #endif
 
 static struct pci_id pcnet32_nics[] = {
-       PCI_ROM(0x1022, 0x2000, "lancepci", "AMD Lance/PCI"),
-       PCI_ROM(0x1022, 0x2625, "pcnetfastiii", "AMD Lance/PCI PCNet/32"),
-       PCI_ROM(0x1022, 0x2001, "amdhomepna", "AMD Lance/HomePNA"),
+       PCI_ROM(0x1022, 0x2000, "pcnet32", "AMD PCnet/PCI"),
+       PCI_ROM(0x1022, 0x2625, "pcnetfastiii", "AMD PCNet FAST III"),
+       PCI_ROM(0x1022, 0x2001, "amdhomepna", "AMD PCnet/HomePNA"),
 };
 
 static struct pci_driver pcnet32_driver __pci_driver = {
index af01d5c..37c6158 100644 (file)
@@ -181,7 +181,7 @@ struct igmptable_t {
        unsigned long time;
 } PACKED;
 
-#define        KERNEL_BUF      (BOOTP_DATA_ADDR->bootp_reply.bp_file)
+#define        KERNEL_BUF      (bootp_data.bootp_reply.bp_file)
 
 #define        FLOPPY_BOOT_LOCATION    0x7c00
 
@@ -292,7 +292,7 @@ extern void poll_interruptions P((void));
 extern int strcasecmp P((const char *a, const char *b));
 extern char *substr P((const char *a, const char *b));
 extern unsigned long strtoul P((const char *p, const char **, int base));
-extern void printf P((const char *, ...));
+extern int printf P((const char *, ...));
 extern int sprintf P((char *, const char *, ...));
 extern int inet_aton P((const char *p, in_addr *i));
 #ifdef PCBIOS
@@ -322,7 +322,6 @@ extern void allot_real_mode_stack ( void );
 extern void forget_real_mode_stack ( void );
 extern void * allot_base_memory ( size_t );
 extern void forget_base_memory ( void*, size_t );
-extern void free_unused_base_memory ( void );
 extern void forget_prefix_base_memory ( void );
 extern void forget_runtime_base_memory ( uint32_t old_addr );
 
@@ -420,23 +419,17 @@ extern int pxe_in_call ( in_call_data_t *in_call_data, va_list params );
 External variables
 ***************************************************************************/
 /* main.c */
-extern struct rom_info rom;
-extern char *hostname;
-extern int hostnamelen;
 extern jmp_buf restart_etherboot;
 extern int url_port;
+/* nic.c */
+extern struct rom_info rom;
 extern struct arptable_t arptable[MAX_ARP];
 extern struct igmptable_t igmptable[MAX_IGMP];
-#ifdef IMAGE_MENU
-extern int menutmo,menudefault;
-extern unsigned char *defparams;
-extern int defparams_max;
-#endif
-#ifdef MOTD
-extern unsigned char *motd[RFC1533_VENDOR_NUMOFMOTD];
-#endif
+extern char *hostname;
+extern int hostnamelen;
+extern unsigned char *addparam;
+extern int addparamlen;
 extern struct bootpd_t bootp_data;
-#define        BOOTP_DATA_ADDR (&bootp_data)
 extern unsigned char *end_of_rfc1533;
 #ifdef IMAGE_FREEBSD
 extern int freebsd_howto;
@@ -444,8 +437,6 @@ extern int freebsd_howto;
 extern char freebsd_kernel_env[FREEBSD_KERNEL_ENV_SIZE];
 #endif
 
-/* bootmenu.c */
-
 /* osloader.c */
 
 /* created by linker */