1*d24f36faSmartin /* $NetBSD: md.c,v 1.35 2022/02/10 16:11:42 martin 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 -- i386 machine specific routines - also used by amd64 */
3650dbef1aSdholland
3750dbef1aSdholland #include <sys/param.h>
3850dbef1aSdholland #include <sys/sysctl.h>
3950dbef1aSdholland #include <sys/exec.h>
4050dbef1aSdholland #include <sys/utsname.h>
4150dbef1aSdholland #include <sys/types.h>
4250dbef1aSdholland #include <sys/stat.h>
4350dbef1aSdholland #include <machine/cpu.h>
444103857bSmartin #include <assert.h>
4550dbef1aSdholland #include <stdio.h>
4650dbef1aSdholland #include <stddef.h>
4750dbef1aSdholland #include <util.h>
4850dbef1aSdholland #include <dirent.h>
4950dbef1aSdholland #include <termios.h>
5050dbef1aSdholland
5150dbef1aSdholland #include "defs.h"
5250dbef1aSdholland #include "md.h"
5350dbef1aSdholland #include "endian.h"
5450dbef1aSdholland #include "msg_defs.h"
5550dbef1aSdholland #include "menu_defs.h"
5650dbef1aSdholland
5750dbef1aSdholland #ifdef NO_LBA_READS /* for testing */
5850dbef1aSdholland #undef BIFLAG_EXTINT13
5950dbef1aSdholland #define BIFLAG_EXTINT13 0
6050dbef1aSdholland #endif
6150dbef1aSdholland
6250dbef1aSdholland static struct biosdisk_info *biosdisk = NULL;
6332ea71a6Smartin static bool uefi_boot;
6450dbef1aSdholland
6550dbef1aSdholland /* prototypes */
6650dbef1aSdholland
674103857bSmartin static bool get_bios_info(const char*, struct disk_partitions*, int*, int*, int*);
686ddad149Smartin static int mbr_root_above_chs(daddr_t);
6950dbef1aSdholland static int md_read_bootcode(const char *, struct mbr_sector *);
7050dbef1aSdholland static unsigned int get_bootmodel(void);
7150dbef1aSdholland
72c42e76ebSmartin static int conmib[] = { CTL_MACHDEP, CPU_CONSDEV };
73c42e76ebSmartin
7432ea71a6Smartin #define BOOT_PART (128*(MEG/512))
7532ea71a6Smartin #define BOOT_PART_TYPE PT_EFI_SYSTEM
7632ea71a6Smartin
7732ea71a6Smartin static const char * uefi_bootloaders[] = {
7832ea71a6Smartin "/usr/mdec/bootia32.efi",
7932ea71a6Smartin "/usr/mdec/bootx64.efi",
8032ea71a6Smartin };
8132ea71a6Smartin
8250dbef1aSdholland void
md_init(void)8350dbef1aSdholland md_init(void)
8450dbef1aSdholland {
8532ea71a6Smartin char boot_method[100];
8632ea71a6Smartin size_t len;
8732ea71a6Smartin
8832ea71a6Smartin len = sizeof(boot_method);
8932ea71a6Smartin if (sysctlbyname("machdep.bootmethod", boot_method, &len, NULL, 0)
9032ea71a6Smartin != -1) {
9132ea71a6Smartin if (strcmp(boot_method, "BIOS") == 0)
9232ea71a6Smartin uefi_boot = false;
9332ea71a6Smartin else if (strcmp(boot_method, "UEFI") == 0)
9432ea71a6Smartin uefi_boot = true;
9532ea71a6Smartin }
9650dbef1aSdholland }
9750dbef1aSdholland
9850dbef1aSdholland void
md_init_set_status(int flags)9950dbef1aSdholland md_init_set_status(int flags)
10050dbef1aSdholland {
10150dbef1aSdholland (void)flags;
10250dbef1aSdholland
10350dbef1aSdholland /* Default to install same type of kernel as we are running */
10450dbef1aSdholland set_kernel_set(get_bootmodel());
10550dbef1aSdholland }
10650dbef1aSdholland
1074103857bSmartin bool
md_get_info(struct install_partition_desc * install)1084103857bSmartin md_get_info(struct install_partition_desc *install)
1094103857bSmartin {
110957b5cd6Smartin int bcyl = 0, bhead = 0, bsec = 0, res;
1114103857bSmartin
1124103857bSmartin if (pm->no_mbr || pm->no_part)
1134103857bSmartin return true;
1144103857bSmartin
115957b5cd6Smartin again:
1164103857bSmartin if (pm->parts == NULL) {
1174103857bSmartin
1184103857bSmartin const struct disk_partitioning_scheme *ps =
1194103857bSmartin select_part_scheme(pm, NULL, true, NULL);
1204103857bSmartin
1214103857bSmartin if (!ps)
1226fec6798Smartin return false;
1234103857bSmartin
1244103857bSmartin struct disk_partitions *parts =
1254103857bSmartin (*ps->create_new_for_disk)(pm->diskdev,
12686906049Smartin 0, pm->dlsize, true, NULL);
1274103857bSmartin if (!parts)
1284103857bSmartin return false;
1294103857bSmartin
1304103857bSmartin pm->parts = parts;
1314103857bSmartin if (ps->size_limit > 0 && pm->dlsize > ps->size_limit)
1324103857bSmartin pm->dlsize = ps->size_limit;
1334103857bSmartin }
1344103857bSmartin
1354103857bSmartin if (get_bios_info(pm->diskdev, pm->parts, &bcyl, &bhead, &bsec)
1364103857bSmartin && pm->parts->pscheme->change_disk_geom != NULL)
1374103857bSmartin pm->parts->pscheme->change_disk_geom(pm->parts,
1384103857bSmartin bcyl, bhead, bsec);
1394103857bSmartin else
14086906049Smartin set_default_sizemult(pm->diskdev, MEG, pm->sectorsize);
1414103857bSmartin
1424103857bSmartin /*
1434103857bSmartin * If the selected scheme does not need two-stage partitioning
1444103857bSmartin * (like GPT), do not bother to edit the outer partitions.
1454103857bSmartin */
1464103857bSmartin if (pm->parts->pscheme->secondary_partitions == NULL ||
1474103857bSmartin pm->parts->pscheme->secondary_scheme == NULL)
1484103857bSmartin return true;
1494103857bSmartin
1504103857bSmartin if (pm->no_mbr || pm->no_part)
1514103857bSmartin return true;
1524103857bSmartin
153957b5cd6Smartin res = edit_outer_parts(pm->parts);
154957b5cd6Smartin if (res == 0)
155957b5cd6Smartin return false;
156957b5cd6Smartin else if (res == 1)
157957b5cd6Smartin return true;
158957b5cd6Smartin
159957b5cd6Smartin pm->parts->pscheme->destroy_part_scheme(pm->parts);
160957b5cd6Smartin pm->parts = NULL;
161957b5cd6Smartin goto again;
1624103857bSmartin }
1634103857bSmartin
1644103857bSmartin /*
1654103857bSmartin * md back-end code for menu-driven BSD disklabel editor.
1664103857bSmartin */
167957b5cd6Smartin int
md_make_bsd_partitions(struct install_partition_desc * install)1684103857bSmartin md_make_bsd_partitions(struct install_partition_desc *install)
1694103857bSmartin {
1704103857bSmartin return make_bsd_partitions(install);
1714103857bSmartin }
1724103857bSmartin
1734103857bSmartin /*
1744103857bSmartin * any additional partition validation
1754103857bSmartin */
1764103857bSmartin bool
md_check_partitions(struct install_partition_desc * install)1774103857bSmartin md_check_partitions(struct install_partition_desc *install)
1784103857bSmartin {
1794103857bSmartin int rval;
1804103857bSmartin char *bootxx;
1814103857bSmartin
18232ea71a6Smartin /* if booting via UEFI no boot blocks are needed */
18332ea71a6Smartin if (uefi_boot)
18432ea71a6Smartin return true;
18532ea71a6Smartin
1864103857bSmartin /* check we have boot code for the root partition type */
1874103857bSmartin bootxx = bootxx_name(install);
1884103857bSmartin rval = access(bootxx, R_OK);
1894103857bSmartin free(bootxx);
1904103857bSmartin if (rval == 0)
1914103857bSmartin return true;
1924103857bSmartin process_menu(MENU_ok, __UNCONST(MSG_No_Bootcode));
1934103857bSmartin return false;
1944103857bSmartin }
1954103857bSmartin
1964103857bSmartin /*
1974103857bSmartin * hook called before writing new disklabel.
1984103857bSmartin */
1994103857bSmartin bool
md_pre_disklabel(struct install_partition_desc * install,struct disk_partitions * parts)2004103857bSmartin md_pre_disklabel(struct install_partition_desc *install,
2014103857bSmartin struct disk_partitions *parts)
2024103857bSmartin {
2034103857bSmartin
2044103857bSmartin if (parts->parent == NULL)
2054103857bSmartin return true; /* no outer partitions */
2064103857bSmartin
2074103857bSmartin parts = parts->parent;
2084103857bSmartin
2094103857bSmartin msg_display_subst(MSG_dofdisk, 3, parts->disk,
2104103857bSmartin msg_string(parts->pscheme->name),
2114103857bSmartin msg_string(parts->pscheme->short_name));
2124103857bSmartin
2134103857bSmartin /* write edited "MBR" onto disk. */
2144103857bSmartin if (!parts->pscheme->write_to_disk(parts)) {
2154103857bSmartin msg_display(MSG_wmbrfail);
2164103857bSmartin process_menu(MENU_ok, NULL);
2174103857bSmartin return false;
2184103857bSmartin }
2194103857bSmartin return true;
2204103857bSmartin }
2214103857bSmartin
2224103857bSmartin /*
2234103857bSmartin * hook called after writing disklabel to new target disk.
2244103857bSmartin */
2254103857bSmartin bool
md_post_disklabel(struct install_partition_desc * install,struct disk_partitions * parts)2264103857bSmartin md_post_disklabel(struct install_partition_desc *install,
2274103857bSmartin struct disk_partitions *parts)
2284103857bSmartin {
2294103857bSmartin return true;
2304103857bSmartin }
2314103857bSmartin
2324103857bSmartin /*
23332ea71a6Smartin * Do all legacy bootblock update/setup here
2344103857bSmartin */
23532ea71a6Smartin static int
update_bios_boot(struct install_partition_desc * install,bool use_target_files)2364204f810Smartin update_bios_boot(struct install_partition_desc *install, bool use_target_files)
2374103857bSmartin {
2384103857bSmartin int ret;
2394103857bSmartin size_t len;
2404103857bSmartin char boot_options[1024];
2414204f810Smartin char *bootxx_filename, *p;
2424103857bSmartin /*
2434103857bSmartin * XXX - this code retains a lot of cruft from when we went
2444103857bSmartin * to great pains to exclude installboot from the ramdisk
2454103857bSmartin * for size reasons and should be rewritten.
2464103857bSmartin */
2474103857bSmartin static const char *consoles[]={
2484103857bSmartin "pc", /* CONSDEV_PC */
2494103857bSmartin "com0", /* CONSDEV_COM0 */
2504103857bSmartin "com1", /* CONSDEV_COM1 */
2514103857bSmartin "com2", /* CONSDEV_COM2 */
2524103857bSmartin "com3", /* CONSDEV_COM3 */
2534103857bSmartin "com0kbd", /* CONSDEV_COM0KBD */
2544103857bSmartin "com1kbd", /* CONSDEV_COM1KBD */
2554103857bSmartin "com2kbd", /* CONSDEV_COM2KBD */
2564103857bSmartin "com3kbd" /* CONSDEV_COM3KBD */ };
2574103857bSmartin static struct x86_boot_params boottype =
2584103857bSmartin {sizeof boottype, 0, 5, 0, 9600, { '\0' }, "", 0};
2594103857bSmartin struct termios t;
2604103857bSmartin dev_t condev;
2614103857bSmartin
2624103857bSmartin if (pm == NULL || !pm->no_part) {
2634103857bSmartin /*
2644103857bSmartin * Get console device, should either be ttyE0 or tty0n.
2654103857bSmartin * Too hard to double check, so just 'know' the device numbers.
2664103857bSmartin */
2674103857bSmartin len = sizeof condev;
26805e0fd74Smartin if (sysctl(conmib, __arraycount(conmib), &condev, &len, NULL,
26905e0fd74Smartin 0) != -1 && (condev & ~3) == 0x800) {
2704103857bSmartin /* Motherboard serial port */
2714103857bSmartin boottype.bp_consdev = (condev & 3) + 1;
27205e0fd74Smartin /* Defaulting the baud rate to that of stdin should
27305e0fd74Smartin suffice */
2744103857bSmartin if (tcgetattr(0, &t) != -1)
2754103857bSmartin boottype.bp_conspeed = t.c_ispeed;
2764103857bSmartin }
2774103857bSmartin
2784103857bSmartin process_menu(MENU_getboottype, &boottype);
27924ecf24eSchristos msg_fmt_display(MSG_dobootblks, "%s", pm->diskdev);
2804103857bSmartin if (boottype.bp_consdev == ~0u)
2814103857bSmartin /* Use existing bootblocks */
2824103857bSmartin return 0;
2834103857bSmartin }
2844103857bSmartin
2854204f810Smartin if (use_target_files)
2864204f810Smartin ret = cp_within_target("/usr/mdec/boot", "/", 0);
2874204f810Smartin else
2884204f810Smartin ret = cp_to_target("/usr/mdec/boot", "/");
2894103857bSmartin if (ret)
2904103857bSmartin return ret;
2914103857bSmartin if (pm && pm->no_part)
2924103857bSmartin return 0;
2934103857bSmartin
2944204f810Smartin p = bootxx_name(install);
2954204f810Smartin if (p && use_target_files) {
2964204f810Smartin bootxx_filename = strdup(target_expand(p));
2974204f810Smartin free(p);
2984204f810Smartin } else {
2994204f810Smartin bootxx_filename = p;
3004204f810Smartin }
3014103857bSmartin if (bootxx_filename != NULL) {
3024103857bSmartin char rdev[PATH_MAX];
3034103857bSmartin
3044103857bSmartin install->infos[0].parts->pscheme->get_part_device(
3054103857bSmartin install->infos[0].parts, install->infos[0].cur_part_id,
306abce8cb3Smartin rdev, sizeof rdev, NULL, raw_dev_name, true, true);
3074103857bSmartin
3084103857bSmartin snprintf(boot_options, sizeof boot_options,
3094103857bSmartin "console=%s,speed=%u", consoles[boottype.bp_consdev],
3104103857bSmartin boottype.bp_conspeed);
3114103857bSmartin ret = run_program(RUN_DISPLAY,
3128ef7426aSmartin "/usr/sbin/installboot -f -o %s %s %s",
3134103857bSmartin boot_options, rdev, bootxx_filename);
3144103857bSmartin free(bootxx_filename);
31508fc9285Smartin } else {
3164103857bSmartin ret = -1;
31708fc9285Smartin }
3184103857bSmartin
3194103857bSmartin if (ret != 0)
3204103857bSmartin process_menu(MENU_ok,
3214103857bSmartin __UNCONST("Warning: disk is probably not bootable"));
3224103857bSmartin
3234103857bSmartin return ret;
3244103857bSmartin }
3254103857bSmartin
3264204f810Smartin static int
md_post_newfs_bios(struct install_partition_desc * install)3274204f810Smartin md_post_newfs_bios(struct install_partition_desc *install)
3284204f810Smartin {
3294204f810Smartin return update_bios_boot(install, false);
3304204f810Smartin }
3314204f810Smartin
33232ea71a6Smartin /*
33332ea71a6Smartin * Make sure our bootloader(s) are in the proper directory in the boot
33432ea71a6Smartin * boot partition (or update them).
33532ea71a6Smartin */
33632ea71a6Smartin static int
copy_uefi_boot(const struct part_usage_info * boot,bool target_is_populated)337*d24f36faSmartin copy_uefi_boot(const struct part_usage_info *boot, bool target_is_populated)
33832ea71a6Smartin {
3394204f810Smartin char dev[MAXPATHLEN], path[MAXPATHLEN], src[MAXPATHLEN];
340*d24f36faSmartin const char *s;
34132ea71a6Smartin size_t i;
34232ea71a6Smartin int err;
34332ea71a6Smartin
34432ea71a6Smartin if (!boot->parts->pscheme->get_part_device(boot->parts,
345abce8cb3Smartin boot->cur_part_id, dev, sizeof(dev), NULL, plain_name, true, true))
34632ea71a6Smartin return -1;
34732ea71a6Smartin
34832ea71a6Smartin /*
34932ea71a6Smartin * We should have a valid file system on that partition.
35032ea71a6Smartin * Try to mount it and check if there is a /EFI in there.
35132ea71a6Smartin */
35232ea71a6Smartin if (boot->mount[0])
35332ea71a6Smartin strlcpy(path, boot->mount, sizeof(path));
35432ea71a6Smartin else
35532ea71a6Smartin strcpy(path, "/mnt");
35632ea71a6Smartin
35732ea71a6Smartin if (!(boot->instflags & PUIINST_MOUNT)) {
35832ea71a6Smartin make_target_dir(path);
35932ea71a6Smartin err = target_mount("", dev, path);
36032ea71a6Smartin if (err != 0)
36132ea71a6Smartin return err;
36232ea71a6Smartin }
36332ea71a6Smartin
36432ea71a6Smartin strlcat(path, "/EFI/boot", sizeof(path));
36532ea71a6Smartin make_target_dir(path);
36632ea71a6Smartin
36732ea71a6Smartin for (i = 0; i < __arraycount(uefi_bootloaders); i++) {
368*d24f36faSmartin s = uefi_bootloaders[i];
369*d24f36faSmartin strcpy(src, target_is_populated ? target_expand(s) : s);
3704204f810Smartin if (access(src, R_OK) != 0)
37132ea71a6Smartin continue;
372*d24f36faSmartin err = target_is_populated ?
373*d24f36faSmartin cp_within_target(s, path, 0) :
374*d24f36faSmartin cp_to_target(s, path);
37532ea71a6Smartin if (err)
37632ea71a6Smartin return err;
37732ea71a6Smartin }
378*d24f36faSmartin if (boot->mount[0] == 0)
379*d24f36faSmartin target_unmount("/mnt");
38032ea71a6Smartin
38132ea71a6Smartin return 0;
38232ea71a6Smartin }
38332ea71a6Smartin
38432ea71a6Smartin /*
38532ea71a6Smartin * Find (U)EFI boot partition and install/update bootloaders
38632ea71a6Smartin */
38732ea71a6Smartin static int
update_uefi_boot_code(struct install_partition_desc * install,bool target_is_populated)388*d24f36faSmartin update_uefi_boot_code(struct install_partition_desc *install,
389*d24f36faSmartin bool target_is_populated)
39032ea71a6Smartin {
3914204f810Smartin size_t i, boot_part;
39232ea71a6Smartin
3934204f810Smartin boot_part = ~0U;
39432ea71a6Smartin for (i = 0; i < install->num; i++) {
39532ea71a6Smartin if (!(install->infos[i].instflags & PUIINST_BOOT))
39632ea71a6Smartin continue;
3974204f810Smartin boot_part = i;
3984204f810Smartin break;
3994204f810Smartin }
4004204f810Smartin if (boot_part == ~0U) {
4014204f810Smartin /*
4024204f810Smartin * Didn't find an explicitly marked boot partition,
4034204f810Smartin * check if we have any EFI System Partitions and
4044204f810Smartin * use the first.
4054204f810Smartin */
4064204f810Smartin for (i = 0; i < install->num; i++) {
4074204f810Smartin if (install->infos[i].type != PT_EFI_SYSTEM)
4084204f810Smartin continue;
4094204f810Smartin boot_part = i;
4104204f810Smartin break;
4114204f810Smartin }
41232ea71a6Smartin }
41332ea71a6Smartin
4144204f810Smartin if (boot_part < install->num)
415*d24f36faSmartin return copy_uefi_boot(&install->infos[boot_part],
416*d24f36faSmartin target_is_populated);
4174204f810Smartin
41832ea71a6Smartin return -1; /* no EFI boot partition found */
41932ea71a6Smartin }
42032ea71a6Smartin
42132ea71a6Smartin /*
4224204f810Smartin * Find bootloader options and update bootloader
4234204f810Smartin */
4244204f810Smartin static int
update_bios_boot_code(struct install_partition_desc * install)4254204f810Smartin update_bios_boot_code(struct install_partition_desc *install)
4264204f810Smartin {
4274204f810Smartin return update_bios_boot(install, true);
4284204f810Smartin }
4294204f810Smartin
4304204f810Smartin static int
update_boot_code(struct install_partition_desc * install,bool target_is_populated)431*d24f36faSmartin update_boot_code(struct install_partition_desc *install,
432*d24f36faSmartin bool target_is_populated)
4334204f810Smartin {
4344204f810Smartin return uefi_boot ?
435*d24f36faSmartin update_uefi_boot_code(install, target_is_populated)
4364204f810Smartin : update_bios_boot_code(install);
4374204f810Smartin }
4384204f810Smartin
4394204f810Smartin static int
md_post_newfs_uefi(struct install_partition_desc * install)4404204f810Smartin md_post_newfs_uefi(struct install_partition_desc *install)
4414204f810Smartin {
442*d24f36faSmartin return update_uefi_boot_code(install, false);
4434204f810Smartin }
4444204f810Smartin
4454204f810Smartin /*
44632ea71a6Smartin * hook called after upgrade() or install() has finished setting
44732ea71a6Smartin * up the target disk but immediately before the user is given the
44832ea71a6Smartin * ``disks are now set up'' message.
44932ea71a6Smartin */
45032ea71a6Smartin int
md_post_newfs(struct install_partition_desc * install)45132ea71a6Smartin md_post_newfs(struct install_partition_desc *install)
45232ea71a6Smartin {
45332ea71a6Smartin
45432ea71a6Smartin return uefi_boot ? md_post_newfs_uefi(install)
45532ea71a6Smartin : md_post_newfs_bios(install);
45632ea71a6Smartin }
45732ea71a6Smartin
4584103857bSmartin int
md_post_extract(struct install_partition_desc * install,bool upgrade)4594204f810Smartin md_post_extract(struct install_partition_desc *install, bool upgrade)
4604103857bSmartin {
4614204f810Smartin if (upgrade)
462*d24f36faSmartin update_boot_code(install, true);
4634204f810Smartin
464db4a9cc4Smartin #if defined(__amd64__)
465db4a9cc4Smartin if (get_kernel_set() == SET_KERNEL_2) {
466db4a9cc4Smartin int ret;
467db4a9cc4Smartin
468db4a9cc4Smartin ret = cp_within_target("/usr/mdec/prekern", "/prekern", 0);
469db4a9cc4Smartin if (ret)
470db4a9cc4Smartin return ret;
471db4a9cc4Smartin }
472db4a9cc4Smartin #endif
4734204f810Smartin
4744103857bSmartin return 0;
4754103857bSmartin }
4764103857bSmartin
4774103857bSmartin void
md_cleanup_install(struct install_partition_desc * install)4784103857bSmartin md_cleanup_install(struct install_partition_desc *install)
4794103857bSmartin {
4804103857bSmartin size_t len;
4814103857bSmartin dev_t condev;
4824103857bSmartin
4834103857bSmartin #ifndef DEBUG
4844103857bSmartin enable_rc_conf();
4854103857bSmartin add_rc_conf("wscons=YES\n");
4864103857bSmartin
4874103857bSmartin # if defined(__i386__) && defined(SET_KERNEL_TINY)
4884103857bSmartin /*
4894103857bSmartin * For GENERIC_TINY, do not enable any extra screens or wsmux.
4904103857bSmartin * Otherwise, run getty on 4 VTs.
4914103857bSmartin */
4924103857bSmartin if (get_kernel_set() == SET_KERNEL_TINY)
4934103857bSmartin run_program(RUN_CHROOT,
4944103857bSmartin "sed -an -e '/^screen/s/^/#/;/^mux/s/^/#/;"
4954103857bSmartin "H;$!d;g;w /etc/wscons.conf' /etc/wscons.conf");
4964103857bSmartin else
4974103857bSmartin # endif
4984103857bSmartin run_program(RUN_CHROOT,
4994103857bSmartin "sed -an -e '/^ttyE[1-9]/s/off/on/;"
5004103857bSmartin "H;$!d;g;w /etc/ttys' /etc/ttys");
5014103857bSmartin
5024103857bSmartin #endif
5034103857bSmartin
5044103857bSmartin /*
5054103857bSmartin * Get console device, should either be ttyE0 or tty0n.
5064103857bSmartin * Too hard to double check, so just 'know' the device numbers.
5074103857bSmartin */
5084103857bSmartin len = sizeof condev;
5094103857bSmartin if (sysctl(conmib, __arraycount(conmib), &condev, &len, NULL, 0) != -1
5104103857bSmartin && (condev & ~3) != 0x800) {
5114103857bSmartin
5124103857bSmartin /*
5134103857bSmartin * Current console is not com*, assume ttyE*.
5144103857bSmartin * Modify /etc/ttys to use wsvt25 for all ports.
5154103857bSmartin */
5164103857bSmartin
5174103857bSmartin run_program(RUN_CHROOT,
5184103857bSmartin "sed -an -e 's/vt100/wsvt25/g;"
5194103857bSmartin "H;$!d;g;w /etc/ttys' /etc/ttys");
5204103857bSmartin }
5214103857bSmartin }
5224103857bSmartin
5234103857bSmartin int
md_pre_update(struct install_partition_desc * install)5244103857bSmartin md_pre_update(struct install_partition_desc *install)
5254103857bSmartin {
5264103857bSmartin return 1;
5274103857bSmartin }
5284103857bSmartin
5294103857bSmartin /* Upgrade support */
5304103857bSmartin int
md_update(struct install_partition_desc * install)5314103857bSmartin md_update(struct install_partition_desc *install)
5324103857bSmartin {
5334103857bSmartin return 1;
5344103857bSmartin }
5354103857bSmartin
5364103857bSmartin int
md_check_mbr(struct disk_partitions * parts,mbr_info_t * mbri,bool quiet)5374103857bSmartin md_check_mbr(struct disk_partitions *parts, mbr_info_t *mbri, bool quiet)
53850dbef1aSdholland {
53950dbef1aSdholland mbr_info_t *ext;
54050dbef1aSdholland struct mbr_partition *p;
54150dbef1aSdholland const char *bootcode;
5426ddad149Smartin daddr_t inst_start, inst_size;
5434103857bSmartin int i, names, fl, ofl;
54450dbef1aSdholland #define ACTIVE_FOUND 0x0100
54550dbef1aSdholland #define NETBSD_ACTIVE 0x0200
54650dbef1aSdholland #define NETBSD_NAMED 0x0400
54750dbef1aSdholland #define ACTIVE_NAMED 0x0800
54850dbef1aSdholland
54950dbef1aSdholland root_limit = 0;
5506ddad149Smartin if (parts->pscheme->guess_install_target == NULL ||
5516ddad149Smartin !parts->pscheme->guess_install_target(parts, &inst_start,
5526ddad149Smartin &inst_size)) {
5536ddad149Smartin inst_start = parts->disk_start;
5546ddad149Smartin inst_size = parts->disk_size;
5556ddad149Smartin }
5566ddad149Smartin
55750dbef1aSdholland if (biosdisk != NULL && (biosdisk->bi_flags & BIFLAG_EXTINT13) == 0) {
5586ddad149Smartin if (mbr_root_above_chs(inst_start)) {
5594103857bSmartin if (quiet)
5604103857bSmartin return 0;
56150dbef1aSdholland msg_display(MSG_partabovechs);
562e21052b4Smartin if (!ask_noyes(NULL))
5634103857bSmartin return 1;
56450dbef1aSdholland /* The user is shooting themselves in the foot here...*/
5654103857bSmartin } else {
5664103857bSmartin if (parts->pscheme->size_limit)
5674103857bSmartin root_limit = min(parts->pscheme->size_limit,
5684103857bSmartin parts->disk_size);
5694103857bSmartin else
5704103857bSmartin root_limit = parts->disk_size;
5714103857bSmartin }
57250dbef1aSdholland }
57350dbef1aSdholland
57450dbef1aSdholland /*
5756ddad149Smartin * Ensure the install partition (at sector inst_start) and the active
57650dbef1aSdholland * partition are bootable.
57750dbef1aSdholland * Determine whether the bootselect code is needed.
57850dbef1aSdholland * Note that MBR_BS_NEWMBR is always set, so we ignore it!
57950dbef1aSdholland */
58050dbef1aSdholland fl = 0;
58150dbef1aSdholland names = 0;
5824103857bSmartin for (ext = mbri; ext != NULL; ext = ext->extended) {
58350dbef1aSdholland p = ext->mbr.mbr_parts;
58450dbef1aSdholland for (i = 0; i < MBR_PART_COUNT; p++, i++) {
58550dbef1aSdholland if (p->mbrp_flag == MBR_PFLAG_ACTIVE) {
58650dbef1aSdholland fl |= ACTIVE_FOUND;
5876ddad149Smartin if (ext->sector + p->mbrp_start == inst_start)
58850dbef1aSdholland fl |= NETBSD_ACTIVE;
58950dbef1aSdholland }
59050dbef1aSdholland if (ext->mbrb.mbrbs_nametab[i][0] == 0) {
59150dbef1aSdholland /* No bootmenu label... */
59250dbef1aSdholland if (ext->sector == 0)
59350dbef1aSdholland continue;
5946ddad149Smartin if (ext->sector + p->mbrp_start == inst_start)
59550dbef1aSdholland /*
59650dbef1aSdholland * Have installed into an extended ptn
59750dbef1aSdholland * force name & bootsel...
59850dbef1aSdholland */
59950dbef1aSdholland names++;
60050dbef1aSdholland continue;
60150dbef1aSdholland }
60250dbef1aSdholland /* Partition has a bootmenu label... */
60350dbef1aSdholland if (ext->sector != 0)
60450dbef1aSdholland fl |= MBR_BS_EXTLBA;
6056ddad149Smartin if (ext->sector + p->mbrp_start == inst_start)
60650dbef1aSdholland fl |= NETBSD_NAMED;
60750dbef1aSdholland else if (p->mbrp_flag == MBR_PFLAG_ACTIVE)
60850dbef1aSdholland fl |= ACTIVE_NAMED;
60950dbef1aSdholland else
61050dbef1aSdholland names++;
61150dbef1aSdholland }
61250dbef1aSdholland }
61350dbef1aSdholland if (!(fl & ACTIVE_FOUND))
61450dbef1aSdholland fl |= NETBSD_ACTIVE;
61550dbef1aSdholland if (fl & NETBSD_NAMED && fl & NETBSD_ACTIVE)
61650dbef1aSdholland fl |= ACTIVE_NAMED;
61750dbef1aSdholland
61850dbef1aSdholland if ((names > 0 || !(fl & NETBSD_ACTIVE)) &&
61950dbef1aSdholland (!(fl & NETBSD_NAMED) || !(fl & ACTIVE_NAMED))) {
62050dbef1aSdholland /*
62150dbef1aSdholland * There appear to be multiple bootable partitions, but they
62250dbef1aSdholland * don't all have bootmenu texts.
62350dbef1aSdholland */
6244103857bSmartin if (quiet)
6254103857bSmartin return 0;
6264103857bSmartin
62750dbef1aSdholland msg_display(MSG_missing_bootmenu_text);
628e21052b4Smartin if (ask_yesno(NULL))
6294103857bSmartin return 1;
63050dbef1aSdholland }
63150dbef1aSdholland
63250dbef1aSdholland if ((fl & MBR_BS_EXTLBA) &&
63350dbef1aSdholland (biosdisk == NULL || !(biosdisk->bi_flags & BIFLAG_EXTINT13))) {
63450dbef1aSdholland /* Need unsupported LBA reads to read boot sectors */
6354103857bSmartin if (quiet)
6364103857bSmartin return 0;
6374103857bSmartin
63850dbef1aSdholland msg_display(MSG_no_extended_bootmenu);
639e21052b4Smartin if (!ask_noyes(NULL))
6404103857bSmartin return 1;
64150dbef1aSdholland }
64250dbef1aSdholland
64350dbef1aSdholland /* Sort out the name of the mbr code we need */
64457bc5d61Smartin if (names > 1 ||
64557bc5d61Smartin (parts->num_part > 1 && (fl & (NETBSD_NAMED | ACTIVE_NAMED)))) {
64650dbef1aSdholland /* Need bootselect code */
64750dbef1aSdholland fl |= MBR_BS_ACTIVE;
64850dbef1aSdholland bootcode = fl & MBR_BS_EXTLBA ? _PATH_BOOTEXT : _PATH_BOOTSEL;
64957bc5d61Smartin } else {
65050dbef1aSdholland bootcode = _PATH_MBR;
65157bc5d61Smartin }
65250dbef1aSdholland
65350dbef1aSdholland fl &= MBR_BS_ACTIVE | MBR_BS_EXTLBA;
65450dbef1aSdholland
65550dbef1aSdholland /* Look at what is installed */
6564103857bSmartin ofl = mbri->mbrb.mbrbs_flags;
65750dbef1aSdholland if (ofl == 0) {
65850dbef1aSdholland /* Check there is some bootcode at all... */
6594103857bSmartin if (mbri->mbr.mbr_magic != htole16(MBR_MAGIC) ||
6604103857bSmartin mbri->mbr.mbr_jmpboot[0] == 0 ||
6616ddad149Smartin mbr_root_above_chs(inst_start))
66250dbef1aSdholland /* Existing won't do, force update */
66350dbef1aSdholland fl |= MBR_BS_NEWMBR;
66450dbef1aSdholland }
6654103857bSmartin ofl = mbri->oflags & (MBR_BS_ACTIVE | MBR_BS_EXTLBA);
66650dbef1aSdholland
6674103857bSmartin if (!quiet) {
66850dbef1aSdholland if (fl & ~ofl || (fl == 0 && ofl & MBR_BS_ACTIVE)) {
66950dbef1aSdholland /* Existing boot code isn't the right one... */
67050dbef1aSdholland if (fl & MBR_BS_ACTIVE)
67150dbef1aSdholland msg_display(MSG_installbootsel);
67250dbef1aSdholland else
67350dbef1aSdholland msg_display(MSG_installmbr);
67450dbef1aSdholland } else
67550dbef1aSdholland /* Existing code would (probably) be ok */
67650dbef1aSdholland msg_display(MSG_updatembr);
67750dbef1aSdholland
678e21052b4Smartin if (!ask_yesno(NULL))
67950dbef1aSdholland /* User doesn't want to update mbr code */
68050dbef1aSdholland return 2;
68150dbef1aSdholland }
68250dbef1aSdholland
6834103857bSmartin if (md_read_bootcode(bootcode, &mbri->mbr) == 0)
6844103857bSmartin /* update suceeded - to memory copy */
6854103857bSmartin return 2;
6864103857bSmartin
6874103857bSmartin /* This shouldn't happen since the files are in the floppy fs... */
68824ecf24eSchristos msg_fmt_display("Can't find %s", "%s", bootcode);
6894103857bSmartin return ask_reedit(parts);
69050dbef1aSdholland }
69150dbef1aSdholland
6924103857bSmartin bool
md_parts_use_wholedisk(struct disk_partitions * parts)6934103857bSmartin md_parts_use_wholedisk(struct disk_partitions *parts)
6944103857bSmartin {
69532ea71a6Smartin struct disk_part_info boot_part = {
69632ea71a6Smartin .size = BOOT_PART,
69732ea71a6Smartin .fs_type = FS_MSDOS, .fs_sub_type = MBR_PTYPE_FAT32L,
69832ea71a6Smartin };
69932ea71a6Smartin
70032ea71a6Smartin if (!uefi_boot)
7014103857bSmartin return parts_use_wholedisk(parts, 0, NULL);
70232ea71a6Smartin
70332ea71a6Smartin boot_part.nat_type = parts->pscheme->get_generic_part_type(
70432ea71a6Smartin PT_EFI_SYSTEM);
70532ea71a6Smartin
70632ea71a6Smartin return parts_use_wholedisk(parts, 1, &boot_part);
7074103857bSmartin }
7084103857bSmartin
7094103857bSmartin static bool
get_bios_info(const char * dev,struct disk_partitions * parts,int * bcyl,int * bhead,int * bsec)7104103857bSmartin get_bios_info(const char *dev, struct disk_partitions *parts, int *bcyl,
7114103857bSmartin int *bhead, int *bsec)
71250dbef1aSdholland {
71350dbef1aSdholland static struct disklist *disklist = NULL;
71450dbef1aSdholland static int mib[2] = {CTL_MACHDEP, CPU_DISKINFO};
71550dbef1aSdholland int i;
71650dbef1aSdholland size_t len;
71750dbef1aSdholland struct biosdisk_info *bip;
71850dbef1aSdholland struct nativedisk_info *nip = NULL, *nat;
7194103857bSmartin int cyl, head, sec;
72050dbef1aSdholland
72150dbef1aSdholland if (disklist == NULL) {
72250dbef1aSdholland if (sysctl(mib, 2, NULL, &len, NULL, 0) < 0)
72350dbef1aSdholland goto nogeom;
72450dbef1aSdholland disklist = malloc(len);
72550dbef1aSdholland if (disklist == NULL) {
72650dbef1aSdholland fprintf(stderr, "Out of memory\n");
7274103857bSmartin return false;
72850dbef1aSdholland }
72950dbef1aSdholland sysctl(mib, 2, disklist, &len, NULL, 0);
73050dbef1aSdholland }
73150dbef1aSdholland
73250dbef1aSdholland for (i = 0; i < disklist->dl_nnativedisks; i++) {
73350dbef1aSdholland nat = &disklist->dl_nativedisks[i];
73450dbef1aSdholland if (!strcmp(dev, nat->ni_devname)) {
73550dbef1aSdholland nip = nat;
73650dbef1aSdholland break;
73750dbef1aSdholland }
73850dbef1aSdholland }
73950dbef1aSdholland if (nip == NULL || nip->ni_nmatches == 0) {
74050dbef1aSdholland nogeom:
74150dbef1aSdholland if (nip != NULL)
74224ecf24eSchristos msg_fmt_display(MSG_nobiosgeom, "%d%d%d",
74324ecf24eSchristos pm->dlcyl, pm->dlhead, pm->dlsec);
7444103857bSmartin if (guess_biosgeom_from_parts(parts, &cyl, &head, &sec) >= 0
74550dbef1aSdholland && nip != NULL)
74624ecf24eSchristos {
74724ecf24eSchristos msg_fmt_display_add(MSG_biosguess, "%d%d%d",
74824ecf24eSchristos cyl, head, sec);
74924ecf24eSchristos }
75050dbef1aSdholland biosdisk = NULL;
75150dbef1aSdholland } else {
7524103857bSmartin guess_biosgeom_from_parts(parts, &cyl, &head, &sec);
75350dbef1aSdholland if (nip->ni_nmatches == 1) {
75450dbef1aSdholland bip = &disklist->dl_biosdisks[nip->ni_biosmatches[0]];
75550dbef1aSdholland msg_display(MSG_onebiosmatch);
75650dbef1aSdholland msg_table_add(MSG_onebiosmatch_header);
75724ecf24eSchristos msg_fmt_table_add(MSG_onebiosmatch_row, "%d%d%d%d%u%u",
75824ecf24eSchristos bip->bi_dev, bip->bi_cyl, bip->bi_head, bip->bi_sec,
75950dbef1aSdholland (unsigned)bip->bi_lbasecs,
76050dbef1aSdholland (unsigned)(bip->bi_lbasecs / (1000000000 / 512)));
76150dbef1aSdholland msg_display_add(MSG_biosgeom_advise);
76250dbef1aSdholland biosdisk = bip;
76350dbef1aSdholland process_menu(MENU_biosonematch, &biosdisk);
76450dbef1aSdholland } else {
76550dbef1aSdholland msg_display(MSG_biosmultmatch);
76650dbef1aSdholland msg_table_add(MSG_biosmultmatch_header);
76750dbef1aSdholland for (i = 0; i < nip->ni_nmatches; i++) {
76850dbef1aSdholland bip = &disklist->dl_biosdisks[
76950dbef1aSdholland nip->ni_biosmatches[i]];
77024ecf24eSchristos msg_fmt_table_add(MSG_biosmultmatch_row,
77124ecf24eSchristos "%d%d%d%d%d%u%u", i,
77250dbef1aSdholland bip->bi_dev, bip->bi_cyl, bip->bi_head,
77350dbef1aSdholland bip->bi_sec, (unsigned)bip->bi_lbasecs,
77450dbef1aSdholland (unsigned)bip->bi_lbasecs/(1000000000/512));
77550dbef1aSdholland }
77650dbef1aSdholland process_menu(MENU_biosmultmatch, &i);
77750dbef1aSdholland if (i == -1)
77850dbef1aSdholland biosdisk = NULL;
77950dbef1aSdholland else
78050dbef1aSdholland biosdisk = &disklist->dl_biosdisks[
78150dbef1aSdholland nip->ni_biosmatches[i]];
78250dbef1aSdholland }
78350dbef1aSdholland }
78450dbef1aSdholland if (biosdisk == NULL) {
7854103857bSmartin *bcyl = cyl;
7864103857bSmartin *bhead = head;
7874103857bSmartin *bsec = sec;
788d2aaad12Smartin if (nip != NULL)
789d2aaad12Smartin set_bios_geom(parts, bcyl, bhead, bsec);
79050dbef1aSdholland } else {
7914103857bSmartin *bcyl = biosdisk->bi_cyl;
7924103857bSmartin *bhead = biosdisk->bi_head;
7934103857bSmartin *bsec = biosdisk->bi_sec;
79450dbef1aSdholland }
7954103857bSmartin return true;
79650dbef1aSdholland }
79750dbef1aSdholland
79850dbef1aSdholland static int
mbr_root_above_chs(daddr_t ptstart)7996ddad149Smartin mbr_root_above_chs(daddr_t ptstart)
80050dbef1aSdholland {
8016ddad149Smartin return ptstart + (daddr_t)DEFROOTSIZE * (daddr_t)(MEG / 512)
8024103857bSmartin >= pm->max_chs;
80350dbef1aSdholland }
80450dbef1aSdholland
8054103857bSmartin /* returns false if no write-back of parts is required */
8064103857bSmartin bool
md_mbr_update_check(struct disk_partitions * parts,mbr_info_t * mbri)8074103857bSmartin md_mbr_update_check(struct disk_partitions *parts, mbr_info_t *mbri)
80850dbef1aSdholland {
80950dbef1aSdholland struct mbr_partition *mbrp;
81050dbef1aSdholland int i, netbsdpart = -1, oldbsdpart = -1, oldbsdcount = 0;
81150dbef1aSdholland
8124103857bSmartin if (pm->no_mbr || pm->no_part)
8134103857bSmartin return false;
81450dbef1aSdholland
8154103857bSmartin mbrp = &mbri->mbr.mbr_parts[0];
81650dbef1aSdholland
81750dbef1aSdholland for (i = 0; i < MBR_PART_COUNT; i++) {
81850dbef1aSdholland if (mbrp[i].mbrp_type == MBR_PTYPE_386BSD) {
81950dbef1aSdholland oldbsdpart = i;
82050dbef1aSdholland oldbsdcount++;
82150dbef1aSdholland } else if (mbrp[i].mbrp_type == MBR_PTYPE_NETBSD)
82250dbef1aSdholland netbsdpart = i;
82350dbef1aSdholland }
82450dbef1aSdholland
82550dbef1aSdholland if (netbsdpart == -1 && oldbsdcount == 1) {
82650dbef1aSdholland mbrp[oldbsdpart].mbrp_type = MBR_PTYPE_NETBSD;
8274103857bSmartin return true;
82850dbef1aSdholland }
8294103857bSmartin
8304103857bSmartin return false;
83150dbef1aSdholland }
83250dbef1aSdholland
83350dbef1aSdholland /*
83450dbef1aSdholland * Read MBR code from a file.
83550dbef1aSdholland * The existing partition table and bootselect configuration is kept.
83650dbef1aSdholland */
83750dbef1aSdholland static int
md_read_bootcode(const char * path,struct mbr_sector * mbrs)83850dbef1aSdholland md_read_bootcode(const char *path, struct mbr_sector *mbrs)
83950dbef1aSdholland {
84050dbef1aSdholland int fd;
84150dbef1aSdholland struct stat st;
84250dbef1aSdholland size_t len;
84350dbef1aSdholland struct mbr_sector new_mbr;
84450dbef1aSdholland uint32_t dsn;
84550dbef1aSdholland
84650dbef1aSdholland fd = open(path, O_RDONLY);
84750dbef1aSdholland if (fd < 0)
84850dbef1aSdholland return -1;
84950dbef1aSdholland
85050dbef1aSdholland if (fstat(fd, &st) < 0 || st.st_size != sizeof *mbrs) {
85150dbef1aSdholland close(fd);
85250dbef1aSdholland return -1;
85350dbef1aSdholland }
85450dbef1aSdholland
85550dbef1aSdholland if (read(fd, &new_mbr, sizeof new_mbr) != sizeof new_mbr) {
85650dbef1aSdholland close(fd);
85750dbef1aSdholland return -1;
85850dbef1aSdholland }
85950dbef1aSdholland close(fd);
86050dbef1aSdholland
86150dbef1aSdholland if (new_mbr.mbr_bootsel_magic != htole16(MBR_BS_MAGIC))
86250dbef1aSdholland return -1;
86350dbef1aSdholland
86450dbef1aSdholland if (mbrs->mbr_bootsel_magic == htole16(MBR_BS_MAGIC)) {
86550dbef1aSdholland len = offsetof(struct mbr_sector, mbr_bootsel);
86650dbef1aSdholland } else
86750dbef1aSdholland len = offsetof(struct mbr_sector, mbr_parts);
86850dbef1aSdholland
86950dbef1aSdholland /* Preserve the 'drive serial number' - especially for Vista */
87050dbef1aSdholland dsn = mbrs->mbr_dsn;
87150dbef1aSdholland memcpy(mbrs, &new_mbr, len);
87250dbef1aSdholland mbrs->mbr_dsn = dsn;
87350dbef1aSdholland
87450dbef1aSdholland /* Keep flags from object file - indicate the properties */
87550dbef1aSdholland mbrs->mbr_bootsel.mbrbs_flags = new_mbr.mbr_bootsel.mbrbs_flags;
87650dbef1aSdholland mbrs->mbr_magic = htole16(MBR_MAGIC);
87750dbef1aSdholland
87850dbef1aSdholland return 0;
87950dbef1aSdholland }
88050dbef1aSdholland
88150dbef1aSdholland static unsigned int
get_bootmodel(void)88250dbef1aSdholland get_bootmodel(void)
88350dbef1aSdholland {
88450dbef1aSdholland #if defined(__i386__)
88550dbef1aSdholland struct utsname ut;
88650dbef1aSdholland #ifdef DEBUG
88750dbef1aSdholland char *envstr;
88850dbef1aSdholland
88950dbef1aSdholland envstr = getenv("BOOTMODEL");
89050dbef1aSdholland if (envstr != NULL)
89150dbef1aSdholland return atoi(envstr);
89250dbef1aSdholland #endif
89350dbef1aSdholland
89450dbef1aSdholland if (uname(&ut) < 0)
89550dbef1aSdholland ut.version[0] = 0;
89650dbef1aSdholland
89750dbef1aSdholland #if defined(SET_KERNEL_TINY)
89850dbef1aSdholland if (strstr(ut.version, "TINY") != NULL)
89950dbef1aSdholland return SET_KERNEL_TINY;
90050dbef1aSdholland #endif
90150dbef1aSdholland #if defined(SET_KERNEL_PS2)
90250dbef1aSdholland if (strstr(ut.version, "PS2") != NULL)
90350dbef1aSdholland return SET_KERNEL_PS2;
90450dbef1aSdholland #endif
90550dbef1aSdholland #endif
90650dbef1aSdholland return SET_KERNEL_GENERIC;
90750dbef1aSdholland }
90850dbef1aSdholland
90950dbef1aSdholland
91050dbef1aSdholland int
md_pre_mount(struct install_partition_desc * install,size_t ndx)9114f30cbf3Smartin md_pre_mount(struct install_partition_desc *install, size_t ndx)
91250dbef1aSdholland {
91350dbef1aSdholland return 0;
91450dbef1aSdholland }
9154103857bSmartin
9164103857bSmartin #ifdef HAVE_GPT
9174103857bSmartin /*
9184103857bSmartin * New GPT partitions have been written, update bootloader or remember
9194103857bSmartin * data untill needed in md_post_newfs
9204103857bSmartin */
9214103857bSmartin 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)9224103857bSmartin md_gpt_post_write(struct disk_partitions *parts, part_id root_id,
9234103857bSmartin bool root_is_new, part_id efi_id, bool efi_is_new)
9244103857bSmartin {
9254103857bSmartin struct disk_part_info info;
9264103857bSmartin
9274103857bSmartin if (root_id != NO_PART) {
9284103857bSmartin /* we always update the gpt boot record for now */
9294103857bSmartin if (!parts->pscheme->get_part_info(parts, root_id, &info))
9304103857bSmartin return false;
9314103857bSmartin if (run_program(RUN_SILENT, "gpt biosboot -b %" PRIu64 " %s",
9324103857bSmartin info.start, parts->disk) != 0)
9334103857bSmartin return false;
9344103857bSmartin }
9354103857bSmartin
9364103857bSmartin return true;
9374103857bSmartin }
9384103857bSmartin #endif
93932ea71a6Smartin
94032ea71a6Smartin /*
94132ea71a6Smartin * When we do an UEFI install, we have completely different default
94232ea71a6Smartin * partitions and need to adjust the description at runtime.
94332ea71a6Smartin */
94432ea71a6Smartin void
x86_md_part_defaults(struct pm_devs * cur_pm,struct part_usage_info ** partsp,size_t * num_usage_infos)94532ea71a6Smartin x86_md_part_defaults(struct pm_devs *cur_pm, struct part_usage_info **partsp,
94632ea71a6Smartin size_t *num_usage_infos)
94732ea71a6Smartin {
94832ea71a6Smartin static const struct part_usage_info uefi_boot_part =
94932ea71a6Smartin {
95032ea71a6Smartin .size = BOOT_PART,
95132ea71a6Smartin .type = BOOT_PART_TYPE,
95232ea71a6Smartin .instflags = PUIINST_NEWFS|PUIINST_BOOT,
95332ea71a6Smartin .fs_type = FS_MSDOS, .fs_version = MBR_PTYPE_FAT32L,
95432ea71a6Smartin .flags = PUIFLAG_ADD_OUTER,
95532ea71a6Smartin };
95632ea71a6Smartin
95732ea71a6Smartin struct disk_partitions *parts;
95832ea71a6Smartin struct part_usage_info *new_usage, *boot;
95932ea71a6Smartin struct disk_part_info info;
96032ea71a6Smartin size_t num;
96132ea71a6Smartin part_id pno;
96232ea71a6Smartin
96332ea71a6Smartin if (!uefi_boot)
96432ea71a6Smartin return; /* legacy defaults apply */
96532ea71a6Smartin
96632ea71a6Smartin /*
96732ea71a6Smartin * Insert a UEFI boot partition at the beginning of the array
96832ea71a6Smartin */
96932ea71a6Smartin
97032ea71a6Smartin /* create space for new description */
97132ea71a6Smartin num = *num_usage_infos + 1;
97232ea71a6Smartin new_usage = realloc(*partsp, sizeof(*new_usage)*num);
97332ea71a6Smartin if (new_usage == NULL)
97432ea71a6Smartin return;
97532ea71a6Smartin *partsp = new_usage;
97632ea71a6Smartin *num_usage_infos = num;
97732ea71a6Smartin boot = new_usage;
97832ea71a6Smartin memmove(boot+1, boot, sizeof(*boot)*(num-1));
97932ea71a6Smartin *boot = uefi_boot_part;
98032ea71a6Smartin
98132ea71a6Smartin /*
98232ea71a6Smartin * Check if the UEFI partition already exists
98332ea71a6Smartin */
98432ea71a6Smartin parts = pm->parts;
98532ea71a6Smartin if (parts->parent != NULL)
98632ea71a6Smartin parts = parts->parent;
98732ea71a6Smartin for (pno = 0; pno < parts->num_part; pno++) {
98832ea71a6Smartin if (!parts->pscheme->get_part_info(parts, pno, &info))
98932ea71a6Smartin continue;
99032ea71a6Smartin if (info.nat_type->generic_ptype != boot->type)
99132ea71a6Smartin continue;
99232ea71a6Smartin boot->flags &= ~PUIFLAG_ADD_OUTER;
993f77b58b1Smartin boot->flags |= PUIFLG_IS_OUTER|PUIFLG_ADD_INNER;
99432ea71a6Smartin boot->size = info.size;
99532ea71a6Smartin boot->cur_start = info.start;
99632ea71a6Smartin boot->cur_flags = info.flags;
99732ea71a6Smartin break;
99832ea71a6Smartin }
99932ea71a6Smartin }
100032ea71a6Smartin
100132ea71a6Smartin /* no need to install bootblock if installing for UEFI */
100232ea71a6Smartin bool
x86_md_need_bootblock(struct install_partition_desc * install)100332ea71a6Smartin x86_md_need_bootblock(struct install_partition_desc *install)
100432ea71a6Smartin {
100532ea71a6Smartin
100632ea71a6Smartin return !uefi_boot;
100732ea71a6Smartin }
1008