diff options
author | Steve Murphree <smurph@cvs.openbsd.org> | 1999-09-26 18:05:33 +0000 |
---|---|---|
committer | Steve Murphree <smurph@cvs.openbsd.org> | 1999-09-26 18:05:33 +0000 |
commit | 1eecb4fff72d38e1345f61f90436020bc5c4f538 (patch) | |
tree | 5a74dde5e77966d13eb38e2c22b54ad3f023104d /sys/arch/mvme68k | |
parent | a2fad63b3549759e52150b633a03cc894f40a474 (diff) |
This fixes installboot.
Diffstat (limited to 'sys/arch/mvme68k')
-rw-r--r-- | sys/arch/mvme68k/stand/installboot/Makefile | 7 | ||||
-rw-r--r-- | sys/arch/mvme68k/stand/installboot/installboot.c | 107 |
2 files changed, 107 insertions, 7 deletions
diff --git a/sys/arch/mvme68k/stand/installboot/Makefile b/sys/arch/mvme68k/stand/installboot/Makefile index cf7ec2e29ce..c6d8145831e 100644 --- a/sys/arch/mvme68k/stand/installboot/Makefile +++ b/sys/arch/mvme68k/stand/installboot/Makefile @@ -1,12 +1,15 @@ -# $NetBSD: Makefile,v 1.4 1995/10/08 23:44:02 gwr Exp $ +# $OpenBSD: Makefile,v 1.3 1999/09/26 18:05:32 smurph Exp $ PROG= installboot MAN= installboot.8 MANSUBDIR=/mvme68k BINDIR=/usr/mdec +DPADD=${LIBUTIL} +LDADD=-lutil # Need this to work in the miniroot -LDSTATIC= -static + +LDSTATIC=-static .include <bsd.prog.mk> diff --git a/sys/arch/mvme68k/stand/installboot/installboot.c b/sys/arch/mvme68k/stand/installboot/installboot.c index 88244cb41ba..ad853175a69 100644 --- a/sys/arch/mvme68k/stand/installboot/installboot.c +++ b/sys/arch/mvme68k/stand/installboot/installboot.c @@ -45,9 +45,13 @@ #include <stdio.h> #include <string.h> #include <unistd.h> +#include <util.h> +#include <machine/disklabel.h> int verbose, nowrite, hflag; char *boot, *proto, *dev; +char cdev[80]; + struct nlist nl[] = { #define X_BLOCK_SIZE 0 {"_block_size"}, @@ -69,6 +73,7 @@ int loadblocknums __P((char *, int)); static void devread __P((int, void *, daddr_t, size_t, char *)); static void usage __P((void)); int main __P((int, char *[])); +static void vid_to_disklabel __P((char *, char*)); static void @@ -115,13 +120,19 @@ main(argc, argv) boot = argv[optind]; proto = argv[optind + 1]; dev = argv[optind + 2]; - + strcpy(cdev, dev); + cdev[strlen(cdev)-1] = 'c'; + if (verbose) { printf("boot: %s\n", boot); printf("proto: %s\n", proto); printf("device: %s\n", dev); + printf("cdevice: %s\n", cdev); } - + + /* Insert VID into disklabel */ + vid_to_disklabel(cdev, proto); + /* Load proto blocks into core */ if ((protostore = loadprotoblocks(proto, &protosize)) == NULL) exit(1); @@ -147,7 +158,7 @@ main(argc, argv) if (protosize > SBSIZE - DEV_BSIZE) errx(1, "proto bootblocks too big"); - if ((devfd = open(dev, O_RDWR, 0)) < 0) + if ((devfd = open(cdev, O_RDWR, 0)) < 0) err(1, "open: %s", dev); if (lseek(devfd, DEV_BSIZE, SEEK_SET) != DEV_BSIZE) @@ -320,9 +331,11 @@ int devfd; fs = (struct fs *)sblock; /* Sanity-check super-block. */ - if (fs->fs_magic != FS_MAGIC) + + if (fs->fs_magic != FS_MAGIC) errx(1, "Bad magic number in superblock"); - if (fs->fs_inopb <= 0) + + if (fs->fs_inopb <= 0) err(1, "Bad inopb=%d in superblock", fs->fs_inopb); /* Read inode */ @@ -375,3 +388,87 @@ int devfd; return 0; } +static void +vid_to_disklabel(dkname, bootproto) +char *dkname; +char *bootproto; +{ + char *specname; + int exe_file, f; + struct cpu_disklabel *pcpul; + struct stat stat; + unsigned int exe_addr; + unsigned short exe_addr_u; + unsigned short exe_addr_l; + + pcpul = (struct cpu_disklabel *)malloc(sizeof(struct cpu_disklabel)); + bzero(pcpul, sizeof(struct cpu_disklabel)); + + if (verbose) + printf("modifying vid.\n"); + + exe_file = open(bootproto, O_RDONLY, 0444); + if (exe_file == -1) { + perror(bootproto); + exit(2); + } + + f = opendev(dkname, O_RDWR, OPENDEV_PART, &specname); + + if (lseek(f, 0, SEEK_SET) < 0 || + read(f, pcpul, sizeof(struct cpu_disklabel)) + < sizeof(struct cpu_disklabel)) + err(4, "%s", specname); + + + pcpul->version = 1; + strcpy(pcpul->vid_id, "M88K"); + + fstat(exe_file, &stat); + + /* size in 256 byte blocks round up after a.out header removed */ + + pcpul->vid_oss = 2; + pcpul->vid_osl = (((stat.st_size -0x20) +511) / 512) *2; + + lseek(exe_file, 0x14, SEEK_SET); + read(exe_file, &exe_addr, 4); + + /* check this, it may not work in both endian. */ + /* No, it doesn't. Use a big endian machine for now. SPM */ + + { + union { + struct s { + unsigned short s1; + unsigned short s2; + } s; + unsigned long l; + } a; + a.l = exe_addr; + pcpul->vid_osa_u = a.s.s1; + pcpul->vid_osa_l = a.s.s2; + + } + pcpul->vid_cas = 1; + pcpul->vid_cal = 1; + + /* do not want to write past end of structure, not null terminated */ + + strncpy(pcpul->vid_mot, "MOTOROLA", 8); + + pcpul->cfg_rec = 0x100; + pcpul->cfg_psm = 0x200; + + if (!nowrite) { + if (lseek(f, 0, SEEK_SET) < 0 || + write(f, pcpul, sizeof(struct cpu_disklabel)) + < sizeof(struct cpu_disklabel)) + err(4, "%s", specname); + } + free(pcpul); + + close(exe_file); + close(f); + +} |