md.c revision 1.1 1 /* $NetBSD: md.c,v 1.1 2014/07/26 19:30:46 dholland Exp $ */
2
3 /*
4 * Copyright 1997 Piermont Information Systems Inc.
5 * All rights reserved.
6 *
7 * Based on code written by Philip A. Nelson for Piermont Information
8 * Systems Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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.
18 * 3. The name of Piermont Information Systems Inc. may not be used to endorse
19 * or promote products derived from this software without specific prior
20 * written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /* md.c -- prep machine specific routines */
36
37 #include <sys/param.h>
38 #include <sys/sysctl.h>
39 #include <stdio.h>
40 #include <util.h>
41 #include <machine/cpu.h>
42
43 #include "defs.h"
44 #include "md.h"
45 #include "msg_defs.h"
46 #include "menu_defs.h"
47 #include "endian.h"
48
49 int prep_nobootfix = 0, prep_rawdevfix = 0, prep_bootpart = PART_BOOT;
50
51 void
52 md_init(void)
53 {
54 }
55
56 void
57 md_init_set_status(int flags)
58 {
59 (void)flags;
60 }
61
62 int
63 md_get_info(void)
64 {
65 return set_bios_geom_with_mbr_guess();
66 }
67
68 /*
69 * md back-end code for menu-driven BSD disklabel editor.
70 */
71 int
72 md_make_bsd_partitions(void)
73 {
74 return make_bsd_partitions();
75 }
76
77 /*
78 * any additional partition validation
79 */
80 int
81 md_check_partitions(void)
82 {
83 int part;
84
85 /* we need to find a boot partition, otherwise we can't write our
86 * "bootblock". We make the assumption that the user hasn't done
87 * something stupid, like move it away from the MBR partition.
88 */
89 for (part = PART_A; part < MAXPARTITIONS; part++)
90 if (bsdlabel[part].pi_fstype == FS_BOOT) {
91 prep_bootpart = part;
92 return 1;
93 }
94
95 msg_display(MSG_prepnobootpart);
96 process_menu(MENU_ok, NULL);
97 return 0;
98 }
99
100 /*
101 * hook called before writing new disklabel.
102 */
103 int
104 md_pre_disklabel(void)
105 {
106 msg_display(MSG_dofdisk);
107
108 /* write edited MBR onto disk. */
109 if (write_mbr(diskdev, &mbr, 1) != 0) {
110 msg_display(MSG_wmbrfail);
111 process_menu(MENU_ok, NULL);
112 return 1;
113 }
114 return 0;
115 }
116
117 /*
118 * hook called after writing disklabel to new target disk.
119 */
120 int
121 md_post_disklabel(void)
122 {
123 return 0;
124 }
125
126 /*
127 * hook called after upgrade() or install() has finished setting
128 * up the target disk but immediately before the user is given the
129 * ``disks are now set up'' message.
130 */
131 int
132 md_post_newfs(void)
133 {
134 return 0;
135 }
136
137 int
138 md_post_extract(void)
139 {
140 char rawdev[100], bootpart[100], bootloader[100];
141
142 /* if we can't make it bootable, just punt */
143 if (prep_nobootfix)
144 return 0;
145
146 process_menu(MENU_prepconsole, NULL);
147 if (yesno == 1)
148 snprintf(bootloader, 100, "/usr/mdec/boot_com0");
149 else
150 snprintf(bootloader, 100, "/usr/mdec/boot");
151
152 snprintf(rawdev, 100, "/dev/r%s%c", diskdev, 'a' + getrawpartition());
153 snprintf(bootpart, 100, "/dev/r%s%c", diskdev, 'a' + prep_bootpart);
154 if (prep_rawdevfix)
155 run_program(RUN_DISPLAY|RUN_CHROOT,
156 "/usr/mdec/mkbootimage -b %s -k /netbsd "
157 "-r %s /.bootimage", bootloader, rawdev);
158 else
159 run_program(RUN_DISPLAY|RUN_CHROOT,
160 "/usr/mdec/mkbootimage -s -b %s -k /netbsd /.bootimage",
161 bootloader);
162 run_program(RUN_DISPLAY|RUN_CHROOT, "/bin/dd if=/.bootimage of=%s "
163 "bs=512 conv=sync", bootpart);
164
165 return 0;
166 }
167
168 void
169 md_cleanup_install(void)
170 {
171 #ifndef DEBUG
172 enable_rc_conf();
173 #endif
174 run_program(0, "rm -f %s", target_expand("/.bootimage"));
175 }
176
177 int
178 md_pre_update(void)
179 {
180 struct mbr_partition *part;
181 mbr_info_t *ext;
182 int i;
183
184 read_mbr(diskdev, &mbr);
185 /* do a sanity check of the partition table */
186 for (ext = &mbr; ext; ext = ext->extended) {
187 part = ext->mbr.mbr_parts;
188 for (i = 0; i < MBR_PART_COUNT; part++, i++) {
189 if (part->mbrp_type != MBR_PTYPE_PREP)
190 continue;
191 if (part->mbrp_size < (MIN_PREP_BOOT/512)) {
192 msg_display(MSG_preptoosmall);
193 msg_display_add(MSG_prepnobootpart, 0);
194 process_menu(MENU_yesno, NULL);
195 if (!yesno)
196 return 0;
197 prep_nobootfix = 1;
198 }
199 if (part->mbrp_start == 0)
200 prep_rawdevfix = 1;
201 }
202 }
203 if (md_check_partitions() == 0)
204 prep_nobootfix = 1;
205 return 1;
206 }
207
208 /* Upgrade support */
209 int
210 md_update(void)
211 {
212 md_post_newfs();
213 return 1;
214 }
215
216 int
217 md_check_mbr(mbr_info_t *mbri)
218 {
219 mbr_info_t *ext;
220 struct mbr_partition *part;
221 int i;
222
223 for (ext = mbri; ext; ext = ext->extended) {
224 part = ext->mbr.mbr_parts;
225 for (i = 0; i < MBR_PART_COUNT; part++, i++) {
226 if (part->mbrp_type != MBR_PTYPE_PREP)
227 continue;
228 bootstart = part->mbrp_start;
229 bootsize = part->mbrp_size;
230 break;
231 }
232 }
233 if (bootsize < (MIN_PREP_BOOT/512)) {
234 msg_display(MSG_preptoosmall);
235 msg_display_add(MSG_reeditpart, 0);
236 process_menu(MENU_yesno, NULL);
237 if (!yesno)
238 return 0;
239 return 1;
240 }
241 if (bootstart == 0 || bootsize == 0) {
242 msg_display(MSG_nopreppart);
243 msg_display_add(MSG_reeditpart, 0);
244 process_menu(MENU_yesno, NULL);
245 if (!yesno)
246 return 0;
247 return 1;
248 }
249 return 2;
250 }
251
252 int
253 md_mbr_use_wholedisk(mbr_info_t *mbri)
254 {
255 struct mbr_sector *mbrs = &mbri->mbr;
256 mbr_info_t *ext;
257 struct mbr_partition *part;
258
259 part = &mbrs->mbr_parts[0];
260 /* Set the partition information for full disk usage. */
261 while ((ext = mbri->extended)) {
262 mbri->extended = ext->extended;
263 free(ext);
264 }
265 memset(part, 0, MBR_PART_COUNT * sizeof *part);
266 #ifdef BOOTSEL
267 memset(&mbri->mbrb, 0, sizeof mbri->mbrb);
268 #endif
269 part[0].mbrp_type = MBR_PTYPE_PREP;
270 part[0].mbrp_size = PREP_BOOT_SIZE/512;
271 part[0].mbrp_start = bsec;
272 part[0].mbrp_flag = MBR_PFLAG_ACTIVE;
273
274 part[1].mbrp_type = MBR_PTYPE_NETBSD;
275 part[1].mbrp_size = dlsize - (bsec + PREP_BOOT_SIZE/512);
276 part[1].mbrp_start = bsec + PREP_BOOT_SIZE/512;
277 part[1].mbrp_flag = 0;
278
279 ptstart = part[1].mbrp_start;
280 ptsize = part[1].mbrp_size;
281 bootstart = part[0].mbrp_start;
282 bootsize = part[0].mbrp_size;
283 return 1;
284 }
285
286
287 int
288 md_pre_mount()
289 {
290 return 0;
291 }
292