summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sys-boot/aboot/files/aboot-pt_note.patch')
-rw-r--r--sys-boot/aboot/files/aboot-pt_note.patch308
1 files changed, 308 insertions, 0 deletions
diff --git a/sys-boot/aboot/files/aboot-pt_note.patch b/sys-boot/aboot/files/aboot-pt_note.patch
new file mode 100644
index 000000000000..d28527ad5b0c
--- /dev/null
+++ b/sys-boot/aboot/files/aboot-pt_note.patch
@@ -0,0 +1,308 @@
+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.
+
+--- aboot-1.0_pre20040408/Makefile
++++ aboot-1.0_pre20040408/Makefile
+@@ -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)
+
+--- aboot-1.0_pre20040408/aboot.c
++++ aboot-1.0_pre20040408/aboot.c
+@@ -19,7 +19,6 @@
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+-#include <linux/elf.h>
+ #include <linux/kernel.h>
+ #include <linux/version.h>
+
+@@ -27,6 +26,7 @@
+ #include <asm/hwrpb.h>
+ #include <asm/system.h>
+
++#include <elf.h>
+ #include <alloca.h>
+ #include <errno.h>
+
+@@ -37,16 +37,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 +73,89 @@ static unsigned long entry_addr = START_ADDR;
+ 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;
+ }
+
+--- aboot-1.0_pre20040408/aboot.lds
++++ aboot-1.0_pre20040408/aboot.lds
+@@ -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) }
+
+--- aboot-1.0_pre20040408/cons.c
++++ aboot-1.0_pre20040408/cons.c
+@@ -82,7 +81,7 @@ cons_getenv(long index, char *envval, long maxlen)
+ * 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);
+
+--- aboot-1.0_pre20040408/disk.c
++++ aboot-1.0_pre20040408/disk.c
+@@ -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 : ' ');
+
+--- aboot-1.0_pre20040408/head.S
++++ aboot-1.0_pre20040408/head.S
+@@ -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