md.c revision 1.4 1 /* $NetBSD: md.c,v 1.4 2015/05/11 13:01:08 martin 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 (pm->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(pm->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 int contype;
142
143 /* if we can't make it bootable, just punt */
144 if (prep_nobootfix)
145 return 0;
146
147 process_menu(MENU_prepconsole, &contype);
148 if (contype == 1)
149 snprintf(bootloader, 100, "/usr/mdec/boot_com0");
150 else
151 snprintf(bootloader, 100, "/usr/mdec/boot");
152
153 snprintf(rawdev, 100, "/dev/r%s%c", pm->diskdev, 'a' + getrawpartition());
154 snprintf(bootpart, 100, "/dev/r%s%c", pm->diskdev, 'a' + prep_bootpart);
155 if (prep_rawdevfix)
156 run_program(RUN_DISPLAY|RUN_CHROOT,
157 "/usr/mdec/mkbootimage -b %s -k /netbsd "
158 "-r %s /.bootimage", bootloader, rawdev);
159 else
160 run_program(RUN_DISPLAY|RUN_CHROOT,
161 "/usr/mdec/mkbootimage -s -b %s -k /netbsd /.bootimage",
162 bootloader);
163 run_program(RUN_DISPLAY|RUN_CHROOT, "/bin/dd if=/.bootimage of=%s "
164 "bs=512 conv=sync", bootpart);
165
166 return 0;
167 }
168
169 void
170 md_cleanup_install(void)
171 {
172 #ifndef DEBUG
173 enable_rc_conf();
174 #endif
175 run_program(0, "rm -f %s", target_expand("/.bootimage"));
176 }
177
178 int
179 md_pre_update(void)
180 {
181 struct mbr_partition *part;
182 mbr_info_t *ext;
183 int i;
184
185 read_mbr(pm->diskdev, &mbr);
186 /* do a sanity check of the partition table */
187 for (ext = &mbr; ext; ext = ext->extended) {
188 part = ext->mbr.mbr_parts;
189 for (i = 0; i < MBR_PART_COUNT; part++, i++) {
190 if (part->mbrp_type != MBR_PTYPE_PREP)
191 continue;
192 if (part->mbrp_size < (MIN_PREP_BOOT/512)) {
193 msg_display(MSG_preptoosmall);
194 msg_display_add(MSG_prepnobootpart, 0);
195 if (!ask_yesno(NULL))
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 pm->bootstart = part->mbrp_start;
229 pm->bootsize = part->mbrp_size;
230 break;
231 }
232 }
233 if (pm->bootsize < (MIN_PREP_BOOT/512)) {
234 msg_display(MSG_preptoosmall);
235 msg_display_add(MSG_reeditpart, 0);
236 if (!ask_yesno(NULL))
237 return 0;
238 return 1;
239 }
240 if (pm->bootstart == 0 || pm->bootsize == 0) {
241 msg_display(MSG_nopreppart);
242 msg_display_add(MSG_reeditpart, 0);
243 if (!ask_yesno(NULL))
244 return 0;
245 return 1;
246 }
247 return 2;
248 }
249
250 int
251 md_mbr_use_wholedisk(mbr_info_t *mbri)
252 {
253 struct mbr_sector *mbrs = &mbri->mbr;
254 mbr_info_t *ext;
255 struct mbr_partition *part;
256
257 part = &mbrs->mbr_parts[0];
258 /* Set the partition information for full disk usage. */
259 while ((ext = mbri->extended)) {
260 mbri->extended = ext->extended;
261 free(ext);
262 }
263 memset(part, 0, MBR_PART_COUNT * sizeof *part);
264 #ifdef BOOTSEL
265 memset(&mbri->mbrb, 0, sizeof mbri->mbrb);
266 #endif
267 part[0].mbrp_type = MBR_PTYPE_PREP;
268 part[0].mbrp_size = PREP_BOOT_SIZE/512;
269 part[0].mbrp_start = bsec;
270 part[0].mbrp_flag = MBR_PFLAG_ACTIVE;
271
272 part[1].mbrp_type = MBR_PTYPE_NETBSD;
273 part[1].mbrp_size = pm->dlsize - (bsec + PREP_BOOT_SIZE/512);
274 part[1].mbrp_start = bsec + PREP_BOOT_SIZE/512;
275 part[1].mbrp_flag = 0;
276
277 pm->ptstart = part[1].mbrp_start;
278 pm->ptsize = part[1].mbrp_size;
279 pm->bootstart = part[0].mbrp_start;
280 pm->bootsize = part[0].mbrp_size;
281 return 1;
282 }
283
284
285 int
286 md_pre_mount()
287 {
288 return 0;
289 }
290