bootst: from Dale Rahn.

This commit is contained in:
chuck 1996-05-17 20:06:45 +00:00
parent 008b8c0664
commit 62a58e8eaa
2 changed files with 354 additions and 0 deletions

View File

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

View File

@ -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);
}