Recent build changes have added a PT_NOTE entry to the kernel's
ELF header.  A perfectly valid change, but Alpha's aboot loader
is none too bright about examining these headers.

The following patch to aboot-1.0_pre20040408.tar.bz2 makes it
so that only PT_LOAD entries are considered for loading, as well
as several other changes required to get the damned thing to
build again.


r~


diff -rup aboot-1.0_pre20040408/Makefile aboot-local/Makefile
--- aboot-1.0_pre20040408/Makefile      2004-04-08 08:19:01.000000000 -0700
+++ aboot-local/Makefile        2007-08-13 16:08:01.000000000 -0700
@@ -32,15 +32,15 @@ export
 #
 LOADADDR       = 20000000
 
-ABOOT_LDFLAGS = -static -N -Taboot.lds
+ABOOT_LDFLAGS = -static -N -Taboot.lds --relax
 
 CC             = gcc
 TOP            = $(shell pwd)
 ifeq ($(TESTING),)
-CPPFLAGS       = $(CFGDEFS) -I$(TOP)/include
-CFLAGS         = $(CPPFLAGS) -D__KERNEL__ -Os -Wall -fno-builtin -mno-fp-regs 
-ffixed-8
+CPPFLAGS       = $(CFGDEFS) -I$(TOP)/include -I$(KSRC)/include
+CFLAGS         = $(CPPFLAGS) -D__KERNEL__ -Os -Wall -fno-builtin -mno-fp-regs
 else
-CPPFLAGS       = -DTESTING $(CFGDEFS) -I$(TOP)/include
+CPPFLAGS       = -DTESTING $(CFGDEFS) -I$(TOP)/include -I$(KSRC)/include
 CFLAGS         = $(CPPFLAGS) -O -g3 -Wall -D__KERNEL__ -ffixed-8
 endif
 ASFLAGS                = $(CPPFLAGS)
diff -rup aboot-1.0_pre20040408/aboot.c aboot-local/aboot.c
--- aboot-1.0_pre20040408/aboot.c       2004-04-08 10:53:57.000000000 -0700
+++ aboot-local/aboot.c 2007-08-13 15:46:33.000000000 -0700
@@ -19,14 +19,13 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/elf.h>
 #include <linux/kernel.h>
 #include <linux/version.h>
-
 #include <asm/console.h>
 #include <asm/hwrpb.h>
 #include <asm/system.h>
 
+#include <elf.h>
 #include <alloca.h>
 #include <errno.h>
 
@@ -37,16 +36,6 @@
 #include "utils.h"
 #include "string.h"
 
-#ifndef elf_check_arch
-# define aboot_elf_check_arch(e)       1
-#else
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-#  define aboot_elf_check_arch(e)        elf_check_arch(e)
-# else
-#  define aboot_elf_check_arch(e)        elf_check_arch(e->e_machine)
-# endif
-#endif
-
 struct bootfs *        bfs = 0;                /* filesystem to boot from */
 char *         dest_addr = 0;
 jmp_buf                jump_buffer;
@@ -83,77 +72,86 @@ static unsigned long entry_addr = START_
 long
 first_block (const char *buf, long blocksize)
 {
-       struct elfhdr *elf;
-       struct elf_phdr *phdrs;
+       Elf64_Ehdr *elf;
+       Elf64_Phdr *phdrs;
+       int i, j;
 
-       elf  = (struct elfhdr *) buf;
+       elf  = (Elf64_Ehdr *) buf;
        
-       if (elf->e_ident[0] == 0x7f
-           && strncmp(elf->e_ident + 1, "ELF", 3) == 0)
-       {
-               int i;
-               /* looks like an ELF binary: */
-               if (elf->e_type != ET_EXEC) {
-                       printf("aboot: not an executable ELF file\n");
-                       return -1;
-               }
-               if (!aboot_elf_check_arch(elf)) {
-                       printf("aboot: ELF executable not for this machine\n");
-                       return -1;
-               }
-               if (elf->e_phoff + elf->e_phnum * sizeof(*phdrs) > (unsigned) 
blocksize) {
-                       printf("aboot: "
-                              "ELF program headers not in first block (%ld)\n",
-                              (long) elf->e_phoff);
+       if (elf->e_ident[0] != 0x7f
+           || elf->e_ident[1] != 'E'
+           || elf->e_ident[2] != 'L'
+           || elf->e_ident[3] != 'F') {
+               /* Fail silently, it might be a compressed file */
+               return -1;
+       }
+       if (elf->e_ident[EI_CLASS] != ELFCLASS64
+           || elf->e_ident[EI_DATA] != ELFDATA2LSB
+           || elf->e_machine != EM_ALPHA) {
+               printf("aboot: ELF executable not for this machine\n");
+               return -1;
+       }
+
+       /* Looks like an ELF binary. */
+       if (elf->e_type != ET_EXEC) {
+               printf("aboot: not an executable ELF file\n");
+               return -1;
+       }
+
+       if (elf->e_phoff + elf->e_phnum * sizeof(*phdrs)
+           > (unsigned) blocksize) {
+               printf("aboot: ELF program headers not in first block (%ld)\n",
+                      (long) elf->e_phoff);
+               return -1;
+       }
+
+       phdrs = (struct elf_phdr *) (buf + elf->e_phoff);
+       chunks = malloc(sizeof(struct segment) * elf->e_phnum);
+       start_addr = phdrs[0].p_vaddr; /* assume they are sorted */
+       entry_addr = elf->e_entry;
+
+       for (i = j = 0; i < elf->e_phnum; ++i) {
+               int status;
+
+               if (phdrs[i].p_type != PT_LOAD)
+                       continue;
+
+               chunks[j].addr   = phdrs[i].p_vaddr;
+               chunks[j].offset = phdrs[i].p_offset;
+               chunks[j].size   = phdrs[i].p_filesz;
+               printf("aboot: PHDR %d vaddr %#lx offset %#lx size %#lx\n",
+                      i, chunks[j].addr, chunks[j].offset, chunks[j].size);
+
+               status = check_memory(chunks[j].addr, chunks[j].size);
+               if (status) {
+                       printf("aboot: Can't load kernel.\n"
+                              "  Memory at %lx - %lx (PHDR %i) "
+                                "is %s\n",
+                              chunks[j].addr,
+                              chunks[j].addr + chunks[j].size - 1,
+                              i,
+                              (status == -ENOMEM) ?
+                                 "Not Found" :
+                                 "Busy (Reserved)");
                        return -1;
                }
-               phdrs = (struct elf_phdr *) (buf + elf->e_phoff);
-               chunks = malloc(sizeof(struct segment) * elf->e_phnum);
-               nchunks = elf->e_phnum;
-               start_addr = phdrs[0].p_vaddr; /* assume they are sorted */
-               entry_addr = elf->e_entry;
-#ifdef DEBUG
-               printf("aboot: %d program headers, start address %#lx, entry 
%#lx\n",
-                      nchunks, start_addr, entry_addr);
-#endif
-               for (i = 0; i < elf->e_phnum; ++i) {
-                       int status;
-
-                       chunks[i].addr   = phdrs[i].p_vaddr;
-                       chunks[i].offset = phdrs[i].p_offset;
-                       chunks[i].size   = phdrs[i].p_filesz;
-#ifdef DEBUG
-                       printf("aboot: segment %d vaddr %#lx offset %#lx size 
%#lx\n",
-                              i, chunks[i].addr, chunks[i].offset, 
chunks[i].size);
-#endif
-
-#ifndef TESTING
-                       status = check_memory(chunks[i].addr, chunks[i].size);
-                       if (status) {
+
+               if (phdrs[i].p_memsz > phdrs[i].p_filesz) {
+                       if (bss_size > 0) {
                                printf("aboot: Can't load kernel.\n"
-                                      "  Memory at %lx - %lx (chunk %i) "
-                                        "is %s\n",
-                                      chunks[i].addr,
-                                      chunks[i].addr + chunks[i].size - 1,
-                                      i,
-                                      (status == -ENOMEM) ?
-                                         "Not Found" :
-                                         "Busy (Reserved)");
+                                      "  Multiple BSS segments"
+                                      " (PHDR %d)\n", i);
                                return -1;
                        }
-#endif
+                       bss_start = (char *) (phdrs[i].p_vaddr +
+                                             phdrs[i].p_filesz);
+                       bss_size = phdrs[i].p_memsz - phdrs[i].p_filesz;
                }
-               bss_start = (char *) (phdrs[elf->e_phnum - 1].p_vaddr +
-                                     phdrs[elf->e_phnum - 1].p_filesz);
-               bss_size = (phdrs[elf->e_phnum - 1].p_memsz -
-                           phdrs[elf->e_phnum - 1].p_filesz);
-#ifdef DEBUG
-               printf("aboot: bss at 0x%p, size %#lx\n", bss_start, bss_size);
-#endif
-       } else {
-               /* Fail silently, it might be a compressed file */
-               return -1;
+
+               j++;
        }
+       nchunks = j;
+       printf("aboot: bss at 0x%p, size %#lx\n", bss_start, bss_size);
 
        return 0;
 }
diff -rup aboot-1.0_pre20040408/aboot.lds aboot-local/aboot.lds
--- aboot-1.0_pre20040408/aboot.lds     2001-10-08 16:03:50.000000000 -0700
+++ aboot-local/aboot.lds       2007-08-13 15:59:46.000000000 -0700
@@ -1,22 +1,25 @@
 OUTPUT_FORMAT("elf64-alpha")
 ENTRY(__start)
+PHDRS { kernel PT_LOAD; }
 SECTIONS
 {
   . = 0x20000000;
-  .text : { *(.text) }
+  .text : { *(.text) } :kernel
   _etext = .;
   PROVIDE (etext = .);
-  .rodata : { *(.rodata) }
-  .data : { *(.data) CONSTRUCTORS }
-  .got : { *(.got) }
-  .sdata : { *(.sdata) }
+  .rodata : { *(.rodata*) } :kernel
+  .data : { *(.data*) } :kernel
+  .got : { *(.got) } :kernel
+  .sdata : { *(.sdata) } :kernel
   _edata = .;
   PROVIDE (edata = .);
-  .sbss : { *(.sbss) *(.scommon) }
-  .bss : { *(.bss) *(COMMON) }
+  .sbss : { *(.sbss) *(.scommon) } :kernel
+  .bss : { *(.bss) *(COMMON) } :kernel
   _end = . ;
   PROVIDE (end = .);
 
+  /DISCARD/ : { *(.eh_frame) } 
+
   .mdebug 0 : { *(.mdebug) }
   .note 0 : { *(.note) }
   .comment 0 : { *(.comment) }
diff -rup aboot-1.0_pre20040408/cons.c aboot-local/cons.c
--- aboot-1.0_pre20040408/cons.c        2003-11-30 19:56:34.000000000 -0800
+++ aboot-local/cons.c  2007-08-13 15:48:45.000000000 -0700
@@ -1,5 +1,3 @@
-#include <alloca.h>
-
 #include <linux/kernel.h>
 
 #include <asm/console.h>
@@ -20,7 +18,7 @@
 #endif
 
 long cons_dev;                 /* console device */
-extern long int dispatch();    /* Need the full 64 bit return here...*/
+extern long int dispatch(long, ...);   /* Need the full 64 bit return here...*/
 
 long
 cons_puts(const char *str, long len)
@@ -82,7 +80,7 @@ cons_getenv(long index, char *envval, lo
         * allocated on the stack (which guaranteed to by 8 byte
         * aligned).
         */
-       char * tmp = alloca(maxlen);
+       char tmp[maxlen];
        long len;
 
        len = dispatch(CCB_GET_ENV, index, tmp, maxlen - 1);
diff -rup aboot-1.0_pre20040408/disk.c aboot-local/disk.c
--- aboot-1.0_pre20040408/disk.c        2004-04-08 11:14:06.000000000 -0700
+++ aboot-local/disk.c  2007-08-13 15:50:22.000000000 -0700
@@ -113,7 +113,7 @@ int
 load_uncompressed (int fd)
 {
        long nread, nblocks;
-       unsigned char *buf;
+       char *buf;
        int i;
 
        buf = malloc(bfs->blocksize);
@@ -131,7 +131,7 @@ load_uncompressed (int fd)
        
                for(i = 0; i < 16; i++) {
                        for (j = 0; j < 16; j++)
-                               printf("%02X ", buf[j+16*i]);
+                               printf("%02X ", (unsigned char) buf[j+16*i]);
                        for(j = 0; j < 16; j++) {
                                c = buf[j+16*i];
                                printf("%c", (c >= ' ') ? c : ' ');
diff -rup aboot-1.0_pre20040408/head.S aboot-local/head.S
--- aboot-1.0_pre20040408/head.S        2001-10-08 16:03:51.000000000 -0700
+++ aboot-local/head.S  2007-08-13 16:03:57.000000000 -0700
@@ -19,8 +19,7 @@ __start:
        .quad   0,0,0,0,0,0,0,0
 1:     br      $27,2f
 2:     ldgp    $29,0($27)
-       lda     $27,main_
-       jsr     $26,($27),main_
+       bsr     $26,main_       !samegp
        call_pal PAL_halt
        .end __start
 
@@ -170,4 +169,4 @@ run_kernel:
        mov     $16,$27
        mov     $17,$30
        jmp     $31,($27)
-       .end run_kernel
\ No newline at end of file
+       .end run_kernel
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to