Home | History | Annotate | Line # | Download | only in wrtvid
wrtvid.c revision 1.8.88.1
      1  1.8.88.1  christos /*	$NetBSD: wrtvid.c,v 1.8.88.1 2019/06/10 22:06:33 christos Exp $	*/
      2       1.5       scw 
      3       1.5       scw /*-
      4       1.5       scw  * Copyright (c) 2002 The NetBSD Foundation, Inc.
      5       1.5       scw  * All rights reserved.
      6       1.5       scw  *
      7       1.5       scw  * This code is derived from software contributed to The NetBSD Foundation
      8       1.5       scw  * by Steve C. Woodford.
      9       1.5       scw  *
     10       1.5       scw  * Redistribution and use in source and binary forms, with or without
     11       1.5       scw  * modification, are permitted provided that the following conditions
     12       1.5       scw  * are met:
     13       1.5       scw  * 1. Redistributions of source code must retain the above copyright
     14       1.5       scw  *    notice, this list of conditions and the following disclaimer.
     15       1.5       scw  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.5       scw  *    notice, this list of conditions and the following disclaimer in the
     17       1.5       scw  *    documentation and/or other materials provided with the distribution.
     18       1.5       scw  *
     19       1.5       scw  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20       1.5       scw  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21       1.5       scw  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22       1.5       scw  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23       1.5       scw  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24       1.5       scw  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25       1.5       scw  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26       1.5       scw  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27       1.5       scw  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28       1.5       scw  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29       1.5       scw  * POSSIBILITY OF SUCH DAMAGE.
     30       1.5       scw  */
     31       1.1     chuck 
     32       1.1     chuck #include <sys/types.h>
     33       1.5       scw #include <sys/stat.h>
     34       1.1     chuck #include <fcntl.h>
     35       1.1     chuck #include <stdio.h>
     36       1.2       scw #include <stdlib.h>
     37       1.5       scw #include <string.h>
     38  1.8.88.1  christos #include <unistd.h>
     39       1.5       scw 
     40       1.5       scw /* mvme68k's boot block is 512 bytes long */
     41       1.5       scw #define SIZEOF_VID		0x200
     42       1.5       scw 
     43       1.5       scw /* The first field is effectively the vendor string, in this case NBSD */
     44       1.5       scw #define	VID_ID_OFF		0x000
     45       1.5       scw #define	 VID_ID			"NBSD"
     46       1.5       scw #define	 VID_ID_LEN		4
     47       1.1     chuck 
     48       1.5       scw /* Start block for the 1st stage bootstrap code */
     49       1.5       scw #define	VID_OSS_OFF		0x014
     50       1.5       scw #define	 VID_OSS_TAPE		1
     51       1.5       scw #define	 VID_OSS_DISK		2
     52       1.2       scw 
     53       1.5       scw /* Length, in 256-byte logical blocks, of the 1st stage bootstrap */
     54       1.5       scw #define	VID_OSL_OFF		0x018
     55       1.2       scw 
     56       1.5       scw /* Start address of the bootstrap */
     57       1.5       scw #define VID_OSA_OFF		0x01e
     58       1.5       scw #define  VID_OSA		0x003f0000
     59       1.1     chuck 
     60       1.5       scw /* Block number of config area */
     61       1.5       scw #define VID_CAS_OFF		0x093
     62       1.5       scw #define  VID_CAS		1
     63       1.1     chuck 
     64       1.5       scw /* Length, in 256-byte logical blocks, of config area */
     65       1.5       scw #define VID_CAL_OFF		0x094
     66       1.5       scw #define  VID_CAL		1
     67       1.1     chuck 
     68       1.5       scw /* Magic `MOTOROLA' string */
     69       1.5       scw #define VID_MOT_OFF		0x0f8
     70       1.5       scw #define  VID_MOT		"MOTOROLA"
     71       1.5       scw #define  VID_MOT_LEN		8
     72       1.1     chuck 
     73       1.5       scw /* Logical block size, in bytes */
     74       1.5       scw #define	CFG_REC_OFF		0x10a
     75       1.5       scw #define	 CFG_REC		0x100
     76       1.1     chuck 
     77       1.5       scw /* Physical sector size, in bytes */
     78       1.5       scw #define	CFG_PSM_OFF		0x11e
     79       1.5       scw #define	 CFG_PSM		0x200
     80       1.1     chuck 
     81       1.2       scw 
     82       1.5       scw /*
     83       1.5       scw  * Write a big-endian 32-bit value at the specified address
     84       1.5       scw  */
     85       1.5       scw static void
     86       1.7   tsutsui write32(uint8_t *vp, uint32_t value)
     87       1.5       scw {
     88       1.7   tsutsui 
     89       1.7   tsutsui 	*vp++ = (uint8_t)((value >> 24) & 0xff);
     90       1.7   tsutsui 	*vp++ = (uint8_t)((value >> 16) & 0xff);
     91       1.7   tsutsui 	*vp++ = (uint8_t)((value >> 8) & 0xff);
     92       1.7   tsutsui 	*vp = (uint8_t)(value & 0xff);
     93       1.1     chuck }
     94       1.1     chuck 
     95       1.5       scw /*
     96       1.5       scw  * Write a big-endian 16-bit value at the specified address
     97       1.5       scw  */
     98       1.2       scw static void
     99       1.7   tsutsui write16(uint8_t *vp, uint16_t value)
    100       1.1     chuck {
    101       1.7   tsutsui 
    102       1.7   tsutsui 	*vp++ = (uint8_t)((value >> 8) & 0xff);
    103       1.7   tsutsui 	*vp = (uint8_t)(value & 0xff);
    104       1.1     chuck }
    105       1.1     chuck 
    106       1.5       scw int
    107       1.5       scw main(int argc, char **argv)
    108       1.1     chuck {
    109       1.5       scw 	struct stat st;
    110       1.7   tsutsui 	uint16_t len;
    111       1.7   tsutsui 	uint8_t *vid;
    112       1.5       scw 	char *fn;
    113       1.5       scw 	int is_disk;
    114       1.5       scw 	int fd;
    115       1.5       scw 
    116       1.5       scw 	if (argc != 2) {
    117       1.5       scw usage:
    118       1.5       scw 		fprintf(stderr, "%s: <bootsd|bootst>\n", argv[0]);
    119       1.5       scw 		exit(1);
    120       1.5       scw 	}
    121       1.5       scw 
    122       1.5       scw 	if (strcmp(argv[1], "bootsd") == 0) {
    123       1.5       scw 		is_disk = 1;
    124       1.5       scw 		fn = "sdboot";
    125       1.5       scw 	} else
    126       1.5       scw 	if (strcmp(argv[1], "bootst") == 0) {
    127       1.5       scw 		is_disk = 0;
    128       1.5       scw 		fn = "stboot";
    129       1.5       scw 	} else
    130       1.5       scw 		goto usage;
    131       1.5       scw 
    132       1.5       scw 	if (stat(argv[1], &st) < 0) {
    133       1.5       scw 		perror(argv[1]);
    134       1.5       scw 		exit(1);
    135       1.5       scw 	}
    136       1.5       scw 
    137       1.5       scw 	/* How many 256-byte logical blocks (rounded up) */
    138       1.7   tsutsui 	len = (uint16_t)((st.st_size + 255) / 256);
    139       1.6       scw 
    140       1.6       scw 	/* For tapes, round up to 8k */
    141       1.6       scw 	if (is_disk == 0) {
    142       1.6       scw 		len += (8192 / 256) - 1;
    143       1.6       scw 		len &= ~((8192 / 256) -1);
    144       1.6       scw 	}
    145       1.5       scw 
    146       1.5       scw 	if ((vid = malloc(SIZEOF_VID)) == NULL) {
    147       1.5       scw 		perror(argv[0]);
    148       1.5       scw 		exit(1);
    149       1.5       scw 	}
    150       1.5       scw 
    151       1.5       scw 	/* Generate the VID and CFG data */
    152       1.5       scw 	memset(vid, 0, SIZEOF_VID);
    153       1.5       scw 	memcpy(&vid[VID_ID_OFF], VID_ID, VID_ID_LEN);
    154       1.5       scw 	write32(&vid[VID_OSS_OFF], is_disk ? VID_OSS_DISK : VID_OSS_TAPE);
    155       1.5       scw 	write16(&vid[VID_OSL_OFF], len);
    156       1.5       scw 	write32(&vid[VID_OSA_OFF], VID_OSA);
    157       1.5       scw 	vid[VID_CAS_OFF] = VID_CAS;
    158       1.5       scw 	vid[VID_CAL_OFF] = VID_CAL;
    159       1.5       scw 	memcpy(&vid[VID_MOT_OFF], VID_MOT, VID_MOT_LEN);
    160       1.5       scw 	write16(&vid[CFG_REC_OFF], CFG_REC);
    161       1.5       scw 	write16(&vid[CFG_PSM_OFF], CFG_PSM);
    162       1.5       scw 
    163       1.5       scw 	/* Create and write it out */
    164       1.5       scw 	if ((fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
    165       1.5       scw 		perror(fn);
    166       1.5       scw 		exit(1);
    167       1.5       scw 	}
    168       1.5       scw 
    169       1.5       scw 	if (write(fd, vid, SIZEOF_VID) != SIZEOF_VID) {
    170       1.5       scw 		perror(fn);
    171       1.5       scw 		exit(1);
    172       1.5       scw 	}
    173       1.5       scw 
    174       1.5       scw 	close(fd);
    175       1.5       scw 	free(vid);
    176       1.5       scw 
    177       1.7   tsutsui 	return 0;
    178       1.1     chuck }
    179