1*1cd43426Sandvar /* $NetBSD: md.c,v 1.14 2024/02/10 18:43:54 andvar Exp $ */
250dbef1aSdholland
350dbef1aSdholland /*
450dbef1aSdholland * Copyright 1997 Piermont Information Systems Inc.
550dbef1aSdholland * All rights reserved.
650dbef1aSdholland *
750dbef1aSdholland * Based on code written by Philip A. Nelson for Piermont Information
850dbef1aSdholland * Systems Inc.
950dbef1aSdholland *
1050dbef1aSdholland * Redistribution and use in source and binary forms, with or without
1150dbef1aSdholland * modification, are permitted provided that the following conditions
1250dbef1aSdholland * are met:
1350dbef1aSdholland * 1. Redistributions of source code must retain the above copyright
1450dbef1aSdholland * notice, this list of conditions and the following disclaimer.
1550dbef1aSdholland * 2. Redistributions in binary form must reproduce the above copyright
1650dbef1aSdholland * notice, this list of conditions and the following disclaimer in the
1750dbef1aSdholland * documentation and/or other materials provided with the distribution.
1850dbef1aSdholland * 3. The name of Piermont Information Systems Inc. may not be used to endorse
1950dbef1aSdholland * or promote products derived from this software without specific prior
2050dbef1aSdholland * written permission.
2150dbef1aSdholland *
2250dbef1aSdholland * THIS SOFTWARE IS PROVIDED BY PIERMONT INFORMATION SYSTEMS INC. ``AS IS''
2350dbef1aSdholland * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2450dbef1aSdholland * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2550dbef1aSdholland * ARE DISCLAIMED. IN NO EVENT SHALL PIERMONT INFORMATION SYSTEMS INC. BE
2650dbef1aSdholland * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2750dbef1aSdholland * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2850dbef1aSdholland * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2950dbef1aSdholland * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3050dbef1aSdholland * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3150dbef1aSdholland * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
3250dbef1aSdholland * THE POSSIBILITY OF SUCH DAMAGE.
3350dbef1aSdholland */
3450dbef1aSdholland
3550dbef1aSdholland /* md.c -- ofppc machine specific routines */
3650dbef1aSdholland
3750dbef1aSdholland #include <sys/param.h>
3850dbef1aSdholland #include <sys/sysctl.h>
3950dbef1aSdholland #include <sys/disklabel_rdb.h>
4050dbef1aSdholland #include <stdio.h>
4150dbef1aSdholland #include <util.h>
4250dbef1aSdholland #include <machine/cpu.h>
4350dbef1aSdholland
4450dbef1aSdholland #include "defs.h"
4550dbef1aSdholland #include "md.h"
4650dbef1aSdholland #include "msg_defs.h"
4750dbef1aSdholland #include "menu_defs.h"
4850dbef1aSdholland #include "endian.h"
4950dbef1aSdholland
5050dbef1aSdholland static int check_rdb(void);
5150dbef1aSdholland static uint32_t rdbchksum(void *);
5250dbef1aSdholland
5350dbef1aSdholland /* We use MBR_PTYPE_PREP like port-prep does. */
5450dbef1aSdholland static int nonewfsmsdos = 0, nobootfix = 0, noprepfix=0;
554103857bSmartin static part_id bootpart_fat12 = NO_PART, bootpart_binfo = NO_PART,
564103857bSmartin bootpart_prep = NO_PART;
5750dbef1aSdholland static int bootinfo_mbr = 1;
5850dbef1aSdholland static int rdb_found = 0;
5950dbef1aSdholland
6050dbef1aSdholland /* bootstart/bootsize are for the fat */
6150dbef1aSdholland int binfostart, binfosize, bprepstart, bprepsize;
6250dbef1aSdholland
6350dbef1aSdholland void
md_init(void)6450dbef1aSdholland md_init(void)
6550dbef1aSdholland {
6650dbef1aSdholland }
6750dbef1aSdholland
6850dbef1aSdholland void
md_init_set_status(int flags)6950dbef1aSdholland md_init_set_status(int flags)
7050dbef1aSdholland {
7150dbef1aSdholland
7250dbef1aSdholland (void)flags;
7350dbef1aSdholland }
7450dbef1aSdholland
754103857bSmartin bool
md_get_info(struct install_partition_desc * install)764103857bSmartin md_get_info(struct install_partition_desc *install)
7750dbef1aSdholland {
78957b5cd6Smartin int res;
7950dbef1aSdholland
8050dbef1aSdholland if (check_rdb())
814103857bSmartin return true;
8250dbef1aSdholland
83e11b8d25Smartin
84e11b8d25Smartin if (pm->no_mbr || pm->no_part)
85e11b8d25Smartin return true;
86e11b8d25Smartin
870d9613faSmartin again:
88e11b8d25Smartin if (pm->parts == NULL) {
89e11b8d25Smartin
90e11b8d25Smartin const struct disk_partitioning_scheme *ps =
91e11b8d25Smartin select_part_scheme(pm, NULL, true, NULL);
92e11b8d25Smartin
93e11b8d25Smartin if (!ps)
946fec6798Smartin return false;
95e11b8d25Smartin
96e11b8d25Smartin struct disk_partitions *parts =
97e11b8d25Smartin (*ps->create_new_for_disk)(pm->diskdev,
9886906049Smartin 0, pm->dlsize, true, NULL);
99e11b8d25Smartin if (!parts)
100e11b8d25Smartin return false;
101e11b8d25Smartin
102e11b8d25Smartin pm->parts = parts;
103e11b8d25Smartin if (ps->size_limit > 0 && pm->dlsize > ps->size_limit)
104e11b8d25Smartin pm->dlsize = ps->size_limit;
105e11b8d25Smartin }
106e11b8d25Smartin
107957b5cd6Smartin res = set_bios_geom_with_mbr_guess(pm->parts);
108957b5cd6Smartin if (res == 0)
109957b5cd6Smartin return false;
110957b5cd6Smartin else if (res == 1)
111957b5cd6Smartin return true;
112957b5cd6Smartin
113957b5cd6Smartin pm->parts->pscheme->destroy_part_scheme(pm->parts);
114957b5cd6Smartin pm->parts = NULL;
115957b5cd6Smartin goto again;
11650dbef1aSdholland }
11750dbef1aSdholland
11850dbef1aSdholland /*
11950dbef1aSdholland * md back-end code for menu-driven BSD disklabel editor.
12050dbef1aSdholland */
121957b5cd6Smartin int
md_make_bsd_partitions(struct install_partition_desc * install)1224103857bSmartin md_make_bsd_partitions(struct install_partition_desc *install)
12350dbef1aSdholland {
1244103857bSmartin #if 0
12550dbef1aSdholland int i;
12650dbef1aSdholland int part;
12750dbef1aSdholland int maxpart = getmaxpartitions();
12850dbef1aSdholland int partstart;
12950dbef1aSdholland int part_raw, part_bsd;
13050dbef1aSdholland int ptend;
13150dbef1aSdholland int no_swap = 0;
1324103857bSmartin #endif
13350dbef1aSdholland
13450dbef1aSdholland if (rdb_found) {
1354103857bSmartin #if 0
1364103857bSmartin /*
1374103857bSmartin * XXX - need to test on real machine if the disklabel code
1384103857bSmartin * deals with RDB partitions properly, otherwise write
1394103857bSmartin * a read-only RDB backend
1404103857bSmartin */
14150dbef1aSdholland /*
14250dbef1aSdholland * We found RDB partitions on the disk, which cannot be
14350dbef1aSdholland * modified by rewriting the disklabel.
14450dbef1aSdholland * So just use what we have got.
14550dbef1aSdholland */
14650dbef1aSdholland for (part = 0; part < maxpart; part++) {
1474b2364d9Smartin if (PI_ISBSDFS(&pm->bsdlabel[part])) {
1484b2364d9Smartin pm->bsdlabel[part].pi_flags |=
14950dbef1aSdholland PIF_NEWFS | PIF_MOUNT;
15050dbef1aSdholland
15150dbef1aSdholland if (part == PART_A)
1524b2364d9Smartin strcpy(pm->bsdlabel[part].pi_mount, "/");
15350dbef1aSdholland }
15450dbef1aSdholland }
15550dbef1aSdholland
15650dbef1aSdholland part_bsd = part_raw = getrawpartition();
15750dbef1aSdholland if (part_raw == -1)
15850dbef1aSdholland part_raw = PART_C; /* for sanity... */
1594b2364d9Smartin pm->bsdlabel[part_raw].pi_offset = 0;
1604b2364d9Smartin pm->bsdlabel[part_raw].pi_size = pm->dlsize;
16150dbef1aSdholland
16250dbef1aSdholland set_sizemultname_meg();
16350dbef1aSdholland rdb_edit_check:
1644b2364d9Smartin if (edit_and_check_label(pm->bsdlabel, maxpart, part_raw,
16550dbef1aSdholland part_bsd) == 0) {
16650dbef1aSdholland msg_display(MSG_abort);
16750dbef1aSdholland return 0;
16850dbef1aSdholland }
16950dbef1aSdholland if (md_check_partitions() == 0)
17050dbef1aSdholland goto rdb_edit_check;
1714103857bSmartin #endif
17250dbef1aSdholland return 1;
17350dbef1aSdholland }
17450dbef1aSdholland
17550dbef1aSdholland /*
17650dbef1aSdholland * Initialize global variables that track space used on this disk.
17750dbef1aSdholland * Standard 4.4BSD 8-partition labels always cover whole disk.
17850dbef1aSdholland */
1794b2364d9Smartin if (pm->ptsize == 0)
1804b2364d9Smartin pm->ptsize = pm->dlsize - pm->ptstart;
1814b2364d9Smartin if (pm->dlsize == 0)
1824b2364d9Smartin pm->dlsize = pm->ptstart + pm->ptsize;
18350dbef1aSdholland
1844103857bSmartin #if 0
1854b2364d9Smartin partstart = pm->ptstart;
1864b2364d9Smartin ptend = pm->ptstart + pm->ptsize;
18750dbef1aSdholland
18850dbef1aSdholland /* Ask for layout type -- standard or special */
18924ecf24eSchristos msg_fmt_display(MSG_layout, "%d%d%d",
1904b2364d9Smartin pm->ptsize / (MEG / pm->sectorsize),
19150dbef1aSdholland DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE,
19250dbef1aSdholland DEFROOTSIZE + DEFSWAPSIZE + DEFUSRSIZE + XNEEDMB);
19350dbef1aSdholland
19450dbef1aSdholland process_menu(MENU_layout, NULL);
19550dbef1aSdholland
19650dbef1aSdholland /* Set so we use the 'real' geometry for rounding, input in MB */
1974b2364d9Smartin pm->current_cylsize = pm->dlcylsize;
19850dbef1aSdholland set_sizemultname_meg();
19950dbef1aSdholland
20050dbef1aSdholland /* Build standard partitions */
2014b2364d9Smartin memset(&pm->bsdlabel, 0, sizeof pm->bsdlabel);
20250dbef1aSdholland
20350dbef1aSdholland /* Set initial partition types to unused */
20450dbef1aSdholland for (part = 0 ; part < maxpart ; ++part)
2054b2364d9Smartin pm->bsdlabel[part].pi_fstype = FS_UNUSED;
20650dbef1aSdholland
20750dbef1aSdholland /* Whole disk partition */
20850dbef1aSdholland part_raw = getrawpartition();
20950dbef1aSdholland if (part_raw == -1)
21050dbef1aSdholland part_raw = PART_C; /* for sanity... */
2114b2364d9Smartin pm->bsdlabel[part_raw].pi_offset = 0;
2124b2364d9Smartin pm->bsdlabel[part_raw].pi_size = pm->dlsize;
21350dbef1aSdholland
21450dbef1aSdholland if (part_raw == PART_D) {
21550dbef1aSdholland /* Probably a system that expects an i386 style mbr */
21650dbef1aSdholland part_bsd = PART_C;
2174b2364d9Smartin pm->bsdlabel[PART_C].pi_offset = pm->ptstart;
2184b2364d9Smartin pm->bsdlabel[PART_C].pi_size = pm->ptsize;
21950dbef1aSdholland } else {
22050dbef1aSdholland part_bsd = part_raw;
22150dbef1aSdholland }
22250dbef1aSdholland
2234b2364d9Smartin if (pm->bootsize != 0) {
2244b2364d9Smartin pm->bsdlabel[PART_BOOT_FAT12].pi_fstype = FS_MSDOS;
2254b2364d9Smartin pm->bsdlabel[PART_BOOT_FAT12].pi_size = pm->bootsize;
2264b2364d9Smartin pm->bsdlabel[PART_BOOT_FAT12].pi_offset = pm->bootstart;
2274b2364d9Smartin pm->bsdlabel[PART_BOOT_FAT12].pi_flags |= PART_BOOT_FAT12_PI_FLAGS;
2284b2364d9Smartin strlcpy(pm->bsdlabel[PART_BOOT_FAT12].pi_mount,
22950dbef1aSdholland PART_BOOT_FAT12_PI_MOUNT,
2304b2364d9Smartin sizeof pm->bsdlabel[PART_BOOT_FAT12].pi_mount);
23150dbef1aSdholland }
23250dbef1aSdholland if (binfosize != 0) {
2334b2364d9Smartin pm->bsdlabel[PART_BOOT_BINFO].pi_fstype = FS_OTHER;
2344b2364d9Smartin pm->bsdlabel[PART_BOOT_BINFO].pi_size = binfosize;
2354b2364d9Smartin pm->bsdlabel[PART_BOOT_BINFO].pi_offset = binfostart;
23650dbef1aSdholland }
23750dbef1aSdholland if (bprepsize != 0) {
2384b2364d9Smartin pm->bsdlabel[PART_BOOT_PREP].pi_fstype = FS_BOOT;
2394b2364d9Smartin pm->bsdlabel[PART_BOOT_PREP].pi_size = bprepsize;
2404b2364d9Smartin pm->bsdlabel[PART_BOOT_PREP].pi_offset = bprepstart;
24150dbef1aSdholland }
24250dbef1aSdholland
24350dbef1aSdholland #ifdef PART_REST
2444b2364d9Smartin pm->bsdlabel[PART_REST].pi_offset = 0;
2454b2364d9Smartin pm->bsdlabel[PART_REST].pi_size = pm->ptstart;
24650dbef1aSdholland #endif
24750dbef1aSdholland
24850dbef1aSdholland /*
24950dbef1aSdholland * Save any partitions that are outside the area we are
25050dbef1aSdholland * going to use.
25150dbef1aSdholland * In particular this saves details of the other MBR
25250dbef1aSdholland * partitions on a multiboot i386 system.
25350dbef1aSdholland */
25450dbef1aSdholland for (i = maxpart; i--;) {
2554b2364d9Smartin if (pm->bsdlabel[i].pi_size != 0)
25650dbef1aSdholland /* Don't overwrite special partitions */
25750dbef1aSdholland continue;
2584b2364d9Smartin p = &pm->oldlabel[i];
25950dbef1aSdholland if (p->pi_fstype == FS_UNUSED || p->pi_size == 0)
26050dbef1aSdholland continue;
2614b2364d9Smartin if (layoutkind == LY_USEEXIST) {
26250dbef1aSdholland if (PI_ISBSDFS(p))
26350dbef1aSdholland p->pi_flags |= PIF_MOUNT;
26450dbef1aSdholland } else {
2654b2364d9Smartin if (p->pi_offset < pm->ptstart + pm->ptsize &&
2664b2364d9Smartin p->pi_offset + p->pi_size > pm->ptstart)
26750dbef1aSdholland /* Not outside area we are allocating */
26850dbef1aSdholland continue;
26950dbef1aSdholland if (p->pi_fstype == FS_SWAP)
27050dbef1aSdholland no_swap = 1;
27150dbef1aSdholland }
2724b2364d9Smartin pm->bsdlabel[i] = pm->oldlabel[i];
27350dbef1aSdholland }
27450dbef1aSdholland
2754b2364d9Smartin if (layoutkind == LY_USEEXIST) {
27650dbef1aSdholland /* XXX Check we have a sensible layout */
27750dbef1aSdholland ;
27850dbef1aSdholland } else
27950dbef1aSdholland get_ptn_sizes(partstart, ptend - partstart, no_swap);
28050dbef1aSdholland
28150dbef1aSdholland /*
28250dbef1aSdholland * OK, we have a partition table. Give the user the chance to
28350dbef1aSdholland * edit it and verify it's OK, or abort altogether.
28450dbef1aSdholland */
28550dbef1aSdholland edit_check:
2864b2364d9Smartin if (edit_and_check_label(pm->bsdlabel, maxpart, part_raw, part_bsd) == 0) {
28750dbef1aSdholland msg_display(MSG_abort);
28850dbef1aSdholland return 0;
28950dbef1aSdholland }
29050dbef1aSdholland if (md_check_partitions() == 0)
29150dbef1aSdholland goto edit_check;
29250dbef1aSdholland
29350dbef1aSdholland /* Disk name */
2944b2364d9Smartin msg_prompt(MSG_packname, pm->bsddiskname, pm->bsddiskname, sizeof pm->bsddiskname);
29550dbef1aSdholland
29650dbef1aSdholland /* save label to disk for MI code to update. */
2974b2364d9Smartin (void) savenewlabel(pm->bsdlabel, maxpart);
29850dbef1aSdholland
29950dbef1aSdholland /* Everything looks OK. */
30050dbef1aSdholland return 1;
3014103857bSmartin #endif
3024103857bSmartin
3034103857bSmartin return make_bsd_partitions(install);
30450dbef1aSdholland }
30550dbef1aSdholland
30650dbef1aSdholland /*
30750dbef1aSdholland * any additional partition validation
30850dbef1aSdholland */
3094103857bSmartin bool
md_check_partitions(struct install_partition_desc * install)3104103857bSmartin md_check_partitions(struct install_partition_desc *install)
31150dbef1aSdholland {
3124103857bSmartin struct disk_partitions *parts;
3134103857bSmartin struct disk_part_info info;
3144103857bSmartin int fprep=0, ffat=0;
3154103857bSmartin part_id part;
31650dbef1aSdholland
31750dbef1aSdholland if (rdb_found)
31850dbef1aSdholland return 1;
31950dbef1aSdholland
3204103857bSmartin if (install->num < 1)
3214103857bSmartin return false;
3224103857bSmartin parts = install->infos[0].parts; /* disklabel parts */
3234103857bSmartin if (parts->parent)
3244103857bSmartin parts = parts->parent; /* MBR parts */
3254103857bSmartin
32650dbef1aSdholland /* we need to find a boot partition, otherwise we can't create
32750dbef1aSdholland * our msdos fs boot partition. We make the assumption that
32850dbef1aSdholland * the user hasn't done something stupid, like move it away
32950dbef1aSdholland * from the MBR partition.
33050dbef1aSdholland */
3314103857bSmartin for (part = 0; part < parts->num_part; part++) {
3324103857bSmartin if (!parts->pscheme->get_part_info(parts, part, &info))
3334103857bSmartin continue;
3344103857bSmartin
3354103857bSmartin if (info.fs_type == FS_MSDOS) {
33650dbef1aSdholland bootpart_fat12 = part;
33750dbef1aSdholland ffat++;
3384103857bSmartin } else if (info.fs_type == FS_BOOT) {
33950dbef1aSdholland bootpart_prep = part;
34050dbef1aSdholland fprep++;
3414103857bSmartin } else if (info.fs_type == FS_OTHER) {
34250dbef1aSdholland bootpart_binfo = part;
34350dbef1aSdholland fprep++;
34450dbef1aSdholland }
34550dbef1aSdholland }
34650dbef1aSdholland /* oh, the confusion */
3474103857bSmartin if (ffat >= 1 && fprep < 2) {
3484103857bSmartin noprepfix = 1;
3494103857bSmartin return true;
3504103857bSmartin }
3514103857bSmartin if (ffat < 1 && fprep >= 2) {
3524103857bSmartin nobootfix = 1;
3534103857bSmartin return true;
3544103857bSmartin }
3554103857bSmartin if (ffat >=1 && fprep >= 2) {
3564103857bSmartin return true;
3574103857bSmartin }
35850dbef1aSdholland
35950dbef1aSdholland msg_display(MSG_nobootpartdisklabel);
36050dbef1aSdholland process_menu(MENU_ok, NULL);
3614103857bSmartin nobootfix = 1;
3624103857bSmartin return false;
36350dbef1aSdholland }
36450dbef1aSdholland
36550dbef1aSdholland /*
36650dbef1aSdholland * hook called before writing new disklabel.
36750dbef1aSdholland */
3684103857bSmartin bool
md_pre_disklabel(struct install_partition_desc * install,struct disk_partitions * parts)3694103857bSmartin md_pre_disklabel(struct install_partition_desc *install,
3704103857bSmartin struct disk_partitions *parts)
37150dbef1aSdholland {
37250dbef1aSdholland
37350dbef1aSdholland if (rdb_found)
3744103857bSmartin return true;
37550dbef1aSdholland
37650dbef1aSdholland
3774103857bSmartin if (parts->parent == NULL)
3784103857bSmartin return true; /* no outer partitions */
3794103857bSmartin
3804103857bSmartin parts = parts->parent;
3814103857bSmartin
3824103857bSmartin msg_display_subst(MSG_dofdisk, 3, parts->disk,
3834103857bSmartin msg_string(parts->pscheme->name),
3844103857bSmartin msg_string(parts->pscheme->short_name));
3854103857bSmartin
3864103857bSmartin /* write edited "MBR" onto disk. */
3874103857bSmartin if (!parts->pscheme->write_to_disk(parts)) {
38850dbef1aSdholland msg_display(MSG_wmbrfail);
38950dbef1aSdholland process_menu(MENU_ok, NULL);
3904103857bSmartin return false;
39150dbef1aSdholland }
3924103857bSmartin return true;
39350dbef1aSdholland }
39450dbef1aSdholland
39550dbef1aSdholland /*
39650dbef1aSdholland * hook called after writing disklabel to new target disk.
39750dbef1aSdholland */
3984103857bSmartin bool
md_post_disklabel(struct install_partition_desc * install,struct disk_partitions * parts)3994103857bSmartin md_post_disklabel(struct install_partition_desc *install,
4004103857bSmartin struct disk_partitions *parts)
40150dbef1aSdholland {
40250dbef1aSdholland char bootdev[100];
40350dbef1aSdholland
4044b2364d9Smartin if (pm->bootstart == 0 || pm->bootsize == 0 || rdb_found)
40550dbef1aSdholland return 0;
40650dbef1aSdholland
4074b2364d9Smartin snprintf(bootdev, sizeof bootdev, "/dev/r%s%c", pm->diskdev,
40824ecf24eSchristos (char)('a'+bootpart_fat12));
40950dbef1aSdholland run_program(RUN_DISPLAY, "/sbin/newfs_msdos %s", bootdev);
41050dbef1aSdholland
41150dbef1aSdholland return 0;
41250dbef1aSdholland }
41350dbef1aSdholland
41450dbef1aSdholland /*
41550dbef1aSdholland * hook called after upgrade() or install() has finished setting
41650dbef1aSdholland * up the target disk but immediately before the user is given the
41750dbef1aSdholland * ``disks are now set up'' message.
41850dbef1aSdholland */
41950dbef1aSdholland int
md_post_newfs(struct install_partition_desc * install)4204103857bSmartin md_post_newfs(struct install_partition_desc *install)
42150dbef1aSdholland {
42250dbef1aSdholland
42350dbef1aSdholland /* No bootblock. We use ofwboot from a partition visiable by OFW. */
42450dbef1aSdholland return 0;
42550dbef1aSdholland }
42650dbef1aSdholland
42750dbef1aSdholland int
md_post_extract(struct install_partition_desc * install,bool upgrade)4284204f810Smartin md_post_extract(struct install_partition_desc *install, bool upgrade)
42950dbef1aSdholland {
43050dbef1aSdholland char bootdev[100], bootbdev[100], version[64];
4314103857bSmartin struct disk_partitions *parts;
43250dbef1aSdholland
43350dbef1aSdholland /* if we can't make it bootable, just punt */
43450dbef1aSdholland if ((nobootfix && noprepfix) || rdb_found)
43550dbef1aSdholland return 0;
43650dbef1aSdholland
43750dbef1aSdholland snprintf(version, sizeof version, "NetBSD/%s %s", MACH, REL);
43850dbef1aSdholland run_program(RUN_DISPLAY, "/usr/mdec/mkbootinfo '%s' %d "
43950dbef1aSdholland "/tmp/bootinfo.txt", version, bootinfo_mbr);
44050dbef1aSdholland
44150dbef1aSdholland if (!nobootfix) {
44250dbef1aSdholland run_program(RUN_DISPLAY, "/bin/mkdir -p /%s/boot/ppc",
44350dbef1aSdholland target_prefix());
44450dbef1aSdholland run_program(RUN_DISPLAY, "/bin/mkdir -p /%s/boot/netbsd",
44550dbef1aSdholland target_prefix());
44650dbef1aSdholland run_program(RUN_DISPLAY, "/bin/cp /usr/mdec/ofwboot "
44750dbef1aSdholland "/%s/boot/netbsd", target_prefix());
44850dbef1aSdholland run_program(RUN_DISPLAY, "/bin/cp /tmp/bootinfo.txt "
44950dbef1aSdholland "/%s/boot/ppc", target_prefix());
45050dbef1aSdholland run_program(RUN_DISPLAY, "/bin/cp /usr/mdec/ofwboot "
45150dbef1aSdholland "/%s/boot/ofwboot", target_prefix());
45250dbef1aSdholland }
45350dbef1aSdholland
4544103857bSmartin if (!noprepfix && install != NULL && install->num > 0) {
4554103857bSmartin parts = install->infos[0].parts; /* disklabel */
4564103857bSmartin if (parts->parent != NULL)
4574103857bSmartin parts = parts->parent; /* MBR */
4584103857bSmartin
4594103857bSmartin parts->pscheme->get_part_device(parts, bootpart_prep,
460abce8cb3Smartin bootdev, sizeof bootdev, NULL, raw_dev_name, true, true);
4614103857bSmartin parts->pscheme->get_part_device(parts, bootpart_prep,
462abce8cb3Smartin bootbdev, sizeof bootbdev, NULL, plain_name, true, true);
46350dbef1aSdholland run_program(RUN_DISPLAY, "/bin/dd if=/dev/zero of=%s bs=512",
46450dbef1aSdholland bootdev);
46550dbef1aSdholland run_program(RUN_DISPLAY, "/bin/dd if=/usr/mdec/ofwboot "
46650dbef1aSdholland "of=%s bs=512", bootbdev);
46750dbef1aSdholland
4684103857bSmartin parts->pscheme->get_part_device(parts, bootpart_binfo,
469abce8cb3Smartin bootdev, sizeof bootdev, NULL, raw_dev_name, true, true);
4704103857bSmartin parts->pscheme->get_part_device(parts, bootpart_binfo,
471abce8cb3Smartin bootbdev, sizeof bootbdev, NULL, plain_name, true, true);
47250dbef1aSdholland run_program(RUN_DISPLAY, "/bin/dd if=/dev/zero of=%s bs=512",
47350dbef1aSdholland bootdev);
47450dbef1aSdholland run_program(RUN_DISPLAY, "/bin/dd if=/tmp/bootinfo.txt "
47550dbef1aSdholland "of=%s bs=512", bootbdev);
47650dbef1aSdholland }
47750dbef1aSdholland
47850dbef1aSdholland return 0;
47950dbef1aSdholland }
48050dbef1aSdholland
48150dbef1aSdholland void
md_cleanup_install(struct install_partition_desc * install)4824103857bSmartin md_cleanup_install(struct install_partition_desc *install)
48350dbef1aSdholland {
48450dbef1aSdholland
48550dbef1aSdholland #ifndef DEBUG
48650dbef1aSdholland enable_rc_conf();
48750dbef1aSdholland #endif
48850dbef1aSdholland }
48950dbef1aSdholland
49050dbef1aSdholland int
md_pre_update(struct install_partition_desc * install)4914103857bSmartin md_pre_update(struct install_partition_desc *install)
49250dbef1aSdholland {
4934103857bSmartin #if 0
49450dbef1aSdholland struct mbr_partition *part;
49550dbef1aSdholland mbr_info_t *ext;
49650dbef1aSdholland int i;
4974103857bSmartin #endif
49850dbef1aSdholland
49950dbef1aSdholland if (check_rdb())
50050dbef1aSdholland return 1;
50150dbef1aSdholland
5024103857bSmartin #if 0
5034b2364d9Smartin read_mbr(pm->diskdev, &mbr);
50450dbef1aSdholland /* do a sanity check of the partition table */
50550dbef1aSdholland for (ext = &mbr; ext; ext = ext->extended) {
50650dbef1aSdholland part = ext->mbr.mbr_parts;
50750dbef1aSdholland for (i = 0; i < MBR_PART_COUNT; part++, i++) {
50850dbef1aSdholland if (part->mbrp_type == MBR_PTYPE_PREP &&
50950dbef1aSdholland part->mbrp_size > 50)
51050dbef1aSdholland bootinfo_mbr = i+1;
51150dbef1aSdholland if (part->mbrp_type == MBR_PTYPE_RESERVED_x21 &&
51250dbef1aSdholland part->mbrp_size < (MIN_FAT12_BOOT/512)) {
51350dbef1aSdholland msg_display(MSG_boottoosmall);
51424ecf24eSchristos msg_fmt_display_add(MSG_nobootpartdisklabel,
51524ecf24eSchristos "%d", 0);
516e21052b4Smartin if (!ask_yesno(NULL))
51750dbef1aSdholland return 0;
51850dbef1aSdholland nobootfix = 1;
51950dbef1aSdholland }
52050dbef1aSdholland }
52150dbef1aSdholland }
5224103857bSmartin #endif
52350dbef1aSdholland
5244103857bSmartin if (!md_check_partitions(install))
5254103857bSmartin return 0;
52650dbef1aSdholland
52750dbef1aSdholland return 1;
52850dbef1aSdholland }
52950dbef1aSdholland
53050dbef1aSdholland /* Upgrade support */
53150dbef1aSdholland int
md_update(struct install_partition_desc * install)5324103857bSmartin md_update(struct install_partition_desc *install)
53350dbef1aSdholland {
53450dbef1aSdholland
53550dbef1aSdholland nonewfsmsdos = 1;
5364103857bSmartin md_post_newfs(install);
53750dbef1aSdholland return 1;
53850dbef1aSdholland }
53950dbef1aSdholland
54050dbef1aSdholland
54150dbef1aSdholland int
md_check_mbr(struct disk_partitions * parts,mbr_info_t * mbri,bool quiet)5424103857bSmartin md_check_mbr(struct disk_partitions *parts, mbr_info_t *mbri, bool quiet)
54350dbef1aSdholland {
54450dbef1aSdholland mbr_info_t *ext;
54550dbef1aSdholland struct mbr_partition *part;
54650dbef1aSdholland int i;
54750dbef1aSdholland
54850dbef1aSdholland for (ext = mbri; ext; ext = ext->extended) {
54950dbef1aSdholland part = ext->mbr.mbr_parts;
55050dbef1aSdholland for (i = 0; i < MBR_PART_COUNT; part++, i++) {
55150dbef1aSdholland if (part->mbrp_type == MBR_PTYPE_FAT12) {
5524b2364d9Smartin pm->bootstart = part->mbrp_start;
5534b2364d9Smartin pm->bootsize = part->mbrp_size;
55450dbef1aSdholland } else if (part->mbrp_type == MBR_PTYPE_PREP &&
55550dbef1aSdholland part->mbrp_size < 50) {
55650dbef1aSdholland /* this is the bootinfo partition */
55750dbef1aSdholland binfostart = part->mbrp_start;
55850dbef1aSdholland binfosize = part->mbrp_size;
55950dbef1aSdholland bootinfo_mbr = i+1;
56050dbef1aSdholland } else if (part->mbrp_type == MBR_PTYPE_PREP &&
56150dbef1aSdholland part->mbrp_size > 50) {
56250dbef1aSdholland bprepstart = part->mbrp_start;
56350dbef1aSdholland bprepsize = part->mbrp_size;
56450dbef1aSdholland }
56550dbef1aSdholland break;
56650dbef1aSdholland }
56750dbef1aSdholland }
56850dbef1aSdholland
56950dbef1aSdholland /* we need to either have a pair of prep partitions, or a single
57050dbef1aSdholland * fat. if neither, things are broken. */
5714b2364d9Smartin if (!(pm->bootsize >= (MIN_FAT12_BOOT/512) ||
57250dbef1aSdholland (binfosize >= (MIN_BINFO_BOOT/512) &&
57350dbef1aSdholland bprepsize >= (MIN_PREP_BOOT/512)))) {
5744103857bSmartin if (quiet)
57550dbef1aSdholland return 0;
5764103857bSmartin msg_display(MSG_bootnotright);
5774103857bSmartin return ask_reedit(parts);
57850dbef1aSdholland }
57950dbef1aSdholland
58050dbef1aSdholland /* check the prep partitions */
58150dbef1aSdholland if ((binfosize > 0 || bprepsize > 0) &&
58250dbef1aSdholland (binfosize < (MIN_BINFO_BOOT/512) ||
58350dbef1aSdholland bprepsize < (MIN_PREP_BOOT/512))) {
5844103857bSmartin if (quiet)
58550dbef1aSdholland return 0;
5864103857bSmartin msg_display(MSG_preptoosmall);
5874103857bSmartin return ask_reedit(parts);
58850dbef1aSdholland }
58950dbef1aSdholland
590*1cd43426Sandvar /* check the fat12 partitions */
5914b2364d9Smartin if (pm->bootsize > 0 && pm->bootsize < (MIN_FAT12_BOOT/512)) {
5924103857bSmartin if (quiet)
59350dbef1aSdholland return 0;
5944103857bSmartin msg_display(MSG_boottoosmall);
5954103857bSmartin return ask_reedit(parts);
59650dbef1aSdholland }
59750dbef1aSdholland
59850dbef1aSdholland /* if both sets contain zero, thats bad */
5994b2364d9Smartin if ((pm->bootstart == 0 || pm->bootsize == 0) &&
60050dbef1aSdholland (binfosize == 0 || binfostart == 0 ||
60150dbef1aSdholland bprepsize == 0 || bprepstart == 0)) {
6024103857bSmartin if (quiet)
60350dbef1aSdholland return 0;
6044103857bSmartin msg_display(MSG_nobootpart);
6054103857bSmartin return ask_reedit(parts);
60650dbef1aSdholland }
60750dbef1aSdholland return 2;
60850dbef1aSdholland }
60950dbef1aSdholland
61050dbef1aSdholland /*
61150dbef1aSdholland * NOTE, we use a reserved partition type, because some RS/6000 machines hang
61250dbef1aSdholland * hard if they find a FAT12, and if we use type prep, that indicates that
61350dbef1aSdholland * it should be read raw.
61450dbef1aSdholland * One partition for FAT12 booting
61550dbef1aSdholland * One partition for NetBSD
61650dbef1aSdholland * One partition to hold the bootinfo.txt file
61750dbef1aSdholland * One partition to hold ofwboot
61850dbef1aSdholland */
61950dbef1aSdholland
6204103857bSmartin bool
md_parts_use_wholedisk(struct disk_partitions * parts)6214103857bSmartin md_parts_use_wholedisk(struct disk_partitions *parts)
62250dbef1aSdholland {
6234103857bSmartin struct disk_part_info boot_parts[] =
6244103857bSmartin {
6254103857bSmartin { .fs_type = FS_MSDOS, .size = FAT12_BOOT_SIZE/512 },
6264103857bSmartin { .fs_type = FS_OTHER, .size = BINFO_BOOT_SIZE/512 },
6274103857bSmartin { .fs_type = FS_BOOT, .size = PREP_BOOT_SIZE/512 }
6284103857bSmartin };
62950dbef1aSdholland
6304103857bSmartin return parts_use_wholedisk(parts, __arraycount(boot_parts),
6314103857bSmartin boot_parts);
63250dbef1aSdholland }
63350dbef1aSdholland
md_disklabel_cmd(void)63450dbef1aSdholland const char *md_disklabel_cmd(void)
63550dbef1aSdholland {
63650dbef1aSdholland
63750dbef1aSdholland /* we cannot rewrite an RDB disklabel */
63850dbef1aSdholland if (rdb_found)
63950dbef1aSdholland return "sync No disklabel";
64050dbef1aSdholland
64150dbef1aSdholland return "disklabel -w -r";
64250dbef1aSdholland }
64350dbef1aSdholland
64450dbef1aSdholland static int
check_rdb(void)64550dbef1aSdholland check_rdb(void)
64650dbef1aSdholland {
64750dbef1aSdholland char buf[512], diskpath[MAXPATHLEN];
64850dbef1aSdholland struct rdblock *rdb;
64950dbef1aSdholland off_t blk;
65050dbef1aSdholland int fd;
65150dbef1aSdholland
65250dbef1aSdholland /* Find out if this disk has a valid RDB, before continuing. */
65350dbef1aSdholland rdb = (struct rdblock *)buf;
6544b2364d9Smartin fd = opendisk(pm->diskdev, O_RDONLY, diskpath, sizeof(diskpath), 0);
65550dbef1aSdholland if (fd < 0)
65650dbef1aSdholland return 0;
65750dbef1aSdholland for (blk = 0; blk < RDB_MAXBLOCKS; blk++) {
65850dbef1aSdholland if (pread(fd, rdb, 512, blk * 512) != 512)
65950dbef1aSdholland return 0;
66050dbef1aSdholland if (rdb->id == RDBLOCK_ID && rdbchksum(rdb) == 0) {
66150dbef1aSdholland rdb_found = 1; /* do not repartition! */
66250dbef1aSdholland return 1;
66350dbef1aSdholland }
66450dbef1aSdholland }
66550dbef1aSdholland return 0;
66650dbef1aSdholland }
66750dbef1aSdholland
66850dbef1aSdholland static uint32_t
rdbchksum(void * bdata)66950dbef1aSdholland rdbchksum(void *bdata)
67050dbef1aSdholland {
67150dbef1aSdholland uint32_t *blp, cnt, val;
67250dbef1aSdholland
67350dbef1aSdholland blp = bdata;
67450dbef1aSdholland cnt = blp[1];
67550dbef1aSdholland val = 0;
67650dbef1aSdholland while (cnt--)
67750dbef1aSdholland val += *blp++;
67850dbef1aSdholland return val;
67950dbef1aSdholland }
68050dbef1aSdholland
68150dbef1aSdholland int
md_pre_mount(struct install_partition_desc * install,size_t ndx)6824f30cbf3Smartin md_pre_mount(struct install_partition_desc *install, size_t ndx)
68350dbef1aSdholland {
68450dbef1aSdholland
68550dbef1aSdholland return 0;
68650dbef1aSdholland }
6874103857bSmartin
6884103857bSmartin bool
md_mbr_update_check(struct disk_partitions * parts,mbr_info_t * mbri)6894103857bSmartin md_mbr_update_check(struct disk_partitions *parts, mbr_info_t *mbri)
6904103857bSmartin {
6914103857bSmartin return false; /* no change, no need to write back */
6924103857bSmartin }
6934103857bSmartin
6944103857bSmartin #ifdef HAVE_GPT
6954103857bSmartin 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)6964103857bSmartin md_gpt_post_write(struct disk_partitions *parts, part_id root_id,
6974103857bSmartin bool root_is_new, part_id efi_id, bool efi_is_new)
6984103857bSmartin {
6994103857bSmartin /* no GPT boot support, nothing needs to be done here */
7004103857bSmartin return true;
7014103857bSmartin }
7024103857bSmartin #endif
7034103857bSmartin
704