157081Sakito /*
257081Sakito * Copyright (c) 1992 OMRON Corporation.
3*63199Sbostic * Copyright (c) 1992, 1993
4*63199Sbostic * The Regents of the University of California. All rights reserved.
557081Sakito *
657081Sakito * This code is derived from software contributed to Berkeley by
757081Sakito * OMRON Corporation.
857081Sakito *
957081Sakito * %sccs.include.redist.c%
1057081Sakito *
11*63199Sbostic * @(#)boot.c 8.1 (Berkeley) 06/10/93
1257081Sakito */
1357081Sakito
1457081Sakito /*
1557081Sakito * boot.c -- boot program
1657081Sakito * by A.Fujita, MAR-01-1992
1757081Sakito */
1857081Sakito
1957081Sakito #include <sys/param.h>
2057081Sakito #include <sys/reboot.h>
2157081Sakito #include <sys/exec.h>
2257081Sakito #include <machine/stinger.h>
2357081Sakito #include <luna68k/stand/saio.h>
2457081Sakito #include <luna68k/stand/status.h>
2557081Sakito
2657081Sakito extern struct KernInter *kiff;
2757081Sakito
2857081Sakito int howto;
2957518Sakito int devtype = MAKEBOOTDEV(4, 0, 6, 0, 0);
3057081Sakito
3157081Sakito char *copyunix();
3257081Sakito
3357081Sakito struct exec header;
3457081Sakito char default_file[] = "sd(0,0)vmunix";
3557081Sakito
3657081Sakito char *how_to_info[] = {
3757081Sakito "RB_ASKNAME ask for file name to reboot from",
3857081Sakito "RB_SINGLE reboot to single user only",
3957081Sakito "RB_NOSYNC dont sync before reboot",
4057081Sakito "RB_HALT don't reboot, just halt",
4157081Sakito "RB_INITNAME name given for /etc/init (unused)",
4257081Sakito "RB_DFLTROOT use compiled-in rootdev",
4357081Sakito "RB_KDB give control to kernel debugger",
4457081Sakito "RB_RDONLY mount root fs read-only"
4557081Sakito };
4657081Sakito
4759955Sakito #define TAPE
4859955Sakito #ifdef TAPE /* A.Kojima */
4959955Sakito extern dev_t rst0;
5059955Sakito extern dev_t nrst0;
5159955Sakito char *stcopyunix();
5259955Sakito #endif
5359955Sakito
5457081Sakito int
how_to_boot(argc,argv)5557081Sakito how_to_boot(argc, argv)
5657081Sakito int argc;
5757081Sakito char *argv[];
5857081Sakito {
5957081Sakito int i, h = howto;
6057081Sakito
6157081Sakito if (argc < 2) {
6257081Sakito printf("howto: 0x%s\n\n", hexstr(howto, 2));
6357081Sakito
6457081Sakito if (h == 0) {
6557081Sakito printf("\t%s\n", "RB_AUTOBOOT flags for system auto-booting itself");
6657081Sakito } else {
6757081Sakito for (i = 0; i < 8; i++, h >>= 1) {
6857081Sakito if (h & 0x01) {
6957081Sakito printf("\t%s\n", how_to_info[i]);
7057081Sakito }
7157081Sakito }
7257081Sakito }
7357081Sakito
7457081Sakito printf("\n");
7557081Sakito }
7657081Sakito }
7757081Sakito
7857081Sakito int
get_boot_device(s)7957518Sakito get_boot_device(s)
8057518Sakito char *s;
8157518Sakito {
8257518Sakito register int unit = 0;
8357518Sakito register int part = 0;
8457518Sakito register char *p = s;
8557518Sakito
8657518Sakito while (*p != '(') {
8757518Sakito if (*p == '\0')
8857518Sakito goto error;
8957518Sakito p++;
9057518Sakito }
9157518Sakito
9257518Sakito while (*++p != ',') {
9357518Sakito if (*p == '\0')
9457518Sakito goto error;
9557518Sakito if (*p >= '0' && *p <= '9')
9657518Sakito unit = (unit * 10) + (*p - '0');
9757518Sakito }
9857518Sakito
9957518Sakito while (*++p != ')') {
10057518Sakito if (*p == '\0')
10157518Sakito goto error;
10257518Sakito if (*p >= '0' && *p <= '9')
10357518Sakito part = (part * 10) + (*p - '0');
10457518Sakito }
10557518Sakito
10657518Sakito return(MAKEBOOTDEV(4, 0, (6 - unit), unit, part));
10757518Sakito
10857518Sakito error:
10957518Sakito return(MAKEBOOTDEV(4, 0, 6, 0, 0));
11057518Sakito }
11157518Sakito
11257518Sakito int
boot(argc,argv)11357081Sakito boot(argc, argv)
11457081Sakito int argc;
11557081Sakito char *argv[];
11657081Sakito {
11757081Sakito register int io;
11857081Sakito char *line;
11957081Sakito
12057081Sakito if (argc < 2)
12157081Sakito line = default_file;
12257081Sakito else
12357081Sakito line = argv[1];
12457081Sakito
12557518Sakito devtype = get_boot_device(line);
12657518Sakito
12757081Sakito printf("Booting %s\n", line);
12857081Sakito
12959955Sakito #ifdef TAPE /* A.Kojima */
13059955Sakito if (!strcmp("st", argv[1])) {
13159955Sakito io = argc < 3 ? 0 : *argv[2] - '0';
13259955Sakito printf("boot tape file number:%d\n", io);
13359955Sakito stbootunix(howto, devtype, io);
13459955Sakito return;
13559955Sakito }
13659955Sakito #endif
13757081Sakito io = open(line, 0);
13857081Sakito if (io >= 0) {
13957081Sakito bootunix(howto, devtype, io);
14057081Sakito close(io);
14157081Sakito }
14257081Sakito }
14357081Sakito
14457081Sakito int
load(argc,argv)14557081Sakito load(argc, argv)
14657081Sakito int argc;
14757081Sakito char *argv[];
14857081Sakito {
14957081Sakito register int io;
15057081Sakito char *line;
15157081Sakito
15257081Sakito if (argc < 2)
15357081Sakito line = default_file;
15457081Sakito else
15557081Sakito line = argv[1];
15657081Sakito
15757081Sakito printf("loading %s\n", line);
15857081Sakito
15957081Sakito io = open(line, 0);
16057081Sakito if (io >= 0) {
16157081Sakito copyunix(io);
16257081Sakito printf("\n");
16357081Sakito close(io);
16457081Sakito }
16557081Sakito }
16657081Sakito
16757081Sakito int
bootunix(howto,devtype,io)16857081Sakito bootunix(howto, devtype, io)
16957081Sakito register howto; /* d7 contains boot flags */
17057081Sakito register devtype; /* d6 contains boot device */
17157081Sakito register io;
17257081Sakito {
17357081Sakito register char *load; /* a5 contains load addr for unix */
17457081Sakito
17557081Sakito load = copyunix(io);
17657081Sakito
17757081Sakito printf(" start 0x%x\n", load);
17857081Sakito asm(" movl %0,d7" : : "d" (howto));
17957081Sakito asm(" movl %0,d6" : : "d" (devtype));
18057081Sakito asm(" movl %0,a5" : : "a" (kiff));
18157081Sakito (*((int (*)()) load))();
18257081Sakito }
18357081Sakito
18457081Sakito char *
copyunix(io)18557081Sakito copyunix(io)
18657081Sakito register io;
18757081Sakito {
18857081Sakito
18957081Sakito register int i;
19057081Sakito register char *load; /* a5 contains load addr for unix */
19157081Sakito register char *addr;
19257081Sakito
19357081Sakito /*
19457081Sakito * Read a.out file header
19557081Sakito */
19657081Sakito
19757081Sakito i = read(io, (char *)&header, sizeof(struct exec));
19857081Sakito if (i != sizeof(struct exec) ||
19957081Sakito (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) {
20057081Sakito printf("illegal magic number ... 0x%x\n");
20157081Sakito printf("Bad format\n");
20257081Sakito return(0);
20357081Sakito }
20457081Sakito
20557081Sakito load = addr = (char *) (header.a_entry & 0x00FFFFFF);
20657081Sakito
20757081Sakito printf("%d", header.a_text);
20857081Sakito if (header.a_magic == 0413 && lseek(io, 0x400, 0) == -1)
20957081Sakito goto shread;
21057081Sakito
21157081Sakito /*
21257081Sakito * Load TEXT Segment
21357081Sakito */
21457081Sakito
21557081Sakito if (read(io, (char *)addr, header.a_text) != header.a_text)
21657081Sakito goto shread;
21757081Sakito addr += header.a_text;
21857081Sakito if (header.a_magic == 0413 || header.a_magic == 0410)
21957081Sakito while ((int)addr & CLOFSET)
22057081Sakito *addr++ = 0;
22157081Sakito
22257081Sakito /*
22357081Sakito * Load DATA Segment
22457081Sakito */
22557081Sakito
22657081Sakito printf("+%d", header.a_data);
22757081Sakito if (read(io, addr, header.a_data) != header.a_data)
22857081Sakito goto shread;
22957081Sakito
23057081Sakito /*
23157081Sakito * Clear BSS Segment
23257081Sakito */
23357081Sakito
23457081Sakito addr += header.a_data;
23557081Sakito printf("+%d", header.a_bss);
23657081Sakito header.a_bss += 128*512; /* slop */
23757081Sakito for (i = 0; i < header.a_bss; i++)
23857081Sakito *addr++ = 0;
23957081Sakito
24057081Sakito return(load);
24157081Sakito
24257081Sakito shread:
24357081Sakito printf(" Short read\n");
24457081Sakito return(0);
24557081Sakito }
24657081Sakito
24759955Sakito #ifdef TAPE /* A.Kojima */
24859955Sakito int
stbootunix(howto,devtype,skip)24959955Sakito stbootunix(howto, devtype, skip)
25059955Sakito register howto; /* d7 contains boot flags */
25159955Sakito register devtype; /* d6 contains boot device */
25259955Sakito register skip; /* tape skip */
25359955Sakito {
25459955Sakito register int i;
25559955Sakito register char *load; /* a5 contains load addr for unix */
25659955Sakito
25759955Sakito /*
25859955Sakito * Tape rewind and skip
25959955Sakito */
26059955Sakito st_rewind(rst0);
26159955Sakito for (i = 0; i < skip; i++) {
26259955Sakito st_skip(rst0);
26359955Sakito }
26459955Sakito
26559955Sakito load = stcopyunix();
26659955Sakito
26759955Sakito st_rewind(rst0);
26859955Sakito
26959955Sakito printf(" start 0x%x\n", load);
27059955Sakito asm(" movl %0,d7" : : "d" (howto));
27159955Sakito asm(" movl %0,d6" : : "d" (devtype));
27259955Sakito asm(" movl %0,a5" : : "a" (kiff));
27359955Sakito (*((int (*)()) load))();
27459955Sakito }
27559955Sakito
27659955Sakito char *
stcopyunix()27759955Sakito stcopyunix()
27859955Sakito {
27959955Sakito
28059955Sakito register int i;
28159955Sakito register char *load; /* a5 contains load addr for unix */
28259955Sakito register char *addr;
28359955Sakito u_char buf[0x400];
28459955Sakito
28559955Sakito /*
28659955Sakito * Read a.out file header
28759955Sakito */
28859955Sakito
28959955Sakito i = tread(/*io,*/ (char *)&header, sizeof(struct exec));
29059955Sakito if (i != sizeof(struct exec) ||
29159955Sakito (header.a_magic != 0407 && header.a_magic != 0413 && header.a_magic != 0410)) {
29259955Sakito printf("illegal magic number ... 0x%x\n");
29359955Sakito printf("Bad format\n");
29459955Sakito return(0);
29559955Sakito }
29659955Sakito
29759955Sakito load = addr = (char *) (header.a_entry & 0x00FFFFFF);
29859955Sakito
29959955Sakito printf("%d", header.a_text);
30059955Sakito
30159955Sakito i = 0x400 - i;
30259955Sakito if (header.a_magic == 0413 && tread(buf, i) != i) { /* easy seek */
30359955Sakito goto shread;
30459955Sakito }
30559955Sakito
30659955Sakito /*
30759955Sakito * Load TEXT Segment
30859955Sakito */
30959955Sakito
31059955Sakito if (tread(/*io,*/ (char *)addr, header.a_text) != header.a_text)
31159955Sakito goto shread;
31259955Sakito addr += header.a_text;
31359955Sakito if (header.a_magic == 0413 || header.a_magic == 0410)
31459955Sakito while ((int)addr & CLOFSET)
31559955Sakito *addr++ = 0;
31659955Sakito
31759955Sakito /*
31859955Sakito * Load DATA Segment
31959955Sakito */
32059955Sakito
32159955Sakito printf("+%d", header.a_data);
32259955Sakito if (tread(/*io,*/ addr, header.a_data) != header.a_data)
32359955Sakito goto shread;
32459955Sakito
32559955Sakito /*
32659955Sakito * Clear BSS Segment
32759955Sakito */
32859955Sakito
32959955Sakito addr += header.a_data;
33059955Sakito printf("+%d", header.a_bss);
33159955Sakito header.a_bss += 128*512; /* slop */
33259955Sakito for (i = 0; i < header.a_bss; i++)
33359955Sakito *addr++ = 0;
33459955Sakito
33559955Sakito return(load);
33659955Sakito
33759955Sakito shread:
33859955Sakito printf(" Short read\n");
33959955Sakito return(0);
34059955Sakito }
34159955Sakito
34259955Sakito int
tread(addr,size)34359955Sakito tread(addr, size)
34459955Sakito int addr;
34559955Sakito int size;
34659955Sakito {
34759955Sakito static u_char buf[512];
34859955Sakito static int head = 512;
34959955Sakito static int tail = 512;
35059955Sakito int req_size = size;
35159955Sakito int rest = tail - head;
35259955Sakito
35359955Sakito if (rest > 0) {
35459955Sakito if (size <= rest) {
35559955Sakito bcopy(&buf[head], addr, size);
35659955Sakito head += size;
35759955Sakito return size;
35859955Sakito } else { /* size > rest */
35959955Sakito bcopy(&buf[head], addr, rest);
36059955Sakito addr += rest;
36159955Sakito size -= rest;
36259955Sakito if (tail != 512) {
36359955Sakito head = 512;
36459955Sakito tail = 512;
36559955Sakito printf("tread() EOF 0\n");
36659955Sakito return rest;
36759955Sakito }
36859955Sakito }
36959955Sakito }
37059955Sakito
37159955Sakito /* head = 0; */
37259955Sakito
37359955Sakito while (size > 512) {
37459955Sakito if ((tail = stread(rst0, addr, 512)) == 512) {
37559955Sakito addr += 512;
37659955Sakito size -= 512;
37759955Sakito } else { /* eof ( tail < 512 ) */
37859955Sakito size -= tail;
37959955Sakito head = tail;
38059955Sakito printf("tread() EOF 1\n");
38159955Sakito return req_size - size;
38259955Sakito }
38359955Sakito }
38459955Sakito tail = stread(rst0, buf, 512);
38559955Sakito if (tail >= size) {
38659955Sakito bcopy(buf, addr, size);
38759955Sakito head = size;
38859955Sakito return req_size;
38959955Sakito } else {
39059955Sakito bcopy(buf, addr, tail);
39159955Sakito head = tail;
39259955Sakito printf("tread() EOF 2\n");
39359955Sakito return req_size - size;
39459955Sakito }
39559955Sakito }
39659955Sakito
39759955Sakito #endif
39859955Sakito
399