1 1.35 martin /* $NetBSD: md.c,v 1.35 2022/02/10 16:11:42 martin 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 -- i386 machine specific routines - also used by amd64 */ 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/exec.h> 40 1.1 dholland #include <sys/utsname.h> 41 1.1 dholland #include <sys/types.h> 42 1.1 dholland #include <sys/stat.h> 43 1.1 dholland #include <machine/cpu.h> 44 1.15 martin #include <assert.h> 45 1.1 dholland #include <stdio.h> 46 1.1 dholland #include <stddef.h> 47 1.1 dholland #include <util.h> 48 1.1 dholland #include <dirent.h> 49 1.1 dholland #include <termios.h> 50 1.1 dholland 51 1.1 dholland #include "defs.h" 52 1.1 dholland #include "md.h" 53 1.1 dholland #include "endian.h" 54 1.1 dholland #include "msg_defs.h" 55 1.1 dholland #include "menu_defs.h" 56 1.1 dholland 57 1.1 dholland #ifdef NO_LBA_READS /* for testing */ 58 1.1 dholland #undef BIFLAG_EXTINT13 59 1.1 dholland #define BIFLAG_EXTINT13 0 60 1.1 dholland #endif 61 1.1 dholland 62 1.1 dholland static struct biosdisk_info *biosdisk = NULL; 63 1.20 martin static bool uefi_boot; 64 1.1 dholland 65 1.1 dholland /* prototypes */ 66 1.1 dholland 67 1.15 martin static bool get_bios_info(const char*, struct disk_partitions*, int*, int*, int*); 68 1.31 martin static int mbr_root_above_chs(daddr_t); 69 1.1 dholland static int md_read_bootcode(const char *, struct mbr_sector *); 70 1.1 dholland static unsigned int get_bootmodel(void); 71 1.1 dholland 72 1.20 martin static int conmib[] = { CTL_MACHDEP, CPU_CONSDEV }; 73 1.20 martin 74 1.20 martin #define BOOT_PART (128*(MEG/512)) 75 1.20 martin #define BOOT_PART_TYPE PT_EFI_SYSTEM 76 1.20 martin 77 1.20 martin static const char * uefi_bootloaders[] = { 78 1.20 martin "/usr/mdec/bootia32.efi", 79 1.20 martin "/usr/mdec/bootx64.efi", 80 1.20 martin }; 81 1.13 martin 82 1.1 dholland void 83 1.1 dholland md_init(void) 84 1.1 dholland { 85 1.20 martin char boot_method[100]; 86 1.20 martin size_t len; 87 1.20 martin 88 1.20 martin len = sizeof(boot_method); 89 1.20 martin if (sysctlbyname("machdep.bootmethod", boot_method, &len, NULL, 0) 90 1.20 martin != -1) { 91 1.20 martin if (strcmp(boot_method, "BIOS") == 0) 92 1.20 martin uefi_boot = false; 93 1.20 martin else if (strcmp(boot_method, "UEFI") == 0) 94 1.20 martin uefi_boot = true; 95 1.20 martin } 96 1.1 dholland } 97 1.1 dholland 98 1.1 dholland void 99 1.1 dholland md_init_set_status(int flags) 100 1.1 dholland { 101 1.1 dholland (void)flags; 102 1.1 dholland 103 1.1 dholland /* Default to install same type of kernel as we are running */ 104 1.1 dholland set_kernel_set(get_bootmodel()); 105 1.1 dholland } 106 1.1 dholland 107 1.15 martin bool 108 1.15 martin md_get_info(struct install_partition_desc *install) 109 1.1 dholland { 110 1.32 martin int bcyl = 0, bhead = 0, bsec = 0, res; 111 1.1 dholland 112 1.15 martin if (pm->no_mbr || pm->no_part) 113 1.15 martin return true; 114 1.1 dholland 115 1.32 martin again: 116 1.15 martin if (pm->parts == NULL) { 117 1.1 dholland 118 1.15 martin const struct disk_partitioning_scheme *ps = 119 1.15 martin select_part_scheme(pm, NULL, true, NULL); 120 1.1 dholland 121 1.15 martin if (!ps) 122 1.21 martin return false; 123 1.1 dholland 124 1.15 martin struct disk_partitions *parts = 125 1.15 martin (*ps->create_new_for_disk)(pm->diskdev, 126 1.29 martin 0, pm->dlsize, true, NULL); 127 1.15 martin if (!parts) 128 1.15 martin return false; 129 1.1 dholland 130 1.15 martin pm->parts = parts; 131 1.15 martin if (ps->size_limit > 0 && pm->dlsize > ps->size_limit) 132 1.15 martin pm->dlsize = ps->size_limit; 133 1.1 dholland } 134 1.1 dholland 135 1.15 martin if (get_bios_info(pm->diskdev, pm->parts, &bcyl, &bhead, &bsec) 136 1.15 martin && pm->parts->pscheme->change_disk_geom != NULL) 137 1.15 martin pm->parts->pscheme->change_disk_geom(pm->parts, 138 1.15 martin bcyl, bhead, bsec); 139 1.15 martin else 140 1.29 martin set_default_sizemult(pm->diskdev, MEG, pm->sectorsize); 141 1.1 dholland 142 1.15 martin /* 143 1.15 martin * If the selected scheme does not need two-stage partitioning 144 1.15 martin * (like GPT), do not bother to edit the outer partitions. 145 1.15 martin */ 146 1.15 martin if (pm->parts->pscheme->secondary_partitions == NULL || 147 1.15 martin pm->parts->pscheme->secondary_scheme == NULL) 148 1.15 martin return true; 149 1.1 dholland 150 1.15 martin if (pm->no_mbr || pm->no_part) 151 1.15 martin return true; 152 1.1 dholland 153 1.32 martin res = edit_outer_parts(pm->parts); 154 1.32 martin if (res == 0) 155 1.32 martin return false; 156 1.32 martin else if (res == 1) 157 1.32 martin return true; 158 1.32 martin 159 1.32 martin pm->parts->pscheme->destroy_part_scheme(pm->parts); 160 1.32 martin pm->parts = NULL; 161 1.32 martin goto again; 162 1.1 dholland } 163 1.1 dholland 164 1.1 dholland /* 165 1.1 dholland * md back-end code for menu-driven BSD disklabel editor. 166 1.1 dholland */ 167 1.32 martin int 168 1.15 martin md_make_bsd_partitions(struct install_partition_desc *install) 169 1.1 dholland { 170 1.15 martin return make_bsd_partitions(install); 171 1.1 dholland } 172 1.1 dholland 173 1.1 dholland /* 174 1.1 dholland * any additional partition validation 175 1.1 dholland */ 176 1.15 martin bool 177 1.15 martin md_check_partitions(struct install_partition_desc *install) 178 1.1 dholland { 179 1.1 dholland int rval; 180 1.1 dholland char *bootxx; 181 1.1 dholland 182 1.20 martin /* if booting via UEFI no boot blocks are needed */ 183 1.20 martin if (uefi_boot) 184 1.20 martin return true; 185 1.20 martin 186 1.1 dholland /* check we have boot code for the root partition type */ 187 1.15 martin bootxx = bootxx_name(install); 188 1.1 dholland rval = access(bootxx, R_OK); 189 1.1 dholland free(bootxx); 190 1.1 dholland if (rval == 0) 191 1.15 martin return true; 192 1.8 joerg process_menu(MENU_ok, __UNCONST(MSG_No_Bootcode)); 193 1.15 martin return false; 194 1.1 dholland } 195 1.1 dholland 196 1.1 dholland /* 197 1.1 dholland * hook called before writing new disklabel. 198 1.1 dholland */ 199 1.15 martin bool 200 1.15 martin md_pre_disklabel(struct install_partition_desc *install, 201 1.15 martin struct disk_partitions *parts) 202 1.1 dholland { 203 1.1 dholland 204 1.15 martin if (parts->parent == NULL) 205 1.15 martin return true; /* no outer partitions */ 206 1.15 martin 207 1.15 martin parts = parts->parent; 208 1.15 martin 209 1.15 martin msg_display_subst(MSG_dofdisk, 3, parts->disk, 210 1.15 martin msg_string(parts->pscheme->name), 211 1.15 martin msg_string(parts->pscheme->short_name)); 212 1.1 dholland 213 1.15 martin /* write edited "MBR" onto disk. */ 214 1.15 martin if (!parts->pscheme->write_to_disk(parts)) { 215 1.1 dholland msg_display(MSG_wmbrfail); 216 1.1 dholland process_menu(MENU_ok, NULL); 217 1.15 martin return false; 218 1.1 dholland } 219 1.15 martin return true; 220 1.1 dholland } 221 1.1 dholland 222 1.1 dholland /* 223 1.1 dholland * hook called after writing disklabel to new target disk. 224 1.1 dholland */ 225 1.15 martin bool 226 1.15 martin md_post_disklabel(struct install_partition_desc *install, 227 1.15 martin struct disk_partitions *parts) 228 1.1 dholland { 229 1.15 martin return true; 230 1.1 dholland } 231 1.1 dholland 232 1.1 dholland /* 233 1.20 martin * Do all legacy bootblock update/setup here 234 1.1 dholland */ 235 1.20 martin static int 236 1.34 martin update_bios_boot(struct install_partition_desc *install, bool use_target_files) 237 1.1 dholland { 238 1.1 dholland int ret; 239 1.1 dholland size_t len; 240 1.3 riz char boot_options[1024]; 241 1.34 martin char *bootxx_filename, *p; 242 1.1 dholland /* 243 1.3 riz * XXX - this code retains a lot of cruft from when we went 244 1.3 riz * to great pains to exclude installboot from the ramdisk 245 1.3 riz * for size reasons and should be rewritten. 246 1.1 dholland */ 247 1.3 riz static const char *consoles[]={ 248 1.3 riz "pc", /* CONSDEV_PC */ 249 1.3 riz "com0", /* CONSDEV_COM0 */ 250 1.3 riz "com1", /* CONSDEV_COM1 */ 251 1.3 riz "com2", /* CONSDEV_COM2 */ 252 1.3 riz "com3", /* CONSDEV_COM3 */ 253 1.3 riz "com0kbd", /* CONSDEV_COM0KBD */ 254 1.3 riz "com1kbd", /* CONSDEV_COM1KBD */ 255 1.3 riz "com2kbd", /* CONSDEV_COM2KBD */ 256 1.3 riz "com3kbd" /* CONSDEV_COM3KBD */ }; 257 1.1 dholland static struct x86_boot_params boottype = 258 1.1 dholland {sizeof boottype, 0, 5, 0, 9600, { '\0' }, "", 0}; 259 1.1 dholland struct termios t; 260 1.1 dholland dev_t condev; 261 1.1 dholland 262 1.9 martin if (pm == NULL || !pm->no_part) { 263 1.9 martin /* 264 1.9 martin * Get console device, should either be ttyE0 or tty0n. 265 1.9 martin * Too hard to double check, so just 'know' the device numbers. 266 1.9 martin */ 267 1.9 martin len = sizeof condev; 268 1.23 martin if (sysctl(conmib, __arraycount(conmib), &condev, &len, NULL, 269 1.23 martin 0) != -1 && (condev & ~3) == 0x800) { 270 1.9 martin /* Motherboard serial port */ 271 1.9 martin boottype.bp_consdev = (condev & 3) + 1; 272 1.23 martin /* Defaulting the baud rate to that of stdin should 273 1.23 martin suffice */ 274 1.9 martin if (tcgetattr(0, &t) != -1) 275 1.9 martin boottype.bp_conspeed = t.c_ispeed; 276 1.9 martin } 277 1.9 martin 278 1.9 martin process_menu(MENU_getboottype, &boottype); 279 1.18 christos msg_fmt_display(MSG_dobootblks, "%s", pm->diskdev); 280 1.9 martin if (boottype.bp_consdev == ~0u) 281 1.9 martin /* Use existing bootblocks */ 282 1.9 martin return 0; 283 1.1 dholland } 284 1.1 dholland 285 1.34 martin if (use_target_files) 286 1.34 martin ret = cp_within_target("/usr/mdec/boot", "/", 0); 287 1.34 martin else 288 1.34 martin ret = cp_to_target("/usr/mdec/boot", "/"); 289 1.1 dholland if (ret) 290 1.1 dholland return ret; 291 1.9 martin if (pm && pm->no_part) 292 1.9 martin return 0; 293 1.1 dholland 294 1.34 martin p = bootxx_name(install); 295 1.34 martin if (p && use_target_files) { 296 1.34 martin bootxx_filename = strdup(target_expand(p)); 297 1.34 martin free(p); 298 1.34 martin } else { 299 1.34 martin bootxx_filename = p; 300 1.34 martin } 301 1.9 martin if (bootxx_filename != NULL) { 302 1.15 martin char rdev[PATH_MAX]; 303 1.15 martin 304 1.15 martin install->infos[0].parts->pscheme->get_part_device( 305 1.15 martin install->infos[0].parts, install->infos[0].cur_part_id, 306 1.28 martin rdev, sizeof rdev, NULL, raw_dev_name, true, true); 307 1.15 martin 308 1.3 riz snprintf(boot_options, sizeof boot_options, 309 1.3 riz "console=%s,speed=%u", consoles[boottype.bp_consdev], 310 1.3 riz boottype.bp_conspeed); 311 1.15 martin ret = run_program(RUN_DISPLAY, 312 1.30 martin "/usr/sbin/installboot -f -o %s %s %s", 313 1.16 martin boot_options, rdev, bootxx_filename); 314 1.15 martin free(bootxx_filename); 315 1.16 martin } else { 316 1.16 martin ret = -1; 317 1.16 martin } 318 1.16 martin 319 1.16 martin if (ret != 0) 320 1.16 martin process_menu(MENU_ok, 321 1.16 martin __UNCONST("Warning: disk is probably not bootable")); 322 1.1 dholland 323 1.1 dholland return ret; 324 1.1 dholland } 325 1.1 dholland 326 1.34 martin static int 327 1.34 martin md_post_newfs_bios(struct install_partition_desc *install) 328 1.34 martin { 329 1.34 martin return update_bios_boot(install, false); 330 1.34 martin } 331 1.34 martin 332 1.20 martin /* 333 1.20 martin * Make sure our bootloader(s) are in the proper directory in the boot 334 1.20 martin * boot partition (or update them). 335 1.20 martin */ 336 1.20 martin static int 337 1.35 martin copy_uefi_boot(const struct part_usage_info *boot, bool target_is_populated) 338 1.20 martin { 339 1.34 martin char dev[MAXPATHLEN], path[MAXPATHLEN], src[MAXPATHLEN]; 340 1.35 martin const char *s; 341 1.20 martin size_t i; 342 1.20 martin int err; 343 1.20 martin 344 1.20 martin if (!boot->parts->pscheme->get_part_device(boot->parts, 345 1.28 martin boot->cur_part_id, dev, sizeof(dev), NULL, plain_name, true, true)) 346 1.20 martin return -1; 347 1.20 martin 348 1.20 martin /* 349 1.20 martin * We should have a valid file system on that partition. 350 1.20 martin * Try to mount it and check if there is a /EFI in there. 351 1.20 martin */ 352 1.20 martin if (boot->mount[0]) 353 1.20 martin strlcpy(path, boot->mount, sizeof(path)); 354 1.20 martin else 355 1.20 martin strcpy(path, "/mnt"); 356 1.20 martin 357 1.20 martin if (!(boot->instflags & PUIINST_MOUNT)) { 358 1.20 martin make_target_dir(path); 359 1.20 martin err = target_mount("", dev, path); 360 1.20 martin if (err != 0) 361 1.20 martin return err; 362 1.20 martin } 363 1.20 martin 364 1.20 martin strlcat(path, "/EFI/boot", sizeof(path)); 365 1.20 martin make_target_dir(path); 366 1.20 martin 367 1.20 martin for (i = 0; i < __arraycount(uefi_bootloaders); i++) { 368 1.35 martin s = uefi_bootloaders[i]; 369 1.35 martin strcpy(src, target_is_populated ? target_expand(s) : s); 370 1.34 martin if (access(src, R_OK) != 0) 371 1.20 martin continue; 372 1.35 martin err = target_is_populated ? 373 1.35 martin cp_within_target(s, path, 0) : 374 1.35 martin cp_to_target(s, path); 375 1.20 martin if (err) 376 1.20 martin return err; 377 1.20 martin } 378 1.35 martin if (boot->mount[0] == 0) 379 1.35 martin target_unmount("/mnt"); 380 1.20 martin 381 1.20 martin return 0; 382 1.20 martin } 383 1.20 martin 384 1.20 martin /* 385 1.20 martin * Find (U)EFI boot partition and install/update bootloaders 386 1.20 martin */ 387 1.20 martin static int 388 1.35 martin update_uefi_boot_code(struct install_partition_desc *install, 389 1.35 martin bool target_is_populated) 390 1.20 martin { 391 1.34 martin size_t i, boot_part; 392 1.20 martin 393 1.34 martin boot_part = ~0U; 394 1.20 martin for (i = 0; i < install->num; i++) { 395 1.20 martin if (!(install->infos[i].instflags & PUIINST_BOOT)) 396 1.20 martin continue; 397 1.34 martin boot_part = i; 398 1.34 martin break; 399 1.34 martin } 400 1.34 martin if (boot_part == ~0U) { 401 1.34 martin /* 402 1.34 martin * Didn't find an explicitly marked boot partition, 403 1.34 martin * check if we have any EFI System Partitions and 404 1.34 martin * use the first. 405 1.34 martin */ 406 1.34 martin for (i = 0; i < install->num; i++) { 407 1.34 martin if (install->infos[i].type != PT_EFI_SYSTEM) 408 1.34 martin continue; 409 1.34 martin boot_part = i; 410 1.34 martin break; 411 1.34 martin } 412 1.34 martin } 413 1.20 martin 414 1.34 martin if (boot_part < install->num) 415 1.35 martin return copy_uefi_boot(&install->infos[boot_part], 416 1.35 martin target_is_populated); 417 1.20 martin 418 1.20 martin return -1; /* no EFI boot partition found */ 419 1.20 martin } 420 1.34 martin 421 1.34 martin /* 422 1.34 martin * Find bootloader options and update bootloader 423 1.34 martin */ 424 1.34 martin static int 425 1.34 martin update_bios_boot_code(struct install_partition_desc *install) 426 1.34 martin { 427 1.34 martin return update_bios_boot(install, true); 428 1.34 martin } 429 1.34 martin 430 1.34 martin static int 431 1.35 martin update_boot_code(struct install_partition_desc *install, 432 1.35 martin bool target_is_populated) 433 1.34 martin { 434 1.34 martin return uefi_boot ? 435 1.35 martin update_uefi_boot_code(install, target_is_populated) 436 1.34 martin : update_bios_boot_code(install); 437 1.34 martin } 438 1.34 martin 439 1.34 martin static int 440 1.34 martin md_post_newfs_uefi(struct install_partition_desc *install) 441 1.34 martin { 442 1.35 martin return update_uefi_boot_code(install, false); 443 1.34 martin } 444 1.20 martin 445 1.20 martin /* 446 1.20 martin * hook called after upgrade() or install() has finished setting 447 1.20 martin * up the target disk but immediately before the user is given the 448 1.20 martin * ``disks are now set up'' message. 449 1.20 martin */ 450 1.20 martin int 451 1.20 martin md_post_newfs(struct install_partition_desc *install) 452 1.20 martin { 453 1.20 martin 454 1.20 martin return uefi_boot ? md_post_newfs_uefi(install) 455 1.20 martin : md_post_newfs_bios(install); 456 1.20 martin } 457 1.20 martin 458 1.1 dholland int 459 1.34 martin md_post_extract(struct install_partition_desc *install, bool upgrade) 460 1.1 dholland { 461 1.34 martin if (upgrade) 462 1.35 martin update_boot_code(install, true); 463 1.34 martin 464 1.26 martin #if defined(__amd64__) 465 1.26 martin if (get_kernel_set() == SET_KERNEL_2) { 466 1.26 martin int ret; 467 1.26 martin 468 1.26 martin ret = cp_within_target("/usr/mdec/prekern", "/prekern", 0); 469 1.26 martin if (ret) 470 1.26 martin return ret; 471 1.26 martin } 472 1.26 martin #endif 473 1.34 martin 474 1.1 dholland return 0; 475 1.1 dholland } 476 1.1 dholland 477 1.1 dholland void 478 1.15 martin md_cleanup_install(struct install_partition_desc *install) 479 1.1 dholland { 480 1.13 martin size_t len; 481 1.13 martin dev_t condev; 482 1.13 martin 483 1.1 dholland #ifndef DEBUG 484 1.1 dholland enable_rc_conf(); 485 1.1 dholland add_rc_conf("wscons=YES\n"); 486 1.1 dholland 487 1.1 dholland # if defined(__i386__) && defined(SET_KERNEL_TINY) 488 1.1 dholland /* 489 1.1 dholland * For GENERIC_TINY, do not enable any extra screens or wsmux. 490 1.1 dholland * Otherwise, run getty on 4 VTs. 491 1.1 dholland */ 492 1.1 dholland if (get_kernel_set() == SET_KERNEL_TINY) 493 1.1 dholland run_program(RUN_CHROOT, 494 1.1 dholland "sed -an -e '/^screen/s/^/#/;/^mux/s/^/#/;" 495 1.1 dholland "H;$!d;g;w /etc/wscons.conf' /etc/wscons.conf"); 496 1.1 dholland else 497 1.1 dholland # endif 498 1.1 dholland run_program(RUN_CHROOT, 499 1.1 dholland "sed -an -e '/^ttyE[1-9]/s/off/on/;" 500 1.1 dholland "H;$!d;g;w /etc/ttys' /etc/ttys"); 501 1.1 dholland 502 1.1 dholland #endif 503 1.13 martin 504 1.13 martin /* 505 1.13 martin * Get console device, should either be ttyE0 or tty0n. 506 1.13 martin * Too hard to double check, so just 'know' the device numbers. 507 1.13 martin */ 508 1.13 martin len = sizeof condev; 509 1.15 martin if (sysctl(conmib, __arraycount(conmib), &condev, &len, NULL, 0) != -1 510 1.13 martin && (condev & ~3) != 0x800) { 511 1.13 martin 512 1.13 martin /* 513 1.13 martin * Current console is not com*, assume ttyE*. 514 1.13 martin * Modify /etc/ttys to use wsvt25 for all ports. 515 1.13 martin */ 516 1.13 martin 517 1.13 martin run_program(RUN_CHROOT, 518 1.13 martin "sed -an -e 's/vt100/wsvt25/g;" 519 1.13 martin "H;$!d;g;w /etc/ttys' /etc/ttys"); 520 1.13 martin } 521 1.1 dholland } 522 1.1 dholland 523 1.1 dholland int 524 1.15 martin md_pre_update(struct install_partition_desc *install) 525 1.1 dholland { 526 1.1 dholland return 1; 527 1.1 dholland } 528 1.1 dholland 529 1.1 dholland /* Upgrade support */ 530 1.1 dholland int 531 1.15 martin md_update(struct install_partition_desc *install) 532 1.1 dholland { 533 1.1 dholland return 1; 534 1.1 dholland } 535 1.1 dholland 536 1.1 dholland int 537 1.15 martin md_check_mbr(struct disk_partitions *parts, mbr_info_t *mbri, bool quiet) 538 1.1 dholland { 539 1.15 martin mbr_info_t *ext; 540 1.15 martin struct mbr_partition *p; 541 1.15 martin const char *bootcode; 542 1.31 martin daddr_t inst_start, inst_size; 543 1.15 martin int i, names, fl, ofl; 544 1.15 martin #define ACTIVE_FOUND 0x0100 545 1.15 martin #define NETBSD_ACTIVE 0x0200 546 1.15 martin #define NETBSD_NAMED 0x0400 547 1.15 martin #define ACTIVE_NAMED 0x0800 548 1.15 martin 549 1.15 martin root_limit = 0; 550 1.31 martin if (parts->pscheme->guess_install_target == NULL || 551 1.31 martin !parts->pscheme->guess_install_target(parts, &inst_start, 552 1.31 martin &inst_size)) { 553 1.31 martin inst_start = parts->disk_start; 554 1.31 martin inst_size = parts->disk_size; 555 1.31 martin } 556 1.31 martin 557 1.15 martin if (biosdisk != NULL && (biosdisk->bi_flags & BIFLAG_EXTINT13) == 0) { 558 1.31 martin if (mbr_root_above_chs(inst_start)) { 559 1.15 martin if (quiet) 560 1.15 martin return 0; 561 1.15 martin msg_display(MSG_partabovechs); 562 1.15 martin if (!ask_noyes(NULL)) 563 1.15 martin return 1; 564 1.15 martin /* The user is shooting themselves in the foot here...*/ 565 1.15 martin } else { 566 1.15 martin if (parts->pscheme->size_limit) 567 1.15 martin root_limit = min(parts->pscheme->size_limit, 568 1.15 martin parts->disk_size); 569 1.15 martin else 570 1.15 martin root_limit = parts->disk_size; 571 1.15 martin } 572 1.15 martin } 573 1.15 martin 574 1.15 martin /* 575 1.31 martin * Ensure the install partition (at sector inst_start) and the active 576 1.15 martin * partition are bootable. 577 1.15 martin * Determine whether the bootselect code is needed. 578 1.15 martin * Note that MBR_BS_NEWMBR is always set, so we ignore it! 579 1.15 martin */ 580 1.15 martin fl = 0; 581 1.15 martin names = 0; 582 1.15 martin for (ext = mbri; ext != NULL; ext = ext->extended) { 583 1.15 martin p = ext->mbr.mbr_parts; 584 1.15 martin for (i = 0; i < MBR_PART_COUNT; p++, i++) { 585 1.15 martin if (p->mbrp_flag == MBR_PFLAG_ACTIVE) { 586 1.15 martin fl |= ACTIVE_FOUND; 587 1.31 martin if (ext->sector + p->mbrp_start == inst_start) 588 1.15 martin fl |= NETBSD_ACTIVE; 589 1.15 martin } 590 1.15 martin if (ext->mbrb.mbrbs_nametab[i][0] == 0) { 591 1.15 martin /* No bootmenu label... */ 592 1.15 martin if (ext->sector == 0) 593 1.15 martin continue; 594 1.31 martin if (ext->sector + p->mbrp_start == inst_start) 595 1.15 martin /* 596 1.15 martin * Have installed into an extended ptn 597 1.15 martin * force name & bootsel... 598 1.15 martin */ 599 1.15 martin names++; 600 1.15 martin continue; 601 1.15 martin } 602 1.15 martin /* Partition has a bootmenu label... */ 603 1.15 martin if (ext->sector != 0) 604 1.15 martin fl |= MBR_BS_EXTLBA; 605 1.31 martin if (ext->sector + p->mbrp_start == inst_start) 606 1.15 martin fl |= NETBSD_NAMED; 607 1.15 martin else if (p->mbrp_flag == MBR_PFLAG_ACTIVE) 608 1.15 martin fl |= ACTIVE_NAMED; 609 1.15 martin else 610 1.15 martin names++; 611 1.15 martin } 612 1.15 martin } 613 1.15 martin if (!(fl & ACTIVE_FOUND)) 614 1.15 martin fl |= NETBSD_ACTIVE; 615 1.15 martin if (fl & NETBSD_NAMED && fl & NETBSD_ACTIVE) 616 1.15 martin fl |= ACTIVE_NAMED; 617 1.15 martin 618 1.15 martin if ((names > 0 || !(fl & NETBSD_ACTIVE)) && 619 1.15 martin (!(fl & NETBSD_NAMED) || !(fl & ACTIVE_NAMED))) { 620 1.15 martin /* 621 1.15 martin * There appear to be multiple bootable partitions, but they 622 1.15 martin * don't all have bootmenu texts. 623 1.15 martin */ 624 1.15 martin if (quiet) 625 1.15 martin return 0; 626 1.15 martin 627 1.15 martin msg_display(MSG_missing_bootmenu_text); 628 1.15 martin if (ask_yesno(NULL)) 629 1.15 martin return 1; 630 1.15 martin } 631 1.15 martin 632 1.15 martin if ((fl & MBR_BS_EXTLBA) && 633 1.15 martin (biosdisk == NULL || !(biosdisk->bi_flags & BIFLAG_EXTINT13))) { 634 1.15 martin /* Need unsupported LBA reads to read boot sectors */ 635 1.15 martin if (quiet) 636 1.15 martin return 0; 637 1.15 martin 638 1.15 martin msg_display(MSG_no_extended_bootmenu); 639 1.15 martin if (!ask_noyes(NULL)) 640 1.15 martin return 1; 641 1.15 martin } 642 1.15 martin 643 1.15 martin /* Sort out the name of the mbr code we need */ 644 1.33 martin if (names > 1 || 645 1.33 martin (parts->num_part > 1 && (fl & (NETBSD_NAMED | ACTIVE_NAMED)))) { 646 1.15 martin /* Need bootselect code */ 647 1.15 martin fl |= MBR_BS_ACTIVE; 648 1.15 martin bootcode = fl & MBR_BS_EXTLBA ? _PATH_BOOTEXT : _PATH_BOOTSEL; 649 1.33 martin } else { 650 1.15 martin bootcode = _PATH_MBR; 651 1.33 martin } 652 1.15 martin 653 1.15 martin fl &= MBR_BS_ACTIVE | MBR_BS_EXTLBA; 654 1.15 martin 655 1.15 martin /* Look at what is installed */ 656 1.15 martin ofl = mbri->mbrb.mbrbs_flags; 657 1.15 martin if (ofl == 0) { 658 1.15 martin /* Check there is some bootcode at all... */ 659 1.15 martin if (mbri->mbr.mbr_magic != htole16(MBR_MAGIC) || 660 1.15 martin mbri->mbr.mbr_jmpboot[0] == 0 || 661 1.31 martin mbr_root_above_chs(inst_start)) 662 1.15 martin /* Existing won't do, force update */ 663 1.15 martin fl |= MBR_BS_NEWMBR; 664 1.15 martin } 665 1.15 martin ofl = mbri->oflags & (MBR_BS_ACTIVE | MBR_BS_EXTLBA); 666 1.15 martin 667 1.15 martin if (!quiet) { 668 1.15 martin if (fl & ~ofl || (fl == 0 && ofl & MBR_BS_ACTIVE)) { 669 1.15 martin /* Existing boot code isn't the right one... */ 670 1.15 martin if (fl & MBR_BS_ACTIVE) 671 1.15 martin msg_display(MSG_installbootsel); 672 1.15 martin else 673 1.15 martin msg_display(MSG_installmbr); 674 1.15 martin } else 675 1.15 martin /* Existing code would (probably) be ok */ 676 1.15 martin msg_display(MSG_updatembr); 677 1.15 martin 678 1.15 martin if (!ask_yesno(NULL)) 679 1.15 martin /* User doesn't want to update mbr code */ 680 1.15 martin return 2; 681 1.15 martin } 682 1.15 martin 683 1.15 martin if (md_read_bootcode(bootcode, &mbri->mbr) == 0) 684 1.15 martin /* update suceeded - to memory copy */ 685 1.15 martin return 2; 686 1.15 martin 687 1.15 martin /* This shouldn't happen since the files are in the floppy fs... */ 688 1.18 christos msg_fmt_display("Can't find %s", "%s", bootcode); 689 1.15 martin return ask_reedit(parts); 690 1.1 dholland } 691 1.1 dholland 692 1.15 martin bool 693 1.15 martin md_parts_use_wholedisk(struct disk_partitions *parts) 694 1.1 dholland { 695 1.20 martin struct disk_part_info boot_part = { 696 1.20 martin .size = BOOT_PART, 697 1.20 martin .fs_type = FS_MSDOS, .fs_sub_type = MBR_PTYPE_FAT32L, 698 1.20 martin }; 699 1.20 martin 700 1.20 martin if (!uefi_boot) 701 1.20 martin return parts_use_wholedisk(parts, 0, NULL); 702 1.20 martin 703 1.20 martin boot_part.nat_type = parts->pscheme->get_generic_part_type( 704 1.20 martin PT_EFI_SYSTEM); 705 1.20 martin 706 1.20 martin return parts_use_wholedisk(parts, 1, &boot_part); 707 1.1 dholland } 708 1.1 dholland 709 1.15 martin static bool 710 1.15 martin get_bios_info(const char *dev, struct disk_partitions *parts, int *bcyl, 711 1.15 martin int *bhead, int *bsec) 712 1.1 dholland { 713 1.1 dholland static struct disklist *disklist = NULL; 714 1.1 dholland static int mib[2] = {CTL_MACHDEP, CPU_DISKINFO}; 715 1.1 dholland int i; 716 1.1 dholland size_t len; 717 1.1 dholland struct biosdisk_info *bip; 718 1.1 dholland struct nativedisk_info *nip = NULL, *nat; 719 1.15 martin int cyl, head, sec; 720 1.1 dholland 721 1.1 dholland if (disklist == NULL) { 722 1.1 dholland if (sysctl(mib, 2, NULL, &len, NULL, 0) < 0) 723 1.1 dholland goto nogeom; 724 1.1 dholland disklist = malloc(len); 725 1.1 dholland if (disklist == NULL) { 726 1.1 dholland fprintf(stderr, "Out of memory\n"); 727 1.15 martin return false; 728 1.1 dholland } 729 1.1 dholland sysctl(mib, 2, disklist, &len, NULL, 0); 730 1.1 dholland } 731 1.1 dholland 732 1.1 dholland for (i = 0; i < disklist->dl_nnativedisks; i++) { 733 1.1 dholland nat = &disklist->dl_nativedisks[i]; 734 1.1 dholland if (!strcmp(dev, nat->ni_devname)) { 735 1.1 dholland nip = nat; 736 1.1 dholland break; 737 1.1 dholland } 738 1.1 dholland } 739 1.1 dholland if (nip == NULL || nip->ni_nmatches == 0) { 740 1.1 dholland nogeom: 741 1.1 dholland if (nip != NULL) 742 1.18 christos msg_fmt_display(MSG_nobiosgeom, "%d%d%d", 743 1.18 christos pm->dlcyl, pm->dlhead, pm->dlsec); 744 1.15 martin if (guess_biosgeom_from_parts(parts, &cyl, &head, &sec) >= 0 745 1.1 dholland && nip != NULL) 746 1.18 christos { 747 1.18 christos msg_fmt_display_add(MSG_biosguess, "%d%d%d", 748 1.18 christos cyl, head, sec); 749 1.18 christos } 750 1.1 dholland biosdisk = NULL; 751 1.1 dholland } else { 752 1.15 martin guess_biosgeom_from_parts(parts, &cyl, &head, &sec); 753 1.1 dholland if (nip->ni_nmatches == 1) { 754 1.1 dholland bip = &disklist->dl_biosdisks[nip->ni_biosmatches[0]]; 755 1.1 dholland msg_display(MSG_onebiosmatch); 756 1.1 dholland msg_table_add(MSG_onebiosmatch_header); 757 1.18 christos msg_fmt_table_add(MSG_onebiosmatch_row, "%d%d%d%d%u%u", 758 1.18 christos bip->bi_dev, bip->bi_cyl, bip->bi_head, bip->bi_sec, 759 1.1 dholland (unsigned)bip->bi_lbasecs, 760 1.1 dholland (unsigned)(bip->bi_lbasecs / (1000000000 / 512))); 761 1.1 dholland msg_display_add(MSG_biosgeom_advise); 762 1.1 dholland biosdisk = bip; 763 1.1 dholland process_menu(MENU_biosonematch, &biosdisk); 764 1.1 dholland } else { 765 1.1 dholland msg_display(MSG_biosmultmatch); 766 1.1 dholland msg_table_add(MSG_biosmultmatch_header); 767 1.1 dholland for (i = 0; i < nip->ni_nmatches; i++) { 768 1.1 dholland bip = &disklist->dl_biosdisks[ 769 1.1 dholland nip->ni_biosmatches[i]]; 770 1.18 christos msg_fmt_table_add(MSG_biosmultmatch_row, 771 1.18 christos "%d%d%d%d%d%u%u", i, 772 1.1 dholland bip->bi_dev, bip->bi_cyl, bip->bi_head, 773 1.1 dholland bip->bi_sec, (unsigned)bip->bi_lbasecs, 774 1.1 dholland (unsigned)bip->bi_lbasecs/(1000000000/512)); 775 1.1 dholland } 776 1.1 dholland process_menu(MENU_biosmultmatch, &i); 777 1.1 dholland if (i == -1) 778 1.1 dholland biosdisk = NULL; 779 1.1 dholland else 780 1.1 dholland biosdisk = &disklist->dl_biosdisks[ 781 1.1 dholland nip->ni_biosmatches[i]]; 782 1.1 dholland } 783 1.1 dholland } 784 1.1 dholland if (biosdisk == NULL) { 785 1.17 martin *bcyl = cyl; 786 1.17 martin *bhead = head; 787 1.17 martin *bsec = sec; 788 1.17 martin if (nip != NULL) 789 1.17 martin set_bios_geom(parts, bcyl, bhead, bsec); 790 1.1 dholland } else { 791 1.15 martin *bcyl = biosdisk->bi_cyl; 792 1.15 martin *bhead = biosdisk->bi_head; 793 1.15 martin *bsec = biosdisk->bi_sec; 794 1.1 dholland } 795 1.15 martin return true; 796 1.1 dholland } 797 1.1 dholland 798 1.1 dholland static int 799 1.31 martin mbr_root_above_chs(daddr_t ptstart) 800 1.1 dholland { 801 1.31 martin return ptstart + (daddr_t)DEFROOTSIZE * (daddr_t)(MEG / 512) 802 1.15 martin >= pm->max_chs; 803 1.1 dholland } 804 1.1 dholland 805 1.15 martin /* returns false if no write-back of parts is required */ 806 1.15 martin bool 807 1.15 martin md_mbr_update_check(struct disk_partitions *parts, mbr_info_t *mbri) 808 1.1 dholland { 809 1.1 dholland struct mbr_partition *mbrp; 810 1.1 dholland int i, netbsdpart = -1, oldbsdpart = -1, oldbsdcount = 0; 811 1.1 dholland 812 1.15 martin if (pm->no_mbr || pm->no_part) 813 1.15 martin return false; 814 1.1 dholland 815 1.15 martin mbrp = &mbri->mbr.mbr_parts[0]; 816 1.1 dholland 817 1.1 dholland for (i = 0; i < MBR_PART_COUNT; i++) { 818 1.1 dholland if (mbrp[i].mbrp_type == MBR_PTYPE_386BSD) { 819 1.1 dholland oldbsdpart = i; 820 1.1 dholland oldbsdcount++; 821 1.1 dholland } else if (mbrp[i].mbrp_type == MBR_PTYPE_NETBSD) 822 1.1 dholland netbsdpart = i; 823 1.1 dholland } 824 1.1 dholland 825 1.1 dholland if (netbsdpart == -1 && oldbsdcount == 1) { 826 1.1 dholland mbrp[oldbsdpart].mbrp_type = MBR_PTYPE_NETBSD; 827 1.15 martin return true; 828 1.1 dholland } 829 1.15 martin 830 1.15 martin return false; 831 1.1 dholland } 832 1.1 dholland 833 1.1 dholland /* 834 1.1 dholland * Read MBR code from a file. 835 1.1 dholland * The existing partition table and bootselect configuration is kept. 836 1.1 dholland */ 837 1.1 dholland static int 838 1.1 dholland md_read_bootcode(const char *path, struct mbr_sector *mbrs) 839 1.1 dholland { 840 1.1 dholland int fd; 841 1.1 dholland struct stat st; 842 1.1 dholland size_t len; 843 1.1 dholland struct mbr_sector new_mbr; 844 1.1 dholland uint32_t dsn; 845 1.1 dholland 846 1.1 dholland fd = open(path, O_RDONLY); 847 1.1 dholland if (fd < 0) 848 1.1 dholland return -1; 849 1.1 dholland 850 1.1 dholland if (fstat(fd, &st) < 0 || st.st_size != sizeof *mbrs) { 851 1.1 dholland close(fd); 852 1.1 dholland return -1; 853 1.1 dholland } 854 1.1 dholland 855 1.1 dholland if (read(fd, &new_mbr, sizeof new_mbr) != sizeof new_mbr) { 856 1.1 dholland close(fd); 857 1.1 dholland return -1; 858 1.1 dholland } 859 1.1 dholland close(fd); 860 1.1 dholland 861 1.1 dholland if (new_mbr.mbr_bootsel_magic != htole16(MBR_BS_MAGIC)) 862 1.1 dholland return -1; 863 1.1 dholland 864 1.1 dholland if (mbrs->mbr_bootsel_magic == htole16(MBR_BS_MAGIC)) { 865 1.1 dholland len = offsetof(struct mbr_sector, mbr_bootsel); 866 1.1 dholland } else 867 1.1 dholland len = offsetof(struct mbr_sector, mbr_parts); 868 1.1 dholland 869 1.1 dholland /* Preserve the 'drive serial number' - especially for Vista */ 870 1.1 dholland dsn = mbrs->mbr_dsn; 871 1.1 dholland memcpy(mbrs, &new_mbr, len); 872 1.1 dholland mbrs->mbr_dsn = dsn; 873 1.1 dholland 874 1.1 dholland /* Keep flags from object file - indicate the properties */ 875 1.1 dholland mbrs->mbr_bootsel.mbrbs_flags = new_mbr.mbr_bootsel.mbrbs_flags; 876 1.1 dholland mbrs->mbr_magic = htole16(MBR_MAGIC); 877 1.1 dholland 878 1.1 dholland return 0; 879 1.1 dholland } 880 1.1 dholland 881 1.1 dholland static unsigned int 882 1.1 dholland get_bootmodel(void) 883 1.1 dholland { 884 1.1 dholland #if defined(__i386__) 885 1.1 dholland struct utsname ut; 886 1.1 dholland #ifdef DEBUG 887 1.1 dholland char *envstr; 888 1.1 dholland 889 1.1 dholland envstr = getenv("BOOTMODEL"); 890 1.1 dholland if (envstr != NULL) 891 1.1 dholland return atoi(envstr); 892 1.1 dholland #endif 893 1.1 dholland 894 1.1 dholland if (uname(&ut) < 0) 895 1.1 dholland ut.version[0] = 0; 896 1.1 dholland 897 1.1 dholland #if defined(SET_KERNEL_TINY) 898 1.1 dholland if (strstr(ut.version, "TINY") != NULL) 899 1.1 dholland return SET_KERNEL_TINY; 900 1.1 dholland #endif 901 1.1 dholland #if defined(SET_KERNEL_PS2) 902 1.1 dholland if (strstr(ut.version, "PS2") != NULL) 903 1.1 dholland return SET_KERNEL_PS2; 904 1.1 dholland #endif 905 1.1 dholland #endif 906 1.1 dholland return SET_KERNEL_GENERIC; 907 1.1 dholland } 908 1.1 dholland 909 1.1 dholland 910 1.1 dholland int 911 1.19 martin md_pre_mount(struct install_partition_desc *install, size_t ndx) 912 1.1 dholland { 913 1.1 dholland return 0; 914 1.1 dholland } 915 1.15 martin 916 1.15 martin #ifdef HAVE_GPT 917 1.15 martin /* 918 1.15 martin * New GPT partitions have been written, update bootloader or remember 919 1.15 martin * data untill needed in md_post_newfs 920 1.15 martin */ 921 1.15 martin bool 922 1.15 martin md_gpt_post_write(struct disk_partitions *parts, part_id root_id, 923 1.15 martin bool root_is_new, part_id efi_id, bool efi_is_new) 924 1.15 martin { 925 1.15 martin struct disk_part_info info; 926 1.15 martin 927 1.15 martin if (root_id != NO_PART) { 928 1.15 martin /* we always update the gpt boot record for now */ 929 1.15 martin if (!parts->pscheme->get_part_info(parts, root_id, &info)) 930 1.15 martin return false; 931 1.15 martin if (run_program(RUN_SILENT, "gpt biosboot -b %" PRIu64 " %s", 932 1.15 martin info.start, parts->disk) != 0) 933 1.15 martin return false; 934 1.15 martin } 935 1.15 martin 936 1.15 martin return true; 937 1.15 martin } 938 1.15 martin #endif 939 1.20 martin 940 1.20 martin /* 941 1.20 martin * When we do an UEFI install, we have completely different default 942 1.20 martin * partitions and need to adjust the description at runtime. 943 1.20 martin */ 944 1.20 martin void 945 1.20 martin x86_md_part_defaults(struct pm_devs *cur_pm, struct part_usage_info **partsp, 946 1.20 martin size_t *num_usage_infos) 947 1.20 martin { 948 1.20 martin static const struct part_usage_info uefi_boot_part = 949 1.20 martin { 950 1.20 martin .size = BOOT_PART, 951 1.20 martin .type = BOOT_PART_TYPE, 952 1.20 martin .instflags = PUIINST_NEWFS|PUIINST_BOOT, 953 1.20 martin .fs_type = FS_MSDOS, .fs_version = MBR_PTYPE_FAT32L, 954 1.20 martin .flags = PUIFLAG_ADD_OUTER, 955 1.20 martin }; 956 1.20 martin 957 1.20 martin struct disk_partitions *parts; 958 1.20 martin struct part_usage_info *new_usage, *boot; 959 1.20 martin struct disk_part_info info; 960 1.20 martin size_t num; 961 1.20 martin part_id pno; 962 1.20 martin 963 1.20 martin if (!uefi_boot) 964 1.20 martin return; /* legacy defaults apply */ 965 1.20 martin 966 1.20 martin /* 967 1.20 martin * Insert a UEFI boot partition at the beginning of the array 968 1.20 martin */ 969 1.20 martin 970 1.20 martin /* create space for new description */ 971 1.20 martin num = *num_usage_infos + 1; 972 1.20 martin new_usage = realloc(*partsp, sizeof(*new_usage)*num); 973 1.20 martin if (new_usage == NULL) 974 1.20 martin return; 975 1.20 martin *partsp = new_usage; 976 1.20 martin *num_usage_infos = num; 977 1.20 martin boot = new_usage; 978 1.20 martin memmove(boot+1, boot, sizeof(*boot)*(num-1)); 979 1.20 martin *boot = uefi_boot_part; 980 1.20 martin 981 1.20 martin /* 982 1.20 martin * Check if the UEFI partition already exists 983 1.20 martin */ 984 1.20 martin parts = pm->parts; 985 1.20 martin if (parts->parent != NULL) 986 1.20 martin parts = parts->parent; 987 1.20 martin for (pno = 0; pno < parts->num_part; pno++) { 988 1.20 martin if (!parts->pscheme->get_part_info(parts, pno, &info)) 989 1.20 martin continue; 990 1.20 martin if (info.nat_type->generic_ptype != boot->type) 991 1.20 martin continue; 992 1.20 martin boot->flags &= ~PUIFLAG_ADD_OUTER; 993 1.22 martin boot->flags |= PUIFLG_IS_OUTER|PUIFLG_ADD_INNER; 994 1.20 martin boot->size = info.size; 995 1.20 martin boot->cur_start = info.start; 996 1.20 martin boot->cur_flags = info.flags; 997 1.20 martin break; 998 1.20 martin } 999 1.20 martin } 1000 1.20 martin 1001 1.20 martin /* no need to install bootblock if installing for UEFI */ 1002 1.20 martin bool 1003 1.20 martin x86_md_need_bootblock(struct install_partition_desc *install) 1004 1.20 martin { 1005 1.20 martin 1006 1.20 martin return !uefi_boot; 1007 1.20 martin } 1008