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