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