1 /* $NetBSD: wrtvid.c,v 1.7 2008/01/12 09:54:33 tsutsui Exp $ */
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Steve C. Woodford.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/types.h>
39 /* mvme68k's boot block is 512 bytes long */
40 #define SIZEOF_VID 0x200
42 /* The first field is effectively the vendor string, in this case NBSD */
43 #define VID_ID_OFF 0x000
47 /* Start block for the 1st stage bootstrap code */
48 #define VID_OSS_OFF 0x014
49 #define VID_OSS_TAPE 1
50 #define VID_OSS_DISK 2
52 /* Length, in 256-byte logical blocks, of the 1st stage bootstrap */
53 #define VID_OSL_OFF 0x018
55 /* Start address of the bootstrap */
56 #define VID_OSA_OFF 0x01e
57 #define VID_OSA 0x003f0000
59 /* Block number of config area */
60 #define VID_CAS_OFF 0x093
63 /* Length, in 256-byte logical blocks, of config area */
64 #define VID_CAL_OFF 0x094
67 /* Magic `MOTOROLA' string */
68 #define VID_MOT_OFF 0x0f8
69 #define VID_MOT "MOTOROLA"
72 /* Logical block size, in bytes */
73 #define CFG_REC_OFF 0x10a
76 /* Physical sector size, in bytes */
77 #define CFG_PSM_OFF 0x11e
82 * Write a big-endian 32-bit value at the specified address
85 write32(uint8_t *vp
, uint32_t value
)
88 *vp
++ = (uint8_t)((value
>> 24) & 0xff);
89 *vp
++ = (uint8_t)((value
>> 16) & 0xff);
90 *vp
++ = (uint8_t)((value
>> 8) & 0xff);
91 *vp
= (uint8_t)(value
& 0xff);
95 * Write a big-endian 16-bit value at the specified address
98 write16(uint8_t *vp
, uint16_t value
)
101 *vp
++ = (uint8_t)((value
>> 8) & 0xff);
102 *vp
= (uint8_t)(value
& 0xff);
106 main(int argc
, char **argv
)
117 fprintf(stderr
, "%s: <bootsd|bootst>\n", argv
[0]);
121 if (strcmp(argv
[1], "bootsd") == 0) {
125 if (strcmp(argv
[1], "bootst") == 0) {
131 if (stat(argv
[1], &st
) < 0) {
136 /* How many 256-byte logical blocks (rounded up) */
137 len
= (uint16_t)((st
.st_size
+ 255) / 256);
139 /* For tapes, round up to 8k */
141 len
+= (8192 / 256) - 1;
142 len
&= ~((8192 / 256) -1);
145 if ((vid
= malloc(SIZEOF_VID
)) == NULL
) {
150 /* Generate the VID and CFG data */
151 memset(vid
, 0, SIZEOF_VID
);
152 memcpy(&vid
[VID_ID_OFF
], VID_ID
, VID_ID_LEN
);
153 write32(&vid
[VID_OSS_OFF
], is_disk
? VID_OSS_DISK
: VID_OSS_TAPE
);
154 write16(&vid
[VID_OSL_OFF
], len
);
155 write32(&vid
[VID_OSA_OFF
], VID_OSA
);
156 vid
[VID_CAS_OFF
] = VID_CAS
;
157 vid
[VID_CAL_OFF
] = VID_CAL
;
158 memcpy(&vid
[VID_MOT_OFF
], VID_MOT
, VID_MOT_LEN
);
159 write16(&vid
[CFG_REC_OFF
], CFG_REC
);
160 write16(&vid
[CFG_PSM_OFF
], CFG_PSM
);
162 /* Create and write it out */
163 if ((fd
= open(fn
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0644)) < 0) {
168 if (write(fd
, vid
, SIZEOF_VID
) != SIZEOF_VID
) {