xref: /minix3/usr.sbin/installboot/arch/vax.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: vax.c,v 1.18 2014/11/13 16:02:25 christos Exp $	*/
29f8e6353SEvgeniy Ivanov 
39f8e6353SEvgeniy Ivanov /*-
49f8e6353SEvgeniy Ivanov  * Copyright (c) 1999, 2002 The NetBSD Foundation, Inc.
59f8e6353SEvgeniy Ivanov  * All rights reserved.
69f8e6353SEvgeniy Ivanov  *
79f8e6353SEvgeniy Ivanov  * This code is derived from software contributed to The NetBSD Foundation
89f8e6353SEvgeniy Ivanov  * by Simon Burge.
99f8e6353SEvgeniy Ivanov  *
109f8e6353SEvgeniy Ivanov  * This code is derived from software contributed to The NetBSD Foundation
119f8e6353SEvgeniy Ivanov  * by Luke Mewburn of Wasabi Systems.
129f8e6353SEvgeniy Ivanov  *
139f8e6353SEvgeniy Ivanov  * Redistribution and use in source and binary forms, with or without
149f8e6353SEvgeniy Ivanov  * modification, are permitted provided that the following conditions
159f8e6353SEvgeniy Ivanov  * are met:
169f8e6353SEvgeniy Ivanov  * 1. Redistributions of source code must retain the above copyright
179f8e6353SEvgeniy Ivanov  *    notice, this list of conditions and the following disclaimer.
189f8e6353SEvgeniy Ivanov  * 2. Redistributions in binary form must reproduce the above copyright
199f8e6353SEvgeniy Ivanov  *    notice, this list of conditions and the following disclaimer in the
209f8e6353SEvgeniy Ivanov  *    documentation and/or other materials provided with the distribution.
219f8e6353SEvgeniy Ivanov  *
229f8e6353SEvgeniy Ivanov  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
239f8e6353SEvgeniy Ivanov  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
249f8e6353SEvgeniy Ivanov  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
259f8e6353SEvgeniy Ivanov  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
269f8e6353SEvgeniy Ivanov  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
279f8e6353SEvgeniy Ivanov  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
289f8e6353SEvgeniy Ivanov  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
299f8e6353SEvgeniy Ivanov  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
309f8e6353SEvgeniy Ivanov  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
319f8e6353SEvgeniy Ivanov  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
329f8e6353SEvgeniy Ivanov  * POSSIBILITY OF SUCH DAMAGE.
339f8e6353SEvgeniy Ivanov  */
349f8e6353SEvgeniy Ivanov 
359f8e6353SEvgeniy Ivanov /*
369f8e6353SEvgeniy Ivanov  * Copyright (c) 1999 Christopher G. Demetriou.  All rights reserved.
379f8e6353SEvgeniy Ivanov  *
389f8e6353SEvgeniy Ivanov  * Redistribution and use in source and binary forms, with or without
399f8e6353SEvgeniy Ivanov  * modification, are permitted provided that the following conditions
409f8e6353SEvgeniy Ivanov  * are met:
419f8e6353SEvgeniy Ivanov  * 1. Redistributions of source code must retain the above copyright
429f8e6353SEvgeniy Ivanov  *    notice, this list of conditions and the following disclaimer.
439f8e6353SEvgeniy Ivanov  * 2. Redistributions in binary form must reproduce the above copyright
449f8e6353SEvgeniy Ivanov  *    notice, this list of conditions and the following disclaimer in the
459f8e6353SEvgeniy Ivanov  *    documentation and/or other materials provided with the distribution.
469f8e6353SEvgeniy Ivanov  * 3. All advertising materials mentioning features or use of this software
479f8e6353SEvgeniy Ivanov  *    must display the following acknowledgement:
489f8e6353SEvgeniy Ivanov  *      This product includes software developed by Christopher G. Demetriou
499f8e6353SEvgeniy Ivanov  *	for the NetBSD Project.
509f8e6353SEvgeniy Ivanov  * 4. The name of the author may not be used to endorse or promote products
519f8e6353SEvgeniy Ivanov  *    derived from this software without specific prior written permission
529f8e6353SEvgeniy Ivanov  *
539f8e6353SEvgeniy Ivanov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
549f8e6353SEvgeniy Ivanov  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
559f8e6353SEvgeniy Ivanov  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
569f8e6353SEvgeniy Ivanov  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
579f8e6353SEvgeniy Ivanov  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
589f8e6353SEvgeniy Ivanov  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
599f8e6353SEvgeniy Ivanov  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
609f8e6353SEvgeniy Ivanov  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
619f8e6353SEvgeniy Ivanov  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
629f8e6353SEvgeniy Ivanov  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
639f8e6353SEvgeniy Ivanov  */
649f8e6353SEvgeniy Ivanov 
659f8e6353SEvgeniy Ivanov #if HAVE_NBTOOL_CONFIG_H
669f8e6353SEvgeniy Ivanov #include "nbtool_config.h"
679f8e6353SEvgeniy Ivanov #endif
689f8e6353SEvgeniy Ivanov 
699f8e6353SEvgeniy Ivanov #include <sys/cdefs.h>
709f8e6353SEvgeniy Ivanov #if !defined(__lint)
71*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: vax.c,v 1.18 2014/11/13 16:02:25 christos Exp $");
729f8e6353SEvgeniy Ivanov #endif	/* !__lint */
739f8e6353SEvgeniy Ivanov 
749f8e6353SEvgeniy Ivanov #include <sys/param.h>
7584d9c625SLionel Sambuc #ifdef HAVE_NBTOOL_CONFIG_H
7684d9c625SLionel Sambuc #include <nbinclude/vax/disklabel.h>
7784d9c625SLionel Sambuc #else
7884d9c625SLionel Sambuc #include <sys/disklabel.h>
7984d9c625SLionel Sambuc #endif
809f8e6353SEvgeniy Ivanov 
819f8e6353SEvgeniy Ivanov #include <assert.h>
829f8e6353SEvgeniy Ivanov #include <err.h>
839f8e6353SEvgeniy Ivanov #include <stddef.h>
849f8e6353SEvgeniy Ivanov #include <stdio.h>
859f8e6353SEvgeniy Ivanov #include <stdlib.h>
8684d9c625SLionel Sambuc #include <string.h>
879f8e6353SEvgeniy Ivanov #include <unistd.h>
889f8e6353SEvgeniy Ivanov 
899f8e6353SEvgeniy Ivanov #include "installboot.h"
909f8e6353SEvgeniy Ivanov 
91*0a6a1f1dSLionel Sambuc #define	VAX_LABELOFFSET		64
92*0a6a1f1dSLionel Sambuc 
9384d9c625SLionel Sambuc #ifndef __CTASSERT
9484d9c625SLionel Sambuc #define	__CTASSERT(X)
9584d9c625SLionel Sambuc #endif
9684d9c625SLionel Sambuc 
979f8e6353SEvgeniy Ivanov static int	load_bootstrap(ib_params *, char **,
989f8e6353SEvgeniy Ivanov 		    uint32_t *, uint32_t *, size_t *);
999f8e6353SEvgeniy Ivanov 
1009f8e6353SEvgeniy Ivanov static int vax_clearboot(ib_params *);
1019f8e6353SEvgeniy Ivanov static int vax_setboot(ib_params *);
1029f8e6353SEvgeniy Ivanov 
1039f8e6353SEvgeniy Ivanov struct ib_mach ib_mach_vax =
1049f8e6353SEvgeniy Ivanov 	{ "vax", vax_setboot, vax_clearboot, no_editboot,
1059f8e6353SEvgeniy Ivanov 		IB_STAGE1START | IB_APPEND | IB_SUNSUM };
1069f8e6353SEvgeniy Ivanov 
1079f8e6353SEvgeniy Ivanov static int
vax_clearboot(ib_params * params)1089f8e6353SEvgeniy Ivanov vax_clearboot(ib_params *params)
1099f8e6353SEvgeniy Ivanov {
1109f8e6353SEvgeniy Ivanov 	struct vax_boot_block	bb;
1119f8e6353SEvgeniy Ivanov 	ssize_t			rv;
1129f8e6353SEvgeniy Ivanov 
1139f8e6353SEvgeniy Ivanov 	assert(params != NULL);
1149f8e6353SEvgeniy Ivanov 	assert(params->fsfd != -1);
1159f8e6353SEvgeniy Ivanov 	assert(params->filesystem != NULL);
11684d9c625SLionel Sambuc 	__CTASSERT(sizeof(bb)==VAX_BOOT_BLOCK_BLOCKSIZE);
1179f8e6353SEvgeniy Ivanov 
1189f8e6353SEvgeniy Ivanov 	rv = pread(params->fsfd, &bb, sizeof(bb), VAX_BOOT_BLOCK_OFFSET);
1199f8e6353SEvgeniy Ivanov 	if (rv == -1) {
1209f8e6353SEvgeniy Ivanov 		warn("Reading `%s'", params->filesystem);
1219f8e6353SEvgeniy Ivanov 		return (0);
1229f8e6353SEvgeniy Ivanov 	} else if (rv != sizeof(bb)) {
1239f8e6353SEvgeniy Ivanov 		warnx("Reading `%s': short read", params->filesystem);
1249f8e6353SEvgeniy Ivanov 		return (0);
1259f8e6353SEvgeniy Ivanov 	}
1269f8e6353SEvgeniy Ivanov 
12784d9c625SLionel Sambuc 	if (bb.bb_id_offset*2 >= VAX_BOOT_BLOCK_BLOCKSIZE
1289f8e6353SEvgeniy Ivanov 	    || bb.bb_magic1 != VAX_BOOT_MAGIC1) {
1299f8e6353SEvgeniy Ivanov 		warnx(
1309f8e6353SEvgeniy Ivanov 		    "Old boot block magic number invalid; boot block invalid");
1319f8e6353SEvgeniy Ivanov 		return (0);
1329f8e6353SEvgeniy Ivanov 	}
1339f8e6353SEvgeniy Ivanov 
1349f8e6353SEvgeniy Ivanov 	bb.bb_id_offset = 1;
1359f8e6353SEvgeniy Ivanov 	bb.bb_mbone = 0;
1369f8e6353SEvgeniy Ivanov 	bb.bb_lbn_hi = 0;
1379f8e6353SEvgeniy Ivanov 	bb.bb_lbn_low = 0;
1389f8e6353SEvgeniy Ivanov 
1399f8e6353SEvgeniy Ivanov 	if (params->flags & IB_SUNSUM) {
1409f8e6353SEvgeniy Ivanov 		uint16_t	sum;
1419f8e6353SEvgeniy Ivanov 
1429f8e6353SEvgeniy Ivanov 		sum = compute_sunsum((uint16_t *)&bb);
1439f8e6353SEvgeniy Ivanov 		if (! set_sunsum(params, (uint16_t *)&bb, sum))
1449f8e6353SEvgeniy Ivanov 			return (0);
1459f8e6353SEvgeniy Ivanov 	}
1469f8e6353SEvgeniy Ivanov 
1479f8e6353SEvgeniy Ivanov 	if (params->flags & IB_VERBOSE)
1489f8e6353SEvgeniy Ivanov 		printf("%slearing boot block\n",
1499f8e6353SEvgeniy Ivanov 		    (params->flags & IB_NOWRITE) ? "Not c" : "C");
1509f8e6353SEvgeniy Ivanov 	if (params->flags & IB_NOWRITE)
1519f8e6353SEvgeniy Ivanov 		return (1);
1529f8e6353SEvgeniy Ivanov 
1539f8e6353SEvgeniy Ivanov 	rv = pwrite(params->fsfd, &bb, sizeof(bb), VAX_BOOT_BLOCK_OFFSET);
1549f8e6353SEvgeniy Ivanov 	if (rv == -1) {
1559f8e6353SEvgeniy Ivanov 		warn("Writing `%s'", params->filesystem);
1569f8e6353SEvgeniy Ivanov 		return (0);
1579f8e6353SEvgeniy Ivanov 	} else if (rv != sizeof(bb)) {
1589f8e6353SEvgeniy Ivanov 		warnx("Writing `%s': short write", params->filesystem);
1599f8e6353SEvgeniy Ivanov 		return (0);
1609f8e6353SEvgeniy Ivanov 	}
1619f8e6353SEvgeniy Ivanov 
1629f8e6353SEvgeniy Ivanov 	return (1);
1639f8e6353SEvgeniy Ivanov }
1649f8e6353SEvgeniy Ivanov 
1659f8e6353SEvgeniy Ivanov static int
vax_setboot(ib_params * params)1669f8e6353SEvgeniy Ivanov vax_setboot(ib_params *params)
1679f8e6353SEvgeniy Ivanov {
1689f8e6353SEvgeniy Ivanov 	struct stat		bootstrapsb;
16984d9c625SLionel Sambuc 	struct vax_boot_block	*bb;
1709f8e6353SEvgeniy Ivanov 	uint32_t		startblock;
1719f8e6353SEvgeniy Ivanov 	int			retval;
17284d9c625SLionel Sambuc 	char			*bootstrapbuf, oldbb[VAX_BOOT_BLOCK_BLOCKSIZE];
1739f8e6353SEvgeniy Ivanov 	size_t			bootstrapsize;
1749f8e6353SEvgeniy Ivanov 	uint32_t		bootstrapload, bootstrapexec;
1759f8e6353SEvgeniy Ivanov 	ssize_t			rv;
1769f8e6353SEvgeniy Ivanov 
1779f8e6353SEvgeniy Ivanov 	assert(params != NULL);
1789f8e6353SEvgeniy Ivanov 	assert(params->fsfd != -1);
1799f8e6353SEvgeniy Ivanov 	assert(params->filesystem != NULL);
1809f8e6353SEvgeniy Ivanov 	assert(params->s1fd != -1);
1819f8e6353SEvgeniy Ivanov 	assert(params->stage1 != NULL);
1829f8e6353SEvgeniy Ivanov 
18384d9c625SLionel Sambuc 	/* see sys/arch/vax/boot/xxboot/start.S for explanation */
18484d9c625SLionel Sambuc 	__CTASSERT(offsetof(struct vax_boot_block,bb_magic1) == 0x19e);
18584d9c625SLionel Sambuc 	__CTASSERT(sizeof(struct vax_boot_block) == VAX_BOOT_BLOCK_BLOCKSIZE);
18684d9c625SLionel Sambuc 
18784d9c625SLionel Sambuc 	startblock = 0;
1889f8e6353SEvgeniy Ivanov 	retval = 0;
1899f8e6353SEvgeniy Ivanov 	bootstrapbuf = NULL;
1909f8e6353SEvgeniy Ivanov 
1919f8e6353SEvgeniy Ivanov 	if (fstat(params->s1fd, &bootstrapsb) == -1) {
1929f8e6353SEvgeniy Ivanov 		warn("Examining `%s'", params->stage1);
1939f8e6353SEvgeniy Ivanov 		goto done;
1949f8e6353SEvgeniy Ivanov 	}
1959f8e6353SEvgeniy Ivanov 	if (!S_ISREG(bootstrapsb.st_mode)) {
1969f8e6353SEvgeniy Ivanov 		warnx("`%s' must be a regular file", params->stage1);
1979f8e6353SEvgeniy Ivanov 		goto done;
1989f8e6353SEvgeniy Ivanov 	}
1999f8e6353SEvgeniy Ivanov 	if (! load_bootstrap(params, &bootstrapbuf, &bootstrapload,
2009f8e6353SEvgeniy Ivanov 	    &bootstrapexec, &bootstrapsize))
2019f8e6353SEvgeniy Ivanov 		goto done;
2029f8e6353SEvgeniy Ivanov 
20384d9c625SLionel Sambuc 	/* read old boot block */
20484d9c625SLionel Sambuc 	rv = pread(params->fsfd, oldbb, sizeof(oldbb), VAX_BOOT_BLOCK_OFFSET);
2059f8e6353SEvgeniy Ivanov 	if (rv == -1) {
2069f8e6353SEvgeniy Ivanov 		warn("Reading `%s'", params->filesystem);
2079f8e6353SEvgeniy Ivanov 		goto done;
20884d9c625SLionel Sambuc 	} else if (rv != sizeof(oldbb)) {
2099f8e6353SEvgeniy Ivanov 		warnx("Reading `%s': short read", params->filesystem);
2109f8e6353SEvgeniy Ivanov 		goto done;
2119f8e6353SEvgeniy Ivanov 	}
2129f8e6353SEvgeniy Ivanov 
21384d9c625SLionel Sambuc 	/*
21484d9c625SLionel Sambuc 	 * Copy disklabel from old boot block to new.
215*0a6a1f1dSLionel Sambuc 	 * Assume everything between VAX_LABELOFFSET and the start of
21684d9c625SLionel Sambuc 	 * the param block is scratch area and can be copied over.
21784d9c625SLionel Sambuc 	 */
218*0a6a1f1dSLionel Sambuc 	memcpy(bootstrapbuf + VAX_LABELOFFSET,
219*0a6a1f1dSLionel Sambuc 	    oldbb + VAX_LABELOFFSET,
220*0a6a1f1dSLionel Sambuc 	    offsetof(struct vax_boot_block,bb_magic1) - VAX_LABELOFFSET);
22184d9c625SLionel Sambuc 
22284d9c625SLionel Sambuc 	/* point to bootblock at begining of bootstrap */
22384d9c625SLionel Sambuc 	bb = (struct vax_boot_block*)bootstrapbuf;
22484d9c625SLionel Sambuc 
2259f8e6353SEvgeniy Ivanov 	/* fill in the updated boot block fields */
2269f8e6353SEvgeniy Ivanov 	if (params->flags & IB_APPEND) {
2279f8e6353SEvgeniy Ivanov 		struct stat	filesyssb;
2289f8e6353SEvgeniy Ivanov 
2299f8e6353SEvgeniy Ivanov 		if (fstat(params->fsfd, &filesyssb) == -1) {
2309f8e6353SEvgeniy Ivanov 			warn("Examining `%s'", params->filesystem);
2319f8e6353SEvgeniy Ivanov 			goto done;
2329f8e6353SEvgeniy Ivanov 		}
2339f8e6353SEvgeniy Ivanov 		if (!S_ISREG(filesyssb.st_mode)) {
2349f8e6353SEvgeniy Ivanov 			warnx(
2359f8e6353SEvgeniy Ivanov 		    "`%s' must be a regular file to append a bootstrap",
2369f8e6353SEvgeniy Ivanov 			    params->filesystem);
2379f8e6353SEvgeniy Ivanov 			goto done;
2389f8e6353SEvgeniy Ivanov 		}
2399f8e6353SEvgeniy Ivanov 		startblock = howmany(filesyssb.st_size,
2409f8e6353SEvgeniy Ivanov 		    VAX_BOOT_BLOCK_BLOCKSIZE);
24184d9c625SLionel Sambuc 		bb->bb_lbn_hi = htole16((uint16_t) (startblock >> 16));
24284d9c625SLionel Sambuc 		bb->bb_lbn_low = htole16((uint16_t) (startblock >>  0));
2439f8e6353SEvgeniy Ivanov 	}
2449f8e6353SEvgeniy Ivanov 
2459f8e6353SEvgeniy Ivanov 	if (params->flags & IB_SUNSUM) {
2469f8e6353SEvgeniy Ivanov 		uint16_t	sum;
2479f8e6353SEvgeniy Ivanov 
24884d9c625SLionel Sambuc 		sum = compute_sunsum((uint16_t *)bb);
24984d9c625SLionel Sambuc 		if (! set_sunsum(params, (uint16_t *)bb, sum))
2509f8e6353SEvgeniy Ivanov 			goto done;
2519f8e6353SEvgeniy Ivanov 	}
2529f8e6353SEvgeniy Ivanov 
2539f8e6353SEvgeniy Ivanov 	if (params->flags & IB_VERBOSE) {
2549f8e6353SEvgeniy Ivanov 		printf("Bootstrap start sector: %u\n", startblock);
25584d9c625SLionel Sambuc 		printf("Bootstrap sector count: %u\n", le32toh(bb->bb_size));
2569f8e6353SEvgeniy Ivanov 		printf("%sriting bootstrap\n",
2579f8e6353SEvgeniy Ivanov 		    (params->flags & IB_NOWRITE) ? "Not w" : "W");
2589f8e6353SEvgeniy Ivanov 	}
2599f8e6353SEvgeniy Ivanov 	if (params->flags & IB_NOWRITE) {
2609f8e6353SEvgeniy Ivanov 		retval = 1;
2619f8e6353SEvgeniy Ivanov 		goto done;
2629f8e6353SEvgeniy Ivanov 	}
26384d9c625SLionel Sambuc 	rv = pwrite(params->fsfd, bootstrapbuf, bootstrapsize, 0);
2649f8e6353SEvgeniy Ivanov 	if (rv == -1) {
2659f8e6353SEvgeniy Ivanov 		warn("Writing `%s'", params->filesystem);
2669f8e6353SEvgeniy Ivanov 		goto done;
2679f8e6353SEvgeniy Ivanov 	} else if ((size_t)rv != bootstrapsize) {
2689f8e6353SEvgeniy Ivanov 		warnx("Writing `%s': short write", params->filesystem);
2699f8e6353SEvgeniy Ivanov 		goto done;
2709f8e6353SEvgeniy Ivanov 	}
2719f8e6353SEvgeniy Ivanov 	retval = 1;
2729f8e6353SEvgeniy Ivanov 
2739f8e6353SEvgeniy Ivanov  done:
2749f8e6353SEvgeniy Ivanov 	if (bootstrapbuf)
2759f8e6353SEvgeniy Ivanov 		free(bootstrapbuf);
2769f8e6353SEvgeniy Ivanov 	return (retval);
2779f8e6353SEvgeniy Ivanov }
2789f8e6353SEvgeniy Ivanov 
2799f8e6353SEvgeniy Ivanov static int
load_bootstrap(ib_params * params,char ** data,uint32_t * loadaddr,uint32_t * execaddr,size_t * len)2809f8e6353SEvgeniy Ivanov load_bootstrap(ib_params *params, char **data,
2819f8e6353SEvgeniy Ivanov 	uint32_t *loadaddr, uint32_t *execaddr, size_t *len)
2829f8e6353SEvgeniy Ivanov {
2839f8e6353SEvgeniy Ivanov 	ssize_t	cc;
2849f8e6353SEvgeniy Ivanov 	size_t	buflen;
2859f8e6353SEvgeniy Ivanov 
2869f8e6353SEvgeniy Ivanov 	buflen = 512 * (VAX_BOOT_SIZE + 1);
2879f8e6353SEvgeniy Ivanov 	*data = malloc(buflen);
2889f8e6353SEvgeniy Ivanov 	if (*data == NULL) {
2899f8e6353SEvgeniy Ivanov 		warn("Allocating %lu bytes", (unsigned long) buflen);
2909f8e6353SEvgeniy Ivanov 		return (0);
2919f8e6353SEvgeniy Ivanov 	}
2929f8e6353SEvgeniy Ivanov 
2939f8e6353SEvgeniy Ivanov 	cc = pread(params->s1fd, *data, buflen, 0);
2949f8e6353SEvgeniy Ivanov 	if (cc <= 0) {
2959f8e6353SEvgeniy Ivanov 		warn("Reading `%s'", params->stage1);
2969f8e6353SEvgeniy Ivanov 		return (0);
2979f8e6353SEvgeniy Ivanov 	}
2989f8e6353SEvgeniy Ivanov 	if (cc > 512 * VAX_BOOT_SIZE) {
2999f8e6353SEvgeniy Ivanov 		warnx("`%s': too large", params->stage1);
3009f8e6353SEvgeniy Ivanov 		return (0);
3019f8e6353SEvgeniy Ivanov 	}
3029f8e6353SEvgeniy Ivanov 
3039f8e6353SEvgeniy Ivanov 	*len = roundup(cc, VAX_BOOT_BLOCK_BLOCKSIZE);
3049f8e6353SEvgeniy Ivanov 	*loadaddr = VAX_BOOT_LOAD;
3059f8e6353SEvgeniy Ivanov 	*execaddr = VAX_BOOT_ENTRY;
3069f8e6353SEvgeniy Ivanov 	return (1);
3079f8e6353SEvgeniy Ivanov }
308