1 /* $OpenBSD: bootxx.c,v 1.8 1998/03/06 05:17:19 millert Exp $ */ 2 /* $NetBSD: bootxx.c,v 1.4 1997/01/18 00:28:59 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1995 Carnegie-Mellon University. 6 * All rights reserved. 7 * 8 * Author: Chris G. Demetriou 9 * 10 * Permission to use, copy, modify and distribute this software and 11 * its documentation is hereby granted, provided that both the copyright 12 * notice and this permission notice appear in all copies of the 13 * software, derivative works or modified versions, and any portions 14 * thereof, and that both notices appear in supporting documentation. 15 * 16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 19 * 20 * Carnegie Mellon requests users of this software to return to 21 * 22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 23 * School of Computer Science 24 * Carnegie Mellon University 25 * Pittsburgh PA 15213-3890 26 * 27 * any improvements or extensions that they make and grant Carnegie the 28 * rights to redistribute these changes. 29 */ 30 31 #include <sys/param.h> 32 #include <machine/rpb.h> 33 #include <machine/prom.h> 34 35 #include "bbinfo.h" 36 37 extern _end, start; 38 39 struct bbinfoloc desc = { 40 0xbabefacedeadbeef, 41 (u_int64_t)&start, 42 (u_int64_t)&_end, 43 { 0, }, 44 0xdeadbeeffacebabe 45 }; 46 47 int 48 open_dev(fd) 49 int *fd; 50 { 51 prom_return_t ret; 52 char devname[64]; 53 int devlen; 54 55 /* 56 * XXX 57 * We don't know what device names look like yet, 58 * so we can't change them. 59 */ 60 ret.bits = prom_getenv(PROM_E_BOOTED_DEV, devname, sizeof(devname)); 61 devlen = ret.u.retval; 62 63 ret.bits = prom_open(devname, devlen); 64 if (ret.u.status) 65 return 0; 66 67 *fd = ret.u.retval; 68 69 return 1; 70 } 71 72 int 73 load_file(bbinfop, loadaddr) 74 struct bbinfo *bbinfop; 75 char *loadaddr; 76 { 77 prom_return_t ret; 78 int32_t cksum, *int32p; 79 int i, n, fd, rv; 80 char *cp; 81 82 if (bbinfop->nblocks <= 0) { 83 puts("invalid number of blocks in boot program description\n"); 84 return 0; 85 } 86 if (bbinfop->bsize < DEV_BSIZE || bbinfop->bsize > MAXBSIZE) { 87 puts("invalid block size in boot program description\n"); 88 return 0; 89 } 90 91 int32p = (int32_t *)&_end; 92 n = bbinfop->nblocks + 93 (sizeof(*bbinfop) / sizeof(bbinfop->blocks[0])) - 1; 94 if ((long)&_end - (long)&start + sizeof(bbinfop->blocks[0]) * n > 95 15 * 512) { 96 puts("way too many blocks\n"); 97 return 0; 98 } 99 100 for (i = 0, cksum = 0; i < n; i++) 101 cksum += *int32p++; 102 if (cksum != 0) { 103 puts("invalid checksum in boot program description\n"); 104 return 0; 105 } 106 107 if (!open_dev(&fd)) { 108 puts("couldn't open disk device\n"); 109 return 0; 110 } 111 112 cp = loadaddr; 113 rv = 1; 114 for (i = 0; i < bbinfop->nblocks; i++) { 115 puts("."); 116 ret.bits = prom_read(fd, bbinfop->bsize, cp, 117 bbinfop->blocks[i]); 118 puts("\b"); 119 if (ret.u.status) { 120 rv = 0; 121 puts("BLOCK READ ERROR!\n"); 122 break; 123 } 124 cp += bbinfop->bsize; 125 } 126 prom_close(fd); 127 128 return (rv); 129 } 130 131 int 132 main() 133 { 134 struct bbinfo *bbinfop; 135 char *loadaddr; 136 void (*entry) __P((void)); 137 138 /* Init prom callback vector. */ 139 init_prom_calls(); 140 141 puts("\nOpenBSD/Alpha Primary Boot\n"); 142 143 bbinfop = (struct bbinfo *)&_end; 144 loadaddr = (char *)SECONDARY_LOAD_ADDRESS; 145 if (!load_file(bbinfop, loadaddr)) { 146 puts("\nLOAD FAILED!\n\n"); 147 return; 148 } 149 150 puts("Jumping to entry point...\n"); 151 entry = (void (*)())loadaddr; 152 (*entry)(); 153 puts("SECONDARY BOOT BLOCK RETURNED!\n"); 154 } 155