Make ELF kernel loadable, by itohy-san.
This commit is contained in:
parent
7ab28ee8d5
commit
1dc0c84b6b
340
sys/arch/x68k/stand/common/exec_sub.c
Normal file
340
sys/arch/x68k/stand/common/exec_sub.c
Normal file
@ -0,0 +1,340 @@
|
||||
/* $NetBSD: exec_sub.c,v 1.1 2002/05/18 13:54:38 isaki Exp $ */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#include "execkern.h"
|
||||
#include <a.out.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifdef BOOT
|
||||
void B_PRINT __P((const unsigned char *p));
|
||||
#endif
|
||||
|
||||
static __inline void bzero4 __P((void *ptr, size_t siz));
|
||||
static void xk_aout __P((struct execkern_arg *xarg, struct exec *hdr));
|
||||
static void xk_elf __P((struct execkern_arg *xarg, Elf32_Ehdr *hdr));
|
||||
|
||||
#ifdef LOADBSD
|
||||
static void DPRINT_SEC __P((const char *ident,
|
||||
const struct execkern_section *sec));
|
||||
extern int opt_v;
|
||||
extern const char *kernel_fn;
|
||||
|
||||
static void
|
||||
DPRINT_SEC(ident, sec)
|
||||
const char *ident;
|
||||
const struct execkern_section *sec;
|
||||
{
|
||||
|
||||
if (opt_v)
|
||||
xwarnx("section (%s): img %p, sz %d, pad %d", ident,
|
||||
sec->sec_image, sec->sec_size, sec->sec_pad);
|
||||
}
|
||||
|
||||
#define ERRX(arg) xerrx arg
|
||||
|
||||
#else
|
||||
#define DPRINT_SEC(ident, sec) /**/
|
||||
#define ERRX(arg) return 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This code is size-hacked version of
|
||||
*
|
||||
* sec->sec_image = (image);
|
||||
* sec->sec_size = (size);
|
||||
* sec->sec_pad = (pad);
|
||||
* DPRINT_SEC((ident), sec);
|
||||
* sec++;
|
||||
*/
|
||||
#define SECTION(sec, ident, image, size, pad) \
|
||||
do { \
|
||||
u_long *wp = (void *) sec; \
|
||||
*(void **)wp++ = (image); \
|
||||
*wp++ = (size); \
|
||||
*wp++ = (pad); \
|
||||
DPRINT_SEC((ident), sec); \
|
||||
sec = (void *) wp; \
|
||||
} while (0)
|
||||
|
||||
#define SECTION_NOPAD(sec, ident, image, size) \
|
||||
SECTION(sec, (ident), (image), (size), 0)
|
||||
|
||||
static __inline void
|
||||
bzero4(ptr, siz)
|
||||
void *ptr;
|
||||
size_t siz;
|
||||
{
|
||||
u_long *p;
|
||||
u_short s;
|
||||
|
||||
p = ptr;
|
||||
s = siz >> 2;
|
||||
|
||||
while (s--)
|
||||
*p++ = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* fill in loading information from an a.out executable
|
||||
*/
|
||||
static void
|
||||
xk_aout(xarg, hdr)
|
||||
struct execkern_arg *xarg;
|
||||
struct exec *hdr;
|
||||
{
|
||||
unsigned u;
|
||||
char *s;
|
||||
struct execkern_section *sec;
|
||||
|
||||
xarg->entry_addr = hdr->a_entry;
|
||||
sec = xarg->sec;
|
||||
|
||||
/* text section and padding between data section */
|
||||
s = (void *) (hdr + 1);
|
||||
SECTION(sec, "text", s, hdr->a_text, -hdr->a_text & (__LDPGSZ-1));
|
||||
|
||||
/* data and bss sections */
|
||||
s += hdr->a_text;
|
||||
SECTION(sec, "data/bss", s, hdr->a_data, hdr->a_bss);
|
||||
|
||||
/* size of symbol table */
|
||||
SECTION_NOPAD(sec, "symtab size", &sec[1].sec_size, sizeof(u_long));
|
||||
|
||||
/* symbol table section */
|
||||
s += hdr->a_data;
|
||||
SECTION_NOPAD(sec, "symbol", s, u = hdr->a_syms);
|
||||
|
||||
/* string table section */
|
||||
if (u) {
|
||||
#ifdef LOADBSD
|
||||
if (opt_v)
|
||||
xwarnx("symbol table found");
|
||||
#endif
|
||||
s += u;
|
||||
SECTION_NOPAD(sec, "string", s, *(u_long *) s);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fill in loading information from an ELF executable
|
||||
*/
|
||||
static void
|
||||
xk_elf(xarg, hdr)
|
||||
struct execkern_arg *xarg;
|
||||
Elf32_Ehdr *hdr;
|
||||
{
|
||||
char *top = (void *) hdr;
|
||||
struct execkern_section *sec;
|
||||
Elf32_Phdr *ph;
|
||||
Elf32_Shdr *sh, *sym, *str, *stab, *shstr;
|
||||
const char *shstrtab, *shname;
|
||||
unsigned u, dpos, pd;
|
||||
const char *const shstrtab_new = SHSTRTAB_FAKE;
|
||||
|
||||
xarg->entry_addr = hdr->e_entry;
|
||||
|
||||
/*
|
||||
* text, data, bss
|
||||
*/
|
||||
ph = (void *) (top + hdr->e_phoff);
|
||||
xarg->load_addr = ph->p_vaddr;
|
||||
|
||||
sec = xarg->sec;
|
||||
sec->sec_image = top + ph->p_offset;
|
||||
sec->sec_size = ph->p_filesz;
|
||||
|
||||
if (hdr->e_phnum != 1) {
|
||||
sec->sec_pad = ph[1].p_vaddr - (ph->p_vaddr + ph->p_filesz);
|
||||
DPRINT_SEC("program (text)", sec);
|
||||
sec++;
|
||||
ph++;
|
||||
sec->sec_image = top + ph->p_offset;
|
||||
sec->sec_size = ph->p_filesz;
|
||||
}
|
||||
|
||||
sec->sec_pad = ph->p_memsz - ph->p_filesz;
|
||||
DPRINT_SEC("program (data/bss)", sec);
|
||||
sec++;
|
||||
|
||||
/*
|
||||
* symbol size
|
||||
*/
|
||||
xarg->elfsymsiz = 0; /* no symbol */
|
||||
SECTION_NOPAD(sec, "symtab size", &xarg->elfsymsiz, sizeof(int));
|
||||
|
||||
/*
|
||||
* ELF header
|
||||
*/
|
||||
xarg->ehdr = *hdr;
|
||||
xarg->ehdr.e_shstrndx = 0; /* .shstrtab will be the 1st section */
|
||||
SECTION_NOPAD(sec, "ELF header", &xarg->ehdr, sizeof(Elf32_Ehdr));
|
||||
|
||||
sh = (void *) (top + hdr->e_shoff); /* section header */
|
||||
shstr = sh + hdr->e_shstrndx; /* .shstrtab */
|
||||
shstrtab = top + shstr->sh_offset;
|
||||
|
||||
sym = str = stab = 0;
|
||||
for (u = 0; sh++, ++u < hdr->e_shnum; ) {
|
||||
shname = shstrtab + sh->sh_name;
|
||||
if (!strcmp(shname, shstrtab_new + SHNAME_OFF_SYMTAB))
|
||||
sym = sh; /* .symtab */
|
||||
if (!strcmp(shname, shstrtab_new + SHNAME_OFF_STRTAB))
|
||||
str = sh; /* .strtab */
|
||||
if (!strcmp(shname, shstrtab_new + SHNAME_OFF_STAB))
|
||||
stab = sh; /* .stab */
|
||||
}
|
||||
|
||||
if (shstr == 0 || sym == 0 || str == 0)
|
||||
xarg->ehdr.e_shnum = 0; /* no symbol */
|
||||
else {
|
||||
#ifdef LOADBSD
|
||||
if (opt_v) {
|
||||
xwarnx("symbol table found");
|
||||
if (stab)
|
||||
xwarnx("debugging information found");
|
||||
}
|
||||
#endif
|
||||
xarg->elfsymsiz = 1; /* has symbol */
|
||||
xarg->ehdr.e_shnum = 3;
|
||||
xarg->ehdr.e_shoff = sizeof(Elf32_Ehdr);
|
||||
|
||||
SECTION_NOPAD(sec, "section header (shstrtab)",
|
||||
shstr, sizeof(Elf32_Shdr));
|
||||
|
||||
SECTION_NOPAD(sec, "section header (symbol)",
|
||||
sym, sizeof(Elf32_Shdr));
|
||||
|
||||
SECTION_NOPAD(sec, "section header (string)",
|
||||
str, sizeof(Elf32_Shdr));
|
||||
|
||||
dpos = sizeof(Elf32_Ehdr) + sizeof(Elf32_Shdr) * 3;
|
||||
u = SIZE_SHSTRTAB_FAKE;
|
||||
|
||||
if (stab) {
|
||||
xarg->ehdr.e_shnum++;
|
||||
SECTION_NOPAD(sec, "section header (stab)",
|
||||
stab, sizeof(Elf32_Shdr));
|
||||
dpos += sizeof(Elf32_Shdr);
|
||||
u = SIZE_SHSTRTAB_FAKE_WITH_STAB;
|
||||
}
|
||||
|
||||
/* new .shstrtab section */
|
||||
memcpy(xarg->shstrtab_fake, shstrtab_new, u);
|
||||
/*
|
||||
* DDB requires symtab be aligned.
|
||||
*/
|
||||
pd = -u & ALIGNBYTES;
|
||||
SECTION(sec, "shstrtab", &xarg->shstrtab_fake, u, pd);
|
||||
shstr->sh_name = SHNAME_OFF_SHSTRTAB;
|
||||
shstr->sh_offset = dpos;
|
||||
dpos += u + pd;
|
||||
|
||||
SECTION_NOPAD(sec, "symtab",
|
||||
top + sym->sh_offset, sym->sh_size);
|
||||
sym->sh_name = SHNAME_OFF_SYMTAB;
|
||||
sym->sh_offset = dpos;
|
||||
dpos += sym->sh_size;
|
||||
|
||||
SECTION_NOPAD(sec, "strtab",
|
||||
top + str->sh_offset, str->sh_size);
|
||||
str->sh_name = SHNAME_OFF_STRTAB;
|
||||
str->sh_offset = dpos;
|
||||
dpos += str->sh_size;
|
||||
|
||||
if (stab) {
|
||||
SECTION_NOPAD(sec, "stab",
|
||||
top + stab->sh_offset, stab->sh_size);
|
||||
stab->sh_name = SHNAME_OFF_STAB;
|
||||
stab->sh_offset = dpos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
xk_load(xarg, buf, loadaddr)
|
||||
struct execkern_arg *xarg;
|
||||
void *buf;
|
||||
u_long loadaddr; /* for a.out */
|
||||
{
|
||||
struct exec *ahdr;
|
||||
Elf32_Ehdr *ehdr;
|
||||
unsigned u;
|
||||
|
||||
/* Unused section entries should be cleared to zero. */
|
||||
bzero4(xarg->sec, sizeof xarg->sec);
|
||||
|
||||
xarg->load_addr = loadaddr;
|
||||
|
||||
/*
|
||||
* check exec header
|
||||
*/
|
||||
ahdr = buf;
|
||||
ehdr = buf;
|
||||
|
||||
if (N_GETMAGIC(*ahdr) == NMAGIC) {
|
||||
/*
|
||||
* this is an a.out
|
||||
*/
|
||||
#ifdef LOADBSD
|
||||
if (opt_v)
|
||||
xwarnx("%s: is an a.out", kernel_fn);
|
||||
#endif
|
||||
#ifdef BOOT
|
||||
B_PRINT("This is an a.out\r\n");
|
||||
#endif
|
||||
|
||||
if ((u = N_GETMID(*ahdr)) != MID_M68K)
|
||||
ERRX((1, "%s: Wrong architecture (mid %u)",
|
||||
kernel_fn, u));
|
||||
|
||||
/*
|
||||
* fill in loading information
|
||||
*/
|
||||
xk_aout(xarg, ahdr);
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
* check ELF header
|
||||
*/
|
||||
if (*(u_int32_t *)&ehdr->e_ident[EI_MAG0] !=
|
||||
(ELFMAG0<<24 | ELFMAG1<<16 | ELFMAG2<<8 | ELFMAG3) ||
|
||||
*(u_int16_t *)&ehdr->e_ident[EI_CLASS] !=
|
||||
(ELFCLASS32 << 8 | ELFDATA2MSB))
|
||||
ERRX((1, "%s: Not an NMAGIC a.out or a 32bit BE ELF",
|
||||
kernel_fn));
|
||||
|
||||
/*
|
||||
* this is an ELF
|
||||
*/
|
||||
#ifdef LOADBSD
|
||||
if (opt_v)
|
||||
xwarnx("%s: is an ELF", kernel_fn);
|
||||
#endif
|
||||
#ifdef BOOT
|
||||
B_PRINT("This is an ELF\r\n");
|
||||
#endif
|
||||
|
||||
if (ehdr->e_ident[EI_VERSION] != EV_CURRENT ||
|
||||
ehdr->e_version != EV_CURRENT)
|
||||
ERRX((1, "%s: Unsupported ELF version", kernel_fn));
|
||||
|
||||
if ((u = ehdr->e_machine) != EM_68K)
|
||||
ERRX((1, "%s: Wrong architecture (mid %u)",
|
||||
kernel_fn, u));
|
||||
if (ehdr->e_type != ET_EXEC)
|
||||
ERRX((1, "%s: Not an executable", kernel_fn));
|
||||
if ((u = ehdr->e_phnum) != 1 && u != 2)
|
||||
ERRX((1, "%s: Wrong number (%u) of loading sections",
|
||||
kernel_fn, u));
|
||||
|
||||
/*
|
||||
* fill in loading information
|
||||
*/
|
||||
xk_elf(xarg, ehdr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -4,10 +4,10 @@
|
||||
| written by Yasha (ITOH Yasufumi)
|
||||
| public domain
|
||||
|
|
||||
| $NetBSD: execkern.S,v 1.2 2001/06/12 16:57:27 minoura Exp $
|
||||
| $NetBSD: execkern.S,v 1.3 2002/05/18 13:54:38 isaki Exp $
|
||||
|
||||
/* XXX this value is from <machine/exec_aout.h> */
|
||||
#define __LDPGSZ 8192
|
||||
#include <machine/asm.h>
|
||||
#include "execkern.h"
|
||||
|
||||
#define MFP 0x00E88000 /* MFP */
|
||||
#define MFP_IERA (MFP+0x07) /* (B) interrupt enable reg A */
|
||||
@ -19,16 +19,20 @@
|
||||
#define SRAM_MEMSZ (SRAM + 8) /* (L) size of main memory */
|
||||
#endif
|
||||
|
||||
| %a3+0 kernel image top address (a.out header is excluded)
|
||||
| %a3+4 load address
|
||||
| %a3+8 text size
|
||||
| %a3+12 data size
|
||||
| %a3+16 bss size
|
||||
| %a3+20 symbol size
|
||||
| %a3+24 (reserved) (%d5)
|
||||
| %a3+28 bootdev (%d6)
|
||||
| %a3+32 boothowto (%d7)
|
||||
| %a3+36 entry address (absolute address)
|
||||
| a3+0 load address
|
||||
|
|
||||
| a3+4 section #1 image top address
|
||||
| a3+8 section #1 size
|
||||
| a3+12 section #1 gap size
|
||||
| : :
|
||||
| a3+n-12 section #XK_NSEC image top address
|
||||
| a3+n-8 section #XK_NSEC size
|
||||
| a3+n-4 section #XK_NSEC gap size
|
||||
|
|
||||
| a3+n (reserved) (d5)
|
||||
| a3+n+4 bootdev (d6)
|
||||
| a3+n+8 boothowto (d7)
|
||||
| a3+n+12 entry address (absolute address)
|
||||
|
||||
#ifndef XK_NO_C_INTERFACE
|
||||
.text
|
||||
@ -38,7 +42,6 @@ ENTRY_NOPROFILE(exec_kernel)
|
||||
moveal %sp@+,%a3 | struct execkern_arg *
|
||||
#endif
|
||||
|
||||
moveal %a3@+,%a0 | image address
|
||||
moveal %a3@+,%a1 | load address
|
||||
movel %a1,%d3
|
||||
|
||||
@ -46,41 +49,16 @@ ENTRY_NOPROFILE(exec_kernel)
|
||||
| copy image
|
||||
|
|
||||
|
||||
| copy text segment
|
||||
movel %a3@+,%d0 | text size
|
||||
movel #XK_NSEC-1,%d2
|
||||
Lloop:
|
||||
moveal %a3@+,%a0 | section image address
|
||||
movel %a3@+,%d0 | section size
|
||||
movel %d0,%d1
|
||||
jbsr copy
|
||||
|
||||
| clear gap between text and data
|
||||
negl %d1
|
||||
andil #__LDPGSZ-1,%d1
|
||||
movel %d1,%d0 | gap size between text and data
|
||||
movel %a3@+,%d0 | section gap
|
||||
jbsr clear
|
||||
|
||||
| copy data segment
|
||||
movel %a3@+,%d0 | data size
|
||||
jbsr copy
|
||||
|
||||
| clear bss
|
||||
movel %a3@+,%d0 | bss size
|
||||
jbsr clear
|
||||
|
||||
| copy symbol table
|
||||
movel %a3@+,%d0 | symbol table size
|
||||
movel %d0,%a1@+
|
||||
beqs Lnotable
|
||||
jbsr copy
|
||||
|
||||
| copy string table size
|
||||
movel %a0@+,%d0
|
||||
movel %d0,%a1@+
|
||||
beqs Lnotable
|
||||
|
||||
| copy string table
|
||||
subql #4,%d0 | table size is already copied
|
||||
jbsr copy
|
||||
|
||||
Lnotable:
|
||||
dbra %d2,Lloop
|
||||
|
||||
| stop MFP interrupts (for compatibility)
|
||||
clrb MFP_IERA
|
||||
@ -95,7 +73,7 @@ Lnotable:
|
||||
addql #3,%d0
|
||||
andib #0xFC,%d0
|
||||
subl %d3,%d0
|
||||
movel %d0,%sp@- | arg #3 (kernel size)
|
||||
movel %d0,%sp@- | arg #3 (end of kernel)
|
||||
movel SRAM_MEMSZ,%sp@- | arg #2 (RAM size from SRAM)
|
||||
movel %d3,%sp@- | arg #1 (load address)
|
||||
|
||||
|
@ -4,25 +4,56 @@
|
||||
* written by Yasha (ITOH Yasufumi)
|
||||
* public domain
|
||||
*
|
||||
* $NetBSD: execkern.h,v 1.1 1998/09/01 19:51:56 itohy Exp $
|
||||
* $NetBSD: execkern.h,v 1.2 2002/05/18 13:54:38 isaki Exp $
|
||||
*/
|
||||
|
||||
#ifndef X68K_BOOT_EXECKERN_H
|
||||
#define X68K_BOOT_EXECKERN_H
|
||||
|
||||
/*
|
||||
* Max number of ``sections''.
|
||||
* Currently this includes: .text, .data, size sym, Elf32_Ehdr, Elf32_Shdr x 4,
|
||||
* .shstrtab, .symtab, .strtab, .stab
|
||||
*/
|
||||
#define XK_NSEC 12
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/exec_elf.h>
|
||||
|
||||
struct execkern_arg {
|
||||
void *image_top;
|
||||
u_long load_addr;
|
||||
u_long text_size;
|
||||
u_long data_size;
|
||||
u_long bss_size;
|
||||
u_long symbol_size;
|
||||
/* Don't change this structure (see exec_sub.c). */
|
||||
u_long load_addr; /* text start address */
|
||||
|
||||
struct execkern_section {
|
||||
void *sec_image; /* section image source address */
|
||||
u_long sec_size; /* section size */
|
||||
u_long sec_pad; /* zero fill size after the image */
|
||||
} sec[XK_NSEC];
|
||||
|
||||
unsigned d5; /* reserved */
|
||||
int rootdev;
|
||||
u_long boothowto;
|
||||
u_long entry_addr;
|
||||
/* end of "Don't change this" */
|
||||
|
||||
int elfsymsiz;
|
||||
Elf32_Ehdr ehdr; /* saved ELF header */
|
||||
|
||||
#define SHSTRTAB_FAKE "\0.shstrtab\0.symtab\0.strtab\0.stab"
|
||||
#define SIZE_SHSTRTAB_FAKE_WITH_STAB 33 /* sizeof SHSTRTAB_FAKE */
|
||||
#define SIZE_SHSTRTAB_FAKE 27 /* - sizeof ".stab" */
|
||||
#define SHNAME_OFF_SHSTRTAB 1
|
||||
#define SHNAME_OFF_SYMTAB 11
|
||||
#define SHNAME_OFF_STRTAB 19
|
||||
#define SHNAME_OFF_STAB 27
|
||||
char shstrtab_fake[SIZE_SHSTRTAB_FAKE_WITH_STAB];
|
||||
};
|
||||
|
||||
int xk_load __P((struct execkern_arg *, void *, u_long));
|
||||
void __dead exec_kernel __P((struct execkern_arg *)) __attribute__((noreturn));
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* X68K_BOOT_EXECKERN_H */
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.8 2001/12/12 01:49:56 tv Exp $
|
||||
# $NetBSD: Makefile,v 1.9 2002/05/18 13:54:39 isaki Exp $
|
||||
|
||||
BASE= loadbsd
|
||||
PROG= ${BASE}.x # Human68k ".x" executable
|
||||
@ -34,7 +34,7 @@ ${PROG}: ${BASE}1 ${BASE}2
|
||||
|
||||
.for i in 1 2
|
||||
${BASE}${i}: ${OBJS} ${LIBDOS}/libdos.a ${LIBIOCS}/libiocs.a
|
||||
${CC} -o ${.TARGET} ${LDFLAGS} -Wl,-Ttext -Wl,${i}${i}000 ${OBJS} ${LDLIBS}
|
||||
${CC} -o ${.TARGET} ${LDFLAGS} -Wl,-Ttext,${i}${i}000 ${OBJS} ${LDLIBS}
|
||||
.endfor
|
||||
|
||||
.ifdef RELEASEDIR
|
||||
|
@ -19,18 +19,19 @@
|
||||
* -q quiet boot
|
||||
* -v verbose boot (also turn on verbosity of loadbsd)
|
||||
*
|
||||
* $NetBSD: loadbsd.c,v 1.7 2001/06/12 16:57:28 minoura Exp $
|
||||
* $NetBSD: loadbsd.c,v 1.8 2002/05/18 13:54:39 isaki Exp $
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__RCSID("$NetBSD: loadbsd.c,v 1.7 2001/06/12 16:57:28 minoura Exp $");
|
||||
#define VERSION "$Revision: 1.7 $ $Date: 2001/06/12 16:57:28 $"
|
||||
__RCSID("$NetBSD: loadbsd.c,v 1.8 2002/05/18 13:54:39 isaki Exp $");
|
||||
#define VERSION "$Revision: 1.8 $ $Date: 2002/05/18 13:54:39 $"
|
||||
|
||||
#include <sys/types.h> /* ntohl */
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/param.h> /* ALIGN, ALIGNBYTES */
|
||||
#include <a.out.h>
|
||||
#include <sys/exec_elf.h>
|
||||
#include <string.h>
|
||||
#include <machine/bootinfo.h>
|
||||
|
||||
@ -59,6 +60,7 @@ int main __P((int argc, char *argv[]));
|
||||
|
||||
int opt_v;
|
||||
int opt_N;
|
||||
const char *kernel_fn;
|
||||
|
||||
const struct hatbl {
|
||||
char name[4];
|
||||
@ -278,12 +280,15 @@ found: major = devtable[u].major;
|
||||
return dev;
|
||||
}
|
||||
|
||||
#define LOADBSD
|
||||
#include "../common/exec_sub.c"
|
||||
|
||||
/*
|
||||
* read kernel and create trampoline
|
||||
*
|
||||
* |----------------------| <- allocated buf addr
|
||||
* | kernel image |
|
||||
* ~ (header is excluded) ~
|
||||
* ~ (exec file contents) ~
|
||||
* | |
|
||||
* |----------------------| <- return value (entry addr of trampoline)
|
||||
* | struct tramparg |
|
||||
@ -301,12 +306,12 @@ read_kernel(fn)
|
||||
union dos_fcb *fcb;
|
||||
size_t filesize, nread;
|
||||
void *buf;
|
||||
struct exec hdr;
|
||||
int i;
|
||||
struct tramparg *arg;
|
||||
size_t size_tramp = end_trampoline - trampoline;
|
||||
|
||||
if ((fd = DOS_OPEN(fn, 0x20)) < 0) /* RO, share READ */
|
||||
kernel_fn = fn;
|
||||
|
||||
if ((fd = DOS_OPEN(fn, 0x00)) < 0) /* read only */
|
||||
xerr(1, "%s: open", fn);
|
||||
|
||||
if ((int)(fcb = DOS_GET_FCB_ADR(fd)) < 0)
|
||||
@ -322,38 +327,18 @@ read_kernel(fn)
|
||||
/*filesize = fcb->blk.size;*/
|
||||
filesize = IOCS_B_LPEEK(&fcb->blk.size);
|
||||
|
||||
/*
|
||||
* read a.out header
|
||||
*/
|
||||
if ((nread = DOS_READ(fd, (void *) &hdr, sizeof hdr)) != sizeof hdr) {
|
||||
if ((int)nread < 0)
|
||||
xerr(1, "%s: read header", fn);
|
||||
else
|
||||
xerrx(1, "%s: Not an a.out", fn);
|
||||
}
|
||||
/*
|
||||
* check header
|
||||
*/
|
||||
if (N_GETMAGIC(hdr) != NMAGIC)
|
||||
xerrx(1, "%s: Bad magic number", fn);
|
||||
if ((i = N_GETMID(hdr)) != MID_M68K)
|
||||
xerrx(1, "%s: Wrong architecture (mid %d)", fn, i);
|
||||
|
||||
if (opt_v)
|
||||
xwarnx("%s: %u bytes; text %u, data %u, bss %u, sym %u",
|
||||
fn, filesize, hdr.a_text, hdr.a_data,
|
||||
hdr.a_bss, hdr.a_syms);
|
||||
if (filesize < sizeof(Elf32_Ehdr))
|
||||
xerrx(1, "%s: Unknown format", fn);
|
||||
|
||||
/*
|
||||
* then, read entire body
|
||||
* read entire file
|
||||
*/
|
||||
if ((int)(buf = DOS_MALLOC(filesize + ALIGNBYTES - sizeof hdr
|
||||
if ((int)(buf = DOS_MALLOC(filesize + ALIGNBYTES
|
||||
+ sizeof(struct tramparg)
|
||||
+ size_tramp + SIZE_TMPSTACK)) < 0)
|
||||
xerr(1, "read_kernel");
|
||||
|
||||
if ((nread = DOS_READ(fd, buf, filesize - sizeof hdr))
|
||||
!= filesize - sizeof hdr) {
|
||||
if ((nread = DOS_READ(fd, buf, filesize)) != filesize) {
|
||||
if ((int)nread < 0)
|
||||
xerr(1, "%s: read", fn);
|
||||
else
|
||||
@ -364,35 +349,34 @@ read_kernel(fn)
|
||||
xerr(1, "%s: close", fn);
|
||||
|
||||
/*
|
||||
* create argument for trampoline code
|
||||
* address for argument for trampoline code
|
||||
*/
|
||||
arg = (struct tramparg *) ALIGN(buf + nread);
|
||||
arg = (struct tramparg *) ALIGN((char *) buf + nread);
|
||||
|
||||
if (opt_v)
|
||||
xwarnx("trampoline arg at %p", arg);
|
||||
|
||||
xk_load(&arg->xk, buf, 0 /* XXX load addr should not be fixed */);
|
||||
|
||||
/*
|
||||
* create argument for trampoline code
|
||||
*/
|
||||
arg->bsr_inst = TRAMP_BSR + sizeof(struct tramparg) - 2;
|
||||
arg->tmp_stack = (char *) arg + sizeof(struct tramparg)
|
||||
+ size_tramp + SIZE_TMPSTACK;
|
||||
arg->mpu_type = IOCS_MPU_STAT() & 0xff;
|
||||
arg->xk.image_top = buf;
|
||||
arg->xk.load_addr = 0x00000000; /* XXX should not be a fixed addr */
|
||||
arg->xk.text_size = hdr.a_text;
|
||||
arg->xk.data_size = hdr.a_data;
|
||||
arg->xk.bss_size = hdr.a_bss;
|
||||
arg->xk.symbol_size = hdr.a_syms;
|
||||
|
||||
arg->xk.d5 = IOCS_BOOTINF(); /* unused for now */
|
||||
#if 0
|
||||
/* filled afterwards */
|
||||
arg->xk.rootdev =
|
||||
arg->xk.boothowto =
|
||||
#endif
|
||||
arg->xk.entry_addr = hdr.a_entry;
|
||||
|
||||
if (opt_v)
|
||||
xwarnx("args: mpu %d, image %p, load 0x%x, entry 0x%x",
|
||||
arg->mpu_type, arg->xk.image_top, arg->xk.load_addr,
|
||||
arg->xk.entry_addr);
|
||||
arg->mpu_type, arg->xk.sec[0].sec_image,
|
||||
arg->xk.load_addr, arg->xk.entry_addr);
|
||||
|
||||
/*
|
||||
* copy trampoline code
|
||||
|
Loading…
Reference in New Issue
Block a user