bootst: from Dale Rahn.
This commit is contained in:
parent
008b8c0664
commit
62a58e8eaa
|
@ -0,0 +1,39 @@
|
||||||
|
# from: @(#)Makefile 8.1 (Berkeley) 6/10/93
|
||||||
|
# $OpenBSD$
|
||||||
|
|
||||||
|
RELOC=0x3F0000
|
||||||
|
|
||||||
|
S= ${.CURDIR}/../../../..
|
||||||
|
DEFS=
|
||||||
|
INCPATH=-I${.CURDIR} -I${.CURDIR}/../libsa -I${.CURDIR}/../libbug \
|
||||||
|
-I${.CURDIR}/../../include -I${S} -I${S}/lib/libsa
|
||||||
|
CFLAGS= -O2 ${INCPATH} ${DEFS} ${COPTS}
|
||||||
|
CLEANFILES+=stboot bootst bootst.bug
|
||||||
|
|
||||||
|
.include "${S}/arch/${MACHINE}/stand/libsa/Makefile.inc"
|
||||||
|
.include "${S}/arch/${MACHINE}/stand/libbug/Makefile.inc"
|
||||||
|
.include "${S}/arch/${MACHINE}/stand/bugcrt/Makefile.inc"
|
||||||
|
.include "${S}/arch/${MACHINE}/stand/wrtvid/Makefile.inc"
|
||||||
|
|
||||||
|
SRCS= bootst.c
|
||||||
|
|
||||||
|
LIBS= ${LIBSA} ${LIBBUG}
|
||||||
|
|
||||||
|
OBJS= ${SRCS:N*.h:R:S/$/.o/g}
|
||||||
|
|
||||||
|
BOOTS= bootst stboot
|
||||||
|
ALL= ${BOOTS}
|
||||||
|
|
||||||
|
all: ${ALL}
|
||||||
|
|
||||||
|
bootst.bug: ${OBJS} ${BUGCRT} ${LIBS}
|
||||||
|
${LD} -s -N -T ${RELOC} ${BUGCRT} ${OBJS} ${LIBS} -o $@
|
||||||
|
@size bootst.bug
|
||||||
|
|
||||||
|
bootst stboot: bootst.bug ${WRTVID}
|
||||||
|
${WRTVID} bootst.bug
|
||||||
|
|
||||||
|
install:
|
||||||
|
install -c -m 555 -g bin -o bin ${BOOTS} ${DESTDIR}${MDEC_DIR}
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
|
@ -0,0 +1,315 @@
|
||||||
|
/* $OpenBSD$ */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/reboot.h>
|
||||||
|
#include <sys/exec.h>
|
||||||
|
#include <machine/prom.h>
|
||||||
|
|
||||||
|
#include "stand.h"
|
||||||
|
#include "libsa.h"
|
||||||
|
|
||||||
|
int load_kern();
|
||||||
|
int read_tape_block __P((short ctrl, short dev, short *status,
|
||||||
|
void *addr, int *cnt, int blk_num, u_char *flags, int verbose));
|
||||||
|
|
||||||
|
struct kernel {
|
||||||
|
void *entry;
|
||||||
|
void *symtab;
|
||||||
|
void *esym;
|
||||||
|
int bflags;
|
||||||
|
int bdev;
|
||||||
|
char *kname;
|
||||||
|
void *smini;
|
||||||
|
void *emini;
|
||||||
|
u_int end_loaded;
|
||||||
|
} kernel;
|
||||||
|
|
||||||
|
typedef(*kernel_entry) __P((struct mvmeprom_args *, struct kernel *));
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
kernel_entry addr;
|
||||||
|
struct mvmeprom_args *pbugargs;
|
||||||
|
|
||||||
|
pbugargs = &bugargs;
|
||||||
|
/*
|
||||||
|
print_bugargs(pbugargs);
|
||||||
|
print_time();
|
||||||
|
print_brdid();
|
||||||
|
print_memory();
|
||||||
|
*/
|
||||||
|
parse_args(&kernel.kname, &kernel.bflags);
|
||||||
|
if (load_kern(pbugargs) == 1) {
|
||||||
|
printf("unsuccessful in loading kernel\n");
|
||||||
|
} else {
|
||||||
|
addr = kernel.entry;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("kernel loaded at %x\n", addr);
|
||||||
|
printf("kernel.entry %x\n", kernel.entry);
|
||||||
|
printf("kernel.symtab %x\n", kernel.symtab);
|
||||||
|
printf("kernel.esym %x\n", kernel.esym);
|
||||||
|
printf("kernel.bflags %x\n", kernel.bflags);
|
||||||
|
printf("kernel.bdev %x\n", kernel.bdev);
|
||||||
|
if (kernel.kname)
|
||||||
|
printf("kernel.kname <%s>\n", kernel.kname);
|
||||||
|
else
|
||||||
|
printf("kernel.kname <null>\n");
|
||||||
|
printf("kernel.end_loaded %x\n", kernel.end_loaded);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (kernel.bflags & RB_MINIROOT)
|
||||||
|
loadmini(kernel.end_loaded, pbugargs);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("kernel.smini %x\n", kernel.smini);
|
||||||
|
printf("kernel.emini %x\n", kernel.emini);
|
||||||
|
printf("kernel.end_loaded %x\n", kernel.end_loaded);
|
||||||
|
#endif
|
||||||
|
if (kernel.bflags & RB_HALT)
|
||||||
|
_rtt();
|
||||||
|
if (((u_long)addr &0xf) == 0x2) {
|
||||||
|
(addr)(pbugargs, &kernel);
|
||||||
|
} else {
|
||||||
|
/* is type fixing anything like price fixing? */
|
||||||
|
typedef (* kernel_start) __P((int, int, void *,void *, void *));
|
||||||
|
kernel_start addr1;
|
||||||
|
addr1 = (void *)addr;
|
||||||
|
(addr1)(kernel.bflags, 0, kernel.esym, kernel.smini, kernel.emini
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MVMEPROM_SCALE (512/MVMEPROM_BLOCK_SIZE)
|
||||||
|
|
||||||
|
int
|
||||||
|
read_tape_block(ctrl, dev, status, addr, cnt, blk_num, flags, verbose)
|
||||||
|
short ctrl;
|
||||||
|
short dev;
|
||||||
|
short *status;
|
||||||
|
void *addr;
|
||||||
|
int *cnt;
|
||||||
|
int blk_num;
|
||||||
|
u_char *flags;
|
||||||
|
int verbose;
|
||||||
|
{
|
||||||
|
struct mvmeprom_dskio dio;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
dio.ctrl_lun = ctrl;
|
||||||
|
dio.dev_lun = dev;
|
||||||
|
dio.status = *status;
|
||||||
|
dio.pbuffer = addr;
|
||||||
|
dio.blk_num = blk_num;
|
||||||
|
dio.blk_cnt = *cnt / (512 / MVMEPROM_SCALE);
|
||||||
|
dio.flag = *flags;
|
||||||
|
dio.addr_mod = 0;
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
printf("saddr %x eaddr %x", dio.pbuffer,
|
||||||
|
(int) dio.pbuffer + (dio.blk_cnt * MVMEPROM_BLOCK_SIZE));
|
||||||
|
ret = mvmeprom_diskrd(&dio);
|
||||||
|
|
||||||
|
*status = dio.status;
|
||||||
|
*cnt = (dio.blk_cnt / MVMEPROM_SCALE) * 512;
|
||||||
|
if (verbose) {
|
||||||
|
printf("status %x ret %d ", *status, ret);
|
||||||
|
printf("flags %x blocks read %x cnt %x\n",
|
||||||
|
*flags, dio.blk_cnt, *cnt);
|
||||||
|
}
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
int verbose = 1;
|
||||||
|
#else
|
||||||
|
int verbose = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int
|
||||||
|
load_kern(pbugargs)
|
||||||
|
struct mvmeprom_args *pbugargs;
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *addr;
|
||||||
|
u_char flags;
|
||||||
|
short status = 0;
|
||||||
|
int blk_num;
|
||||||
|
struct exec *pexec;
|
||||||
|
int magic;
|
||||||
|
int *esym;
|
||||||
|
int *symtab;
|
||||||
|
int cnt, len;
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
blk_num = 2;
|
||||||
|
/* flags = IGNORE_FILENUM; */
|
||||||
|
flags = 0;
|
||||||
|
cnt = 512;
|
||||||
|
ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun, &status,
|
||||||
|
buf, &cnt, blk_num, &flags, verbose);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("unable to load kernel 1 status %x\n", status);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
pexec = (struct exec *) buf;
|
||||||
|
if (N_GETMID(*pexec) != MID_M68K &&
|
||||||
|
N_GETMID(*pexec) != MID_M68K4K) {
|
||||||
|
printf("invalid mid on kernel\n");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
magic = N_GETMAGIC(*pexec);
|
||||||
|
switch (magic) {
|
||||||
|
case ZMAGIC:
|
||||||
|
break;
|
||||||
|
case NMAGIC:
|
||||||
|
printf("NMAGIC not yet supported");
|
||||||
|
case OMAGIC:
|
||||||
|
case QMAGIC:
|
||||||
|
default:
|
||||||
|
printf("Unknown or unsupported magic type <%x>\n", magic);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
if (magic == ZMAGIC) {
|
||||||
|
status = 0;
|
||||||
|
addr = (char *) (pexec->a_entry & ~0x0FFF);
|
||||||
|
|
||||||
|
bcopy(&buf, addr, 512);
|
||||||
|
/* 2nd block of exe */
|
||||||
|
addr += 512;
|
||||||
|
|
||||||
|
printf("text 0x%x data 0x%x bss 0x%x\n",
|
||||||
|
pexec->a_text, pexec->a_data, pexec->a_bss);
|
||||||
|
|
||||||
|
len = (pexec->a_text - 512); /* XXX */
|
||||||
|
len += (pexec->a_data);
|
||||||
|
|
||||||
|
printf("loading [ %x + %x ", pexec->a_text, pexec->a_data);
|
||||||
|
|
||||||
|
cnt = len;
|
||||||
|
flags = IGNORE_FILENUM;
|
||||||
|
ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun,
|
||||||
|
&status, addr, &cnt, blk_num, &flags, verbose);
|
||||||
|
if (ret != 0 || cnt != len) {
|
||||||
|
printf("unable to load kernel 2 status %x\n", status);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
addr += len;
|
||||||
|
|
||||||
|
/* Skip over text and data and zero bss. */
|
||||||
|
len = pexec->a_bss;
|
||||||
|
printf("+ %x", len);
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("bss %x - %x\n", addr, addr + pexec->a_bss);
|
||||||
|
#endif
|
||||||
|
bzero(addr, pexec->a_bss);
|
||||||
|
addr += len;
|
||||||
|
|
||||||
|
if (pexec->a_syms != 0 && !(kernel.bflags & RB_NOSYM)) {
|
||||||
|
printf(" + [ %x", pexec->a_syms);
|
||||||
|
addr += 4; /* skip over _end symbol */
|
||||||
|
symtab = (void *) pexec->a_syms;
|
||||||
|
len = pexec->a_syms;
|
||||||
|
cnt = ((len + (512 - 1)) / 512) * 512;
|
||||||
|
flags = IGNORE_FILENUM;
|
||||||
|
ret = read_tape_block(pbugargs->ctrl_lun,
|
||||||
|
pbugargs->dev_lun, &status, addr,
|
||||||
|
&cnt, blk_num, &flags, verbose);
|
||||||
|
if (ret != 0 || cnt != ((len + (512 - 1)) / 512) * 512) {
|
||||||
|
printf("unable to load kernel 3\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* this value should have already been loaded XXX */
|
||||||
|
esym = (void *) ((u_int) addr + pexec->a_syms);
|
||||||
|
if ((int) addr + cnt <= (int) esym) {
|
||||||
|
printf("missed loading count of symbols\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
addr += cnt;
|
||||||
|
|
||||||
|
|
||||||
|
len = *esym;
|
||||||
|
#if 0
|
||||||
|
printf("start load %x end load %x %x\n", addr,
|
||||||
|
len, addr + len);
|
||||||
|
printf("esym %x *esym %x\n", esym, len);
|
||||||
|
#endif
|
||||||
|
/* dont load tail of already loaded */
|
||||||
|
len -= (u_int) addr - (u_int) esym;
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
printf(" + %x", *esym);
|
||||||
|
esym = (void *) (addr + len);
|
||||||
|
cnt = ((len + (512 - 1)) / 512) * 512;
|
||||||
|
flags = IGNORE_FILENUM;
|
||||||
|
ret = read_tape_block(pbugargs->ctrl_lun,
|
||||||
|
pbugargs->dev_lun, &status, addr,
|
||||||
|
&cnt, blk_num, &flags, verbose);
|
||||||
|
if (ret != 0 || cnt != ((len + (512-1)) / 512)*512) {
|
||||||
|
printf("unable to load kernel 4\n");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
addr += len;
|
||||||
|
printf(" ]");
|
||||||
|
} else {
|
||||||
|
printf("+ %x ]", *esym);
|
||||||
|
}
|
||||||
|
esym = (int *) (((int) esym) + *esym);
|
||||||
|
|
||||||
|
kernel.symtab = symtab;
|
||||||
|
kernel.esym = esym;
|
||||||
|
} else {
|
||||||
|
kernel.symtab = 0;
|
||||||
|
kernel.esym = 0;
|
||||||
|
}
|
||||||
|
kernel.end_loaded = (int) addr;
|
||||||
|
flags = IGNORE_FILENUM | END_OF_FILE;
|
||||||
|
cnt = 8192;
|
||||||
|
printf("removing pad [");
|
||||||
|
ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun,
|
||||||
|
&status, addr, &cnt, blk_num, &flags, verbose);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("unable to load kernel 5\n");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
printf(" %d ]", cnt);
|
||||||
|
|
||||||
|
printf("]\n");
|
||||||
|
}
|
||||||
|
kernel.entry = (void *) pexec->a_entry;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
loadmini(addr, pbugargs)
|
||||||
|
u_int addr;
|
||||||
|
struct mvmeprom_args *pbugargs;
|
||||||
|
{
|
||||||
|
int cnt, ret, blk_num = 3;
|
||||||
|
short status = 0;
|
||||||
|
u_char flags;
|
||||||
|
|
||||||
|
/* align addr to some boundary */
|
||||||
|
#define ALIGN_F 0x4
|
||||||
|
addr = (u_int) ((((int) addr + ALIGN_F - 1) / ALIGN_F) * ALIGN_F);
|
||||||
|
#undef ALIGN_F
|
||||||
|
flags = END_OF_FILE;
|
||||||
|
cnt = 6144 * 512; /* some abserdly large value. (3meg) */
|
||||||
|
printf("loading miniroot[ ");
|
||||||
|
ret = read_tape_block(pbugargs->ctrl_lun, pbugargs->dev_lun,
|
||||||
|
&status, (void *) addr, &cnt, blk_num, &flags, verbose);
|
||||||
|
if (ret != 0) {
|
||||||
|
printf("unable to load miniroot\n");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
kernel.smini = (void *)addr;
|
||||||
|
printf("%d ]\n", cnt);
|
||||||
|
kernel.emini = (void *) ((u_int) addr + cnt);
|
||||||
|
kernel.end_loaded = (u_int) kernel.emini;
|
||||||
|
return (0);
|
||||||
|
}
|
Loading…
Reference in New Issue