1 /* $NetBSD: md.c,v 1.14 2024/02/10 18:43:54 andvar 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 -- ofppc machine specific routines */
36
37 #include <sys/param.h>
38 #include <sys/sysctl.h>
39 #include <sys/disklabel_rdb.h>
40 #include <stdio.h>
41 #include <util.h>
42 #include <machine/cpu.h>
43
44 #include "defs.h"
45 #include "md.h"
46 #include "msg_defs.h"
47 #include "menu_defs.h"
48 #include "endian.h"
49
50 static int check_rdb(void);
51 static uint32_t rdbchksum(void *);
52
53 /* We use MBR_PTYPE_PREP like port-prep does. */
54 static int nonewfsmsdos = 0, nobootfix = 0, noprepfix=0;
55 static part_id bootpart_fat12 = NO_PART, bootpart_binfo = NO_PART,
56 bootpart_prep = NO_PART;
57 static int bootinfo_mbr = 1;
58 static int rdb_found = 0;
59
60 /* bootstart/bootsize are for the fat */
61 int binfostart, binfosize, bprepstart, bprepsize;
62
63 void
md_init(void)64 md_init(void)
65 {
66 }
67
68 void
md_init_set_status(int flags)69 md_init_set_status(int flags)
70 {
71
72 (void)flags;
73 }
74
75 bool
md_get_info(struct install_partition_desc * install)76 md_get_info(struct install_partition_desc *install)
77 {
78 int res;
79
80 if (check_rdb())
81 return true;
82
83
84 if (pm->no_mbr || pm->no_part)
85 return true;
86
87 again:
88 if (pm->parts == NULL) {
89
90 const struct disk_partitioning_scheme *ps =
91 select_part_scheme(pm, NULL, true, NULL);
92
93 if (!ps)
94 return false;
95
96 struct disk_partitions *parts =
97 (*ps->create_new_for_disk)(pm->diskdev,
98 0, pm->dlsize, true, NULL);
99 if (!parts)
100 return false;
101
102 pm->parts = parts;
103 if (ps->size_limit > 0 && pm->dlsize > ps->size_limit)
104 pm->dlsize = ps->size_limit;
105 }
106
107 res = set_bios_geom_with_mbr_guess(pm->parts);
108 if (res == 0)
109 return false;
110 else if (res == 1)
111 return true;
112
113 pm->parts->pscheme->destroy_part_scheme(pm->parts);
114 pm->parts = NULL;
115 goto again;
116 }
117
118 /*
119 * md back-end code for menu-driven BSD disklabel editor.
120 */
121 int
md_make_bsd_partitions(struct install_partition_desc * install)122 md_make_bsd_partitions(struct install_partition_desc *install)
123 {
124 #if 0
125 int i;
126 int part;
127 int maxpart = getmaxpartitions();
128 int partstart;
129 int part_raw, part_bsd;
130 int ptend;
131 int no_swap = 0;
132 #endif
133
134 if (rdb_found) {
135 #if 0
136 /*
137 * XXX - need to test on real machine if the disklabel code
138 * deals with RDB partitions properly, otherwise write
139 * a read-only RDB backend
140 */
141 /*
142 * We found RDB partitions on the disk, which cannot be
143 * modified by rewriting the disklabel.
144 * So just use what we have got.
145 */
146 for (part = 0; part < maxpart; part++) {
147 if (PI_ISBSDFS(&pm->bsdlabel[part])) {
148 pm->bsdlabel[part].pi_flags |=
149 PIF_NEWFS | PIF_MOUNT;
150
151 if (part == PART_A)
152 strcpy(pm->bsdlabel[part].pi_mount, "/");
153 }
154 }
155
156 part_bsd = part_raw = getrawpartition();
157 if (part_raw == -1)
158 part_raw = PART_C; /* for sanity... */
159 pm->bsdlabel[part_raw].pi_offset = 0;
160 pm->bsdlabel[part_raw].pi_size = pm->dlsize;
161
162 set_sizemultname_meg();
163 rdb_edit_check:
164 if (edit_and_check_label(pm->bsdlabel, maxpart, part_raw,
165 part_bsd) == 0) {
166 msg_display(MSG_abort);
167 return 0;
168 }
169 if (md_check_partitions() == 0)
170 goto rdb_edit_check;
171 #endif
172 return 1;
173 }
174
175 /*
176 * Initialize global variables that track space used on this disk.
177 * Standard 4.4BSD 8-partition labels always cover whole disk.
178 */
179 if (pm->ptsize == 0)
180 pm->ptsize = pm->dlsize - pm->ptstart;
181 if (pm->dlsize == 0)
182 pm->dlsize = pm->ptstart + pm->ptsize;
183
184 #if 0
185 partstart = pm->ptstart;
186 ptend = pm->ptstart + pm->ptsize;
187
188 /* Ask for layout type -- standard or special */
189 msg_fmt_display(MSG_layout, "%d%d%d",
190 pm->ptsize / (MEG / pm->sectorsize),
191 DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE,
192 DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE + XNEEDMB);
193
194 process_menu(MENU_layout, NULL);
195
196 /* Set so we use the 'real' geometry for rounding, input in MB */
197 pm->current_cylsize = pm->dlcylsize;
198 set_sizemultname_meg();
199
200 /* Build standard partitions */
201 memset(&pm->bsdlabel, 0, sizeof pm->bsdlabel);
202
203 /* Set initial partition types to unused */
204 for (part = 0 ; part < maxpart ; ++part)
205 pm->bsdlabel[part].pi_fstype = FS_UNUSED;
206
207 /* Whole disk partition */
208 part_raw = getrawpartition();
209 if (part_raw == -1)
210 part_raw = PART_C; /* for sanity... */
211 pm->bsdlabel[part_raw].pi_offset = 0;
212 pm->bsdlabel[part_raw].pi_size = pm->dlsize;
213
214 if (part_raw == PART_D) {
215 /* Probably a system that expects an i386 style mbr */
216 part_bsd = PART_C;
217 pm->bsdlabel[PART_C].pi_offset = pm->ptstart;
218 pm->bsdlabel[PART_C].pi_size = pm->ptsize;
219 } else {
220 part_bsd = part_raw;
221 }
222
223 if (pm->bootsize != 0) {
224 pm->bsdlabel[PART_BOOT_FAT12].pi_fstype = FS_MSDOS;
225 pm->bsdlabel[PART_BOOT_FAT12].pi_size = pm->bootsize;
226 pm->bsdlabel[PART_BOOT_FAT12].pi_offset = pm->bootstart;
227 pm->bsdlabel[PART_BOOT_FAT12].pi_flags |= PART_BOOT_FAT12_PI_FLAGS;
228 strlcpy(pm->bsdlabel[PART_BOOT_FAT12].pi_mount,
229 PART_BOOT_FAT12_PI_MOUNT,
230 sizeof pm->bsdlabel[PART_BOOT_FAT12].pi_mount);
231 }
232 if (binfosize != 0) {
233 pm->bsdlabel[PART_BOOT_BINFO].pi_fstype = FS_OTHER;
234 pm->bsdlabel[PART_BOOT_BINFO].pi_size = binfosize;
235 pm->bsdlabel[PART_BOOT_BINFO].pi_offset = binfostart;
236 }
237 if (bprepsize != 0) {
238 pm->bsdlabel[PART_BOOT_PREP].pi_fstype = FS_BOOT;
239 pm->bsdlabel[PART_BOOT_PREP].pi_size = bprepsize;
240 pm->bsdlabel[PART_BOOT_PREP].pi_offset = bprepstart;
241 }
242
243 #ifdef PART_REST
244 pm->bsdlabel[PART_REST].pi_offset = 0;
245 pm->bsdlabel[PART_REST].pi_size = pm->ptstart;
246 #endif
247
248 /*
249 * Save any partitions that are outside the area we are
250 * going to use.
251 * In particular this saves details of the other MBR
252 * partitions on a multiboot i386 system.
253 */
254 for (i = maxpart; i--;) {
255 if (pm->bsdlabel[i].pi_size != 0)
256 /* Don't overwrite special partitions */
257 continue;
258 p = &pm->oldlabel[i];
259 if (p->pi_fstype == FS_UNUSED || p->pi_size == 0)
260 continue;
261 if (layoutkind == LY_USEEXIST) {
262 if (PI_ISBSDFS(p))
263 p->pi_flags |= PIF_MOUNT;
264 } else {
265 if (p->pi_offset < pm->ptstart + pm->ptsize &&
266 p->pi_offset + p->pi_size > pm->ptstart)
267 /* Not outside area we are allocating */
268 continue;
269 if (p->pi_fstype == FS_SWAP)
270 no_swap = 1;
271 }
272 pm->bsdlabel[i] = pm->oldlabel[i];
273 }
274
275 if (layoutkind == LY_USEEXIST) {
276 /* XXX Check we have a sensible layout */
277 ;
278 } else
279 get_ptn_sizes(partstart, ptend - partstart, no_swap);
280
281 /*
282 * OK, we have a partition table. Give the user the chance to
283 * edit it and verify it's OK, or abort altogether.
284 */
285 edit_check:
286 if (edit_and_check_label(pm->bsdlabel, maxpart, part_raw, part_bsd) == 0) {
287 msg_display(MSG_abort);
288 return 0;
289 }
290 if (md_check_partitions() == 0)
291 goto edit_check;
292
293 /* Disk name */
294 msg_prompt(MSG_packname, pm->bsddiskname, pm->bsddiskname, sizeof pm->bsddiskname);
295
296 /* save label to disk for MI code to update. */
297 (void) savenewlabel(pm->bsdlabel, maxpart);
298
299 /* Everything looks OK. */
300 return 1;
301 #endif
302
303 return make_bsd_partitions(install);
304 }
305
306 /*
307 * any additional partition validation
308 */
309 bool
md_check_partitions(struct install_partition_desc * install)310 md_check_partitions(struct install_partition_desc *install)
311 {
312 struct disk_partitions *parts;
313 struct disk_part_info info;
314 int fprep=0, ffat=0;
315 part_id part;
316
317 if (rdb_found)
318 return 1;
319
320 if (install->num < 1)
321 return false;
322 parts = install->infos[0].parts; /* disklabel parts */
323 if (parts->parent)
324 parts = parts->parent; /* MBR parts */
325
326 /* we need to find a boot partition, otherwise we can't create
327 * our msdos fs boot partition. We make the assumption that
328 * the user hasn't done something stupid, like move it away
329 * from the MBR partition.
330 */
331 for (part = 0; part < parts->num_part; part++) {
332 if (!parts->pscheme->get_part_info(parts, part, &info))
333 continue;
334
335 if (info.fs_type == FS_MSDOS) {
336 bootpart_fat12 = part;
337 ffat++;
338 } else if (info.fs_type == FS_BOOT) {
339 bootpart_prep = part;
340 fprep++;
341 } else if (info.fs_type == FS_OTHER) {
342 bootpart_binfo = part;
343 fprep++;
344 }
345 }
346 /* oh, the confusion */
347 if (ffat >= 1 && fprep < 2) {
348 noprepfix = 1;
349 return true;
350 }
351 if (ffat < 1 && fprep >= 2) {
352 nobootfix = 1;
353 return true;
354 }
355 if (ffat >=1 && fprep >= 2) {
356 return true;
357 }
358
359 msg_display(MSG_nobootpartdisklabel);
360 process_menu(MENU_ok, NULL);
361 nobootfix = 1;
362 return false;
363 }
364
365 /*
366 * hook called before writing new disklabel.
367 */
368 bool
md_pre_disklabel(struct install_partition_desc * install,struct disk_partitions * parts)369 md_pre_disklabel(struct install_partition_desc *install,
370 struct disk_partitions *parts)
371 {
372
373 if (rdb_found)
374 return true;
375
376
377 if (parts->parent == NULL)
378 return true; /* no outer partitions */
379
380 parts = parts->parent;
381
382 msg_display_subst(MSG_dofdisk, 3, parts->disk,
383 msg_string(parts->pscheme->name),
384 msg_string(parts->pscheme->short_name));
385
386 /* write edited "MBR" onto disk. */
387 if (!parts->pscheme->write_to_disk(parts)) {
388 msg_display(MSG_wmbrfail);
389 process_menu(MENU_ok, NULL);
390 return false;
391 }
392 return true;
393 }
394
395 /*
396 * hook called after writing disklabel to new target disk.
397 */
398 bool
md_post_disklabel(struct install_partition_desc * install,struct disk_partitions * parts)399 md_post_disklabel(struct install_partition_desc *install,
400 struct disk_partitions *parts)
401 {
402 char bootdev[100];
403
404 if (pm->bootstart == 0 || pm->bootsize == 0 || rdb_found)
405 return 0;
406
407 snprintf(bootdev, sizeof bootdev, "/dev/r%s%c", pm->diskdev,
408 (char)('a'+bootpart_fat12));
409 run_program(RUN_DISPLAY, "/sbin/newfs_msdos %s", bootdev);
410
411 return 0;
412 }
413
414 /*
415 * hook called after upgrade() or install() has finished setting
416 * up the target disk but immediately before the user is given the
417 * ``disks are now set up'' message.
418 */
419 int
md_post_newfs(struct install_partition_desc * install)420 md_post_newfs(struct install_partition_desc *install)
421 {
422
423 /* No bootblock. We use ofwboot from a partition visiable by OFW. */
424 return 0;
425 }
426
427 int
md_post_extract(struct install_partition_desc * install,bool upgrade)428 md_post_extract(struct install_partition_desc *install, bool upgrade)
429 {
430 char bootdev[100], bootbdev[100], version[64];
431 struct disk_partitions *parts;
432
433 /* if we can't make it bootable, just punt */
434 if ((nobootfix && noprepfix) || rdb_found)
435 return 0;
436
437 snprintf(version, sizeof version, "NetBSD/%s %s", MACH, REL);
438 run_program(RUN_DISPLAY, "/usr/mdec/mkbootinfo '%s' %d "
439 "/tmp/bootinfo.txt", version, bootinfo_mbr);
440
441 if (!nobootfix) {
442 run_program(RUN_DISPLAY, "/bin/mkdir -p /%s/boot/ppc",
443 target_prefix());
444 run_program(RUN_DISPLAY, "/bin/mkdir -p /%s/boot/netbsd",
445 target_prefix());
446 run_program(RUN_DISPLAY, "/bin/cp /usr/mdec/ofwboot "
447 "/%s/boot/netbsd", target_prefix());
448 run_program(RUN_DISPLAY, "/bin/cp /tmp/bootinfo.txt "
449 "/%s/boot/ppc", target_prefix());
450 run_program(RUN_DISPLAY, "/bin/cp /usr/mdec/ofwboot "
451 "/%s/boot/ofwboot", target_prefix());
452 }
453
454 if (!noprepfix && install != NULL && install->num > 0) {
455 parts = install->infos[0].parts; /* disklabel */
456 if (parts->parent != NULL)
457 parts = parts->parent; /* MBR */
458
459 parts->pscheme->get_part_device(parts, bootpart_prep,
460 bootdev, sizeof bootdev, NULL, raw_dev_name, true, true);
461 parts->pscheme->get_part_device(parts, bootpart_prep,
462 bootbdev, sizeof bootbdev, NULL, plain_name, true, true);
463 run_program(RUN_DISPLAY, "/bin/dd if=/dev/zero of=%s bs=512",
464 bootdev);
465 run_program(RUN_DISPLAY, "/bin/dd if=/usr/mdec/ofwboot "
466 "of=%s bs=512", bootbdev);
467
468 parts->pscheme->get_part_device(parts, bootpart_binfo,
469 bootdev, sizeof bootdev, NULL, raw_dev_name, true, true);
470 parts->pscheme->get_part_device(parts, bootpart_binfo,
471 bootbdev, sizeof bootbdev, NULL, plain_name, true, true);
472 run_program(RUN_DISPLAY, "/bin/dd if=/dev/zero of=%s bs=512",
473 bootdev);
474 run_program(RUN_DISPLAY, "/bin/dd if=/tmp/bootinfo.txt "
475 "of=%s bs=512", bootbdev);
476 }
477
478 return 0;
479 }
480
481 void
md_cleanup_install(struct install_partition_desc * install)482 md_cleanup_install(struct install_partition_desc *install)
483 {
484
485 #ifndef DEBUG
486 enable_rc_conf();
487 #endif
488 }
489
490 int
md_pre_update(struct install_partition_desc * install)491 md_pre_update(struct install_partition_desc *install)
492 {
493 #if 0
494 struct mbr_partition *part;
495 mbr_info_t *ext;
496 int i;
497 #endif
498
499 if (check_rdb())
500 return 1;
501
502 #if 0
503 read_mbr(pm->diskdev, &mbr);
504 /* do a sanity check of the partition table */
505 for (ext = &mbr; ext; ext = ext->extended) {
506 part = ext->mbr.mbr_parts;
507 for (i = 0; i < MBR_PART_COUNT; part++, i++) {
508 if (part->mbrp_type == MBR_PTYPE_PREP &&
509 part->mbrp_size > 50)
510 bootinfo_mbr = i+1;
511 if (part->mbrp_type == MBR_PTYPE_RESERVED_x21 &&
512 part->mbrp_size < (MIN_FAT12_BOOT/512)) {
513 msg_display(MSG_boottoosmall);
514 msg_fmt_display_add(MSG_nobootpartdisklabel,
515 "%d", 0);
516 if (!ask_yesno(NULL))
517 return 0;
518 nobootfix = 1;
519 }
520 }
521 }
522 #endif
523
524 if (!md_check_partitions(install))
525 return 0;
526
527 return 1;
528 }
529
530 /* Upgrade support */
531 int
md_update(struct install_partition_desc * install)532 md_update(struct install_partition_desc *install)
533 {
534
535 nonewfsmsdos = 1;
536 md_post_newfs(install);
537 return 1;
538 }
539
540
541 int
md_check_mbr(struct disk_partitions * parts,mbr_info_t * mbri,bool quiet)542 md_check_mbr(struct disk_partitions *parts, mbr_info_t *mbri, bool quiet)
543 {
544 mbr_info_t *ext;
545 struct mbr_partition *part;
546 int i;
547
548 for (ext = mbri; ext; ext = ext->extended) {
549 part = ext->mbr.mbr_parts;
550 for (i = 0; i < MBR_PART_COUNT; part++, i++) {
551 if (part->mbrp_type == MBR_PTYPE_FAT12) {
552 pm->bootstart = part->mbrp_start;
553 pm->bootsize = part->mbrp_size;
554 } else if (part->mbrp_type == MBR_PTYPE_PREP &&
555 part->mbrp_size < 50) {
556 /* this is the bootinfo partition */
557 binfostart = part->mbrp_start;
558 binfosize = part->mbrp_size;
559 bootinfo_mbr = i+1;
560 } else if (part->mbrp_type == MBR_PTYPE_PREP &&
561 part->mbrp_size > 50) {
562 bprepstart = part->mbrp_start;
563 bprepsize = part->mbrp_size;
564 }
565 break;
566 }
567 }
568
569 /* we need to either have a pair of prep partitions, or a single
570 * fat. if neither, things are broken. */
571 if (!(pm->bootsize >= (MIN_FAT12_BOOT/512) ||
572 (binfosize >= (MIN_BINFO_BOOT/512) &&
573 bprepsize >= (MIN_PREP_BOOT/512)))) {
574 if (quiet)
575 return 0;
576 msg_display(MSG_bootnotright);
577 return ask_reedit(parts);
578 }
579
580 /* check the prep partitions */
581 if ((binfosize > 0 || bprepsize > 0) &&
582 (binfosize < (MIN_BINFO_BOOT/512) ||
583 bprepsize < (MIN_PREP_BOOT/512))) {
584 if (quiet)
585 return 0;
586 msg_display(MSG_preptoosmall);
587 return ask_reedit(parts);
588 }
589
590 /* check the fat12 partitions */
591 if (pm->bootsize > 0 && pm->bootsize < (MIN_FAT12_BOOT/512)) {
592 if (quiet)
593 return 0;
594 msg_display(MSG_boottoosmall);
595 return ask_reedit(parts);
596 }
597
598 /* if both sets contain zero, thats bad */
599 if ((pm->bootstart == 0 || pm->bootsize == 0) &&
600 (binfosize == 0 || binfostart == 0 ||
601 bprepsize == 0 || bprepstart == 0)) {
602 if (quiet)
603 return 0;
604 msg_display(MSG_nobootpart);
605 return ask_reedit(parts);
606 }
607 return 2;
608 }
609
610 /*
611 * NOTE, we use a reserved partition type, because some RS/6000 machines hang
612 * hard if they find a FAT12, and if we use type prep, that indicates that
613 * it should be read raw.
614 * One partition for FAT12 booting
615 * One partition for NetBSD
616 * One partition to hold the bootinfo.txt file
617 * One partition to hold ofwboot
618 */
619
620 bool
md_parts_use_wholedisk(struct disk_partitions * parts)621 md_parts_use_wholedisk(struct disk_partitions *parts)
622 {
623 struct disk_part_info boot_parts[] =
624 {
625 { .fs_type = FS_MSDOS, .size = FAT12_BOOT_SIZE/512 },
626 { .fs_type = FS_OTHER, .size = BINFO_BOOT_SIZE/512 },
627 { .fs_type = FS_BOOT, .size = PREP_BOOT_SIZE/512 }
628 };
629
630 return parts_use_wholedisk(parts, __arraycount(boot_parts),
631 boot_parts);
632 }
633
md_disklabel_cmd(void)634 const char *md_disklabel_cmd(void)
635 {
636
637 /* we cannot rewrite an RDB disklabel */
638 if (rdb_found)
639 return "sync No disklabel";
640
641 return "disklabel -w -r";
642 }
643
644 static int
check_rdb(void)645 check_rdb(void)
646 {
647 char buf[512], diskpath[MAXPATHLEN];
648 struct rdblock *rdb;
649 off_t blk;
650 int fd;
651
652 /* Find out if this disk has a valid RDB, before continuing. */
653 rdb = (struct rdblock *)buf;
654 fd = opendisk(pm->diskdev, O_RDONLY, diskpath, sizeof(diskpath), 0);
655 if (fd < 0)
656 return 0;
657 for (blk = 0; blk < RDB_MAXBLOCKS; blk++) {
658 if (pread(fd, rdb, 512, blk * 512) != 512)
659 return 0;
660 if (rdb->id == RDBLOCK_ID && rdbchksum(rdb) == 0) {
661 rdb_found = 1; /* do not repartition! */
662 return 1;
663 }
664 }
665 return 0;
666 }
667
668 static uint32_t
rdbchksum(void * bdata)669 rdbchksum(void *bdata)
670 {
671 uint32_t *blp, cnt, val;
672
673 blp = bdata;
674 cnt = blp[1];
675 val = 0;
676 while (cnt--)
677 val += *blp++;
678 return val;
679 }
680
681 int
md_pre_mount(struct install_partition_desc * install,size_t ndx)682 md_pre_mount(struct install_partition_desc *install, size_t ndx)
683 {
684
685 return 0;
686 }
687
688 bool
md_mbr_update_check(struct disk_partitions * parts,mbr_info_t * mbri)689 md_mbr_update_check(struct disk_partitions *parts, mbr_info_t *mbri)
690 {
691 return false; /* no change, no need to write back */
692 }
693
694 #ifdef HAVE_GPT
695 bool
md_gpt_post_write(struct disk_partitions * parts,part_id root_id,bool root_is_new,part_id efi_id,bool efi_is_new)696 md_gpt_post_write(struct disk_partitions *parts, part_id root_id,
697 bool root_is_new, part_id efi_id, bool efi_is_new)
698 {
699 /* no GPT boot support, nothing needs to be done here */
700 return true;
701 }
702 #endif
703
704