1 /* $NetBSD: hp700.c,v 1.3 2008/02/02 16:46:15 itohy Exp $ */
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Luke Mewburn of Wasabi Systems.
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 #if HAVE_NBTOOL_CONFIG_H
33 #include "nbtool_config.h"
36 #include <sys/cdefs.h>
38 __RCSID("$NetBSD: hp700.c,v 1.3 2008/02/02 16:46:15 itohy Exp $");
41 /* We need the target disklabel.h, not the hosts one..... */
42 #ifdef HAVE_NBTOOL_CONFIG_H
43 #include "nbtool_config.h"
44 #include <nbinclude/sys/disklabel.h>
46 #include <sys/disklabel.h>
48 #include <sys/param.h>
59 #include "installboot.h"
61 #define HP700_LABELOFFSET 512
62 #define HP700_LABELSIZE 404 /* reserve 16 partitions */
63 #define HP700_BOOT_BLOCK_SIZE 8192
65 static int hp700_clearboot(ib_params
*);
66 static int hp700_setboot(ib_params
*);
68 struct ib_mach ib_mach_hp700
=
69 { "hp700", hp700_setboot
, hp700_clearboot
, no_editboot
, 0};
72 hp700_clearboot(ib_params
*params
)
74 char bb
[HP700_BOOT_BLOCK_SIZE
];
78 assert(params
!= NULL
);
79 assert(params
->fsfd
!= -1);
80 assert(params
->filesystem
!= NULL
);
84 /* read disklabel on the target disk */
85 rv
= pread(params
->fsfd
, bb
, sizeof bb
, 0);
87 warn("Reading `%s'", params
->filesystem
);
89 } else if (rv
!= sizeof bb
) {
90 warnx("Reading `%s': short read", params
->filesystem
);
95 memset(bb
, 0, HP700_LABELOFFSET
);
96 eol
= HP700_LABELOFFSET
+ HP700_LABELSIZE
;
97 memset(&bb
[eol
], 0, sizeof bb
- eol
);
99 if (params
->flags
& IB_VERBOSE
) {
100 printf("%slearing bootstrap\n",
101 (params
->flags
& IB_NOWRITE
) ? "Not c" : "C");
103 if (params
->flags
& IB_NOWRITE
) {
108 rv
= pwrite(params
->fsfd
, bb
, sizeof bb
, 0);
110 warn("Writing `%s'", params
->filesystem
);
112 } else if (rv
!= HP700_BOOT_BLOCK_SIZE
) {
113 warnx("Writing `%s': short write", params
->filesystem
);
123 hp700_setboot(ib_params
*params
)
125 struct stat bootstrapsb
;
126 char bb
[HP700_BOOT_BLOCK_SIZE
];
128 char l_off
[HP700_LABELOFFSET
];
130 char l_pad
[HP700_BOOT_BLOCK_SIZE
131 - HP700_LABELOFFSET
- sizeof(struct disklabel
)];
133 unsigned int secsize
, npart
;
137 assert(params
!= NULL
);
138 assert(params
->fsfd
!= -1);
139 assert(params
->filesystem
!= NULL
);
140 assert(params
->s1fd
!= -1);
141 assert(params
->stage1
!= NULL
);
145 /* read disklabel on the target disk */
146 rv
= pread(params
->fsfd
, &label
, HP700_BOOT_BLOCK_SIZE
, 0);
148 warn("Reading `%s'", params
->filesystem
);
150 } else if (rv
!= HP700_BOOT_BLOCK_SIZE
) {
151 warnx("Reading `%s': short read", params
->filesystem
);
155 if (fstat(params
->s1fd
, &bootstrapsb
) == -1) {
156 warn("Examining `%s'", params
->stage1
);
159 if (!S_ISREG(bootstrapsb
.st_mode
)) {
160 warnx("`%s' must be a regular file", params
->stage1
);
164 /* check if valid disklabel exists */
165 secsize
= be32toh(label
.l
.d_secsize
);
166 npart
= be16toh(label
.l
.d_npartitions
);
167 if (label
.l
.d_magic
!= htobe32(DISKMAGIC
) ||
168 label
.l
.d_magic2
!= htobe32(DISKMAGIC
) ||
169 secsize
== 0 || secsize
& (secsize
- 1) ||
170 npart
> MAXMAXPARTITIONS
) {
171 warnx("No disklabel in `%s'", params
->filesystem
);
173 /* then check if boot partition exists */
174 } else if (npart
< 1 || label
.l
.d_partitions
[0].p_size
== 0) {
175 warnx("Partition `a' doesn't exist in %s", params
->filesystem
);
177 /* check if the boot partition is below 2GB */
178 } else if (be32toh(label
.l
.d_partitions
[0].p_offset
) +
179 be32toh(label
.l
.d_partitions
[0].p_size
) >
180 ((unsigned)2*1024*1024*1024) / secsize
) {
181 warnx("WARNING: Partition `a' of `%s' exceeds 2GB boundary.",
183 warnx("WARNING: It won't boot since hp700 PDC can handle only 2GB.");
186 /* read boot loader */
187 memset(&bb
, 0, sizeof bb
);
188 rv
= read(params
->s1fd
, &bb
, sizeof bb
);
190 warn("Reading `%s'", params
->stage1
);
193 /* then, overwrite disklabel */
194 memcpy(&bb
[HP700_LABELOFFSET
], &label
.l
, HP700_LABELSIZE
);
196 if (params
->flags
& IB_VERBOSE
) {
197 printf("Bootstrap start sector: %#x\n", 0);
198 printf("Bootstrap byte count: %#zx\n", rv
);
199 printf("%sriting bootstrap\n",
200 (params
->flags
& IB_NOWRITE
) ? "Not w" : "W");
202 if (params
->flags
& IB_NOWRITE
) {
207 /* write boot loader and disklabel into the target disk */
208 rv
= pwrite(params
->fsfd
, &bb
, HP700_BOOT_BLOCK_SIZE
, 0);
210 warn("Writing `%s'", params
->filesystem
);
212 } else if (rv
!= HP700_BOOT_BLOCK_SIZE
) {
213 warnx("Writing `%s': short write", params
->filesystem
);