You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

309 lines
8.8 KiB

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