| 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 |