Module Name: src Committed By: martin Date: Sun Jul 14 11:27:34 UTC 2019
Modified Files: src/usr.sbin/sysinst/arch/amd64: md.h src/usr.sbin/sysinst/arch/i386: md.c md.h Log Message: Work in progress UEFI boot support, don't try this at home yet! To generate a diff of this commit: cvs rdiff -u -r1.5 -r1.6 src/usr.sbin/sysinst/arch/amd64/md.h cvs rdiff -u -r1.19 -r1.20 src/usr.sbin/sysinst/arch/i386/md.c cvs rdiff -u -r1.5 -r1.6 src/usr.sbin/sysinst/arch/i386/md.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/sysinst/arch/amd64/md.h diff -u src/usr.sbin/sysinst/arch/amd64/md.h:1.5 src/usr.sbin/sysinst/arch/amd64/md.h:1.6 --- src/usr.sbin/sysinst/arch/amd64/md.h:1.5 Wed Jun 12 06:20:18 2019 +++ src/usr.sbin/sysinst/arch/amd64/md.h Sun Jul 14 11:27:33 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: md.h,v 1.5 2019/06/12 06:20:18 martin Exp $ */ +/* $NetBSD: md.h,v 1.6 2019/07/14 11:27:33 martin Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -110,3 +110,16 @@ extern struct mbr_bootsel *mbs; /* * prototypes for MD code. */ + +/* + * When we do an UEFI install, we have completely different default + * partitions and need to adjust the description at runtime. + */ +void x86_md_part_defaults(struct pm_devs*, struct part_usage_info**, + size_t *num_usage_infos); +#define MD_PART_DEFAULTS(A,B,C) x86_md_part_defaults(A,&(B),&(C)) + +/* no need to install bootblock if installing for UEFI */ +bool x86_md_need_bootblock(struct install_partition_desc *install); +#define MD_NEED_BOOTBLOCK(A) x86_md_need_bootblock(A) + Index: src/usr.sbin/sysinst/arch/i386/md.c diff -u src/usr.sbin/sysinst/arch/i386/md.c:1.19 src/usr.sbin/sysinst/arch/i386/md.c:1.20 --- src/usr.sbin/sysinst/arch/i386/md.c:1.19 Sat Jul 13 17:13:38 2019 +++ src/usr.sbin/sysinst/arch/i386/md.c Sun Jul 14 11:27:33 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: md.c,v 1.19 2019/07/13 17:13:38 martin Exp $ */ +/* $NetBSD: md.c,v 1.20 2019/07/14 11:27:33 martin Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -60,6 +60,7 @@ #endif static struct biosdisk_info *biosdisk = NULL; +static bool uefi_boot; /* prototypes */ @@ -68,11 +69,30 @@ static int mbr_root_above_chs(void); static int md_read_bootcode(const char *, struct mbr_sector *); static unsigned int get_bootmodel(void); -static int conmib[] = {CTL_MACHDEP, CPU_CONSDEV}; +static int conmib[] = { CTL_MACHDEP, CPU_CONSDEV }; + +#define BOOT_PART (128*(MEG/512)) +#define BOOT_PART_TYPE PT_EFI_SYSTEM + +static const char * uefi_bootloaders[] = { + "/usr/mdec/bootia32.efi", + "/usr/mdec/bootx64.efi", +}; void md_init(void) { + char boot_method[100]; + size_t len; + + len = sizeof(boot_method); + if (sysctlbyname("machdep.bootmethod", boot_method, &len, NULL, 0) + != -1) { + if (strcmp(boot_method, "BIOS") == 0) + uefi_boot = false; + else if (strcmp(boot_method, "UEFI") == 0) + uefi_boot = true; + } } void @@ -150,6 +170,10 @@ md_check_partitions(struct install_parti int rval; char *bootxx; + /* if booting via UEFI no boot blocks are needed */ + if (uefi_boot) + return true; + /* check we have boot code for the root partition type */ bootxx = bootxx_name(install); rval = access(bootxx, R_OK); @@ -197,12 +221,10 @@ md_post_disklabel(struct install_partiti } /* - * hook called after upgrade() or install() has finished setting - * up the target disk but immediately before the user is given the - * ``disks are now set up'' message. + * Do all legacy bootblock update/setup here */ -int -md_post_newfs(struct install_partition_desc *install) +static int +md_post_newfs_bios(struct install_partition_desc *install) { int ret; size_t len; @@ -282,6 +304,82 @@ md_post_newfs(struct install_partition_d return ret; } +/* + * Make sure our bootloader(s) are in the proper directory in the boot + * boot partition (or update them). + */ +static int +copy_uefi_boot(const struct part_usage_info *boot) +{ + char dev[MAXPATHLEN], path[MAXPATHLEN]; + size_t i; + int err; + + if (!boot->parts->pscheme->get_part_device(boot->parts, + boot->cur_part_id, dev, sizeof(dev), NULL, plain_name, true)) + return -1; + + /* + * We should have a valid file system on that partition. + * Try to mount it and check if there is a /EFI in there. + */ + if (boot->mount[0]) + strlcpy(path, boot->mount, sizeof(path)); + else + strcpy(path, "/mnt"); + + if (!(boot->instflags & PUIINST_MOUNT)) { + make_target_dir(path); + err = target_mount("", dev, path); + if (err != 0) + return err; + } + + strlcat(path, "/EFI/boot", sizeof(path)); + make_target_dir(path); + + for (i = 0; i < __arraycount(uefi_bootloaders); i++) { + if (access(uefi_bootloaders[i], R_OK) != 0) + continue; + err = cp_to_target(uefi_bootloaders[i], path); + if (err) + return err; + } + + return 0; +} + +/* + * Find (U)EFI boot partition and install/update bootloaders + */ +static int +md_post_newfs_uefi(struct install_partition_desc *install) +{ + size_t i; + + for (i = 0; i < install->num; i++) { + if (!(install->infos[i].instflags & PUIINST_BOOT)) + continue; + + return copy_uefi_boot(&install->infos[i]); + } + + return -1; /* no EFI boot partition found */ +} + +/* + * hook called after upgrade() or install() has finished setting + * up the target disk but immediately before the user is given the + * ``disks are now set up'' message. + */ +int +md_post_newfs(struct install_partition_desc *install) +{ + + return uefi_boot ? md_post_newfs_uefi(install) + : md_post_newfs_bios(install); +} + int md_post_extract(struct install_partition_desc *install) { @@ -497,7 +595,18 @@ md_check_mbr(struct disk_partitions *par bool md_parts_use_wholedisk(struct disk_partitions *parts) { - return parts_use_wholedisk(parts, 0, NULL); + struct disk_part_info boot_part = { + .size = BOOT_PART, + .fs_type = FS_MSDOS, .fs_sub_type = MBR_PTYPE_FAT32L, + }; + + if (!uefi_boot) + return parts_use_wholedisk(parts, 0, NULL); + + boot_part.nat_type = parts->pscheme->get_generic_part_type( + PT_EFI_SYSTEM); + + return parts_use_wholedisk(parts, 1, &boot_part); } static bool @@ -732,3 +841,74 @@ md_gpt_post_write(struct disk_partitions return true; } #endif + +/* + * When we do an UEFI install, we have completely different default + * partitions and need to adjust the description at runtime. + */ +void +x86_md_part_defaults(struct pm_devs *cur_pm, struct part_usage_info **partsp, + size_t *num_usage_infos) +{ + static const struct part_usage_info uefi_boot_part = + { + .size = BOOT_PART, + .type = BOOT_PART_TYPE, + .instflags = PUIINST_NEWFS|PUIINST_BOOT, + .fs_type = FS_MSDOS, .fs_version = MBR_PTYPE_FAT32L, + .flags = PUIFLAG_ADD_OUTER, + }; + + struct disk_partitions *parts; + struct part_usage_info *new_usage, *boot; + struct disk_part_info info; + size_t num; + part_id pno; + + if (!uefi_boot) + return; /* legacy defaults apply */ + + /* + * Insert a UEFI boot partition at the beginning of the array + */ + + /* create space for new description */ + num = *num_usage_infos + 1; + new_usage = realloc(*partsp, sizeof(*new_usage)*num); + if (new_usage == NULL) + return; + *partsp = new_usage; + *num_usage_infos = num; + boot = new_usage; + memmove(boot+1, boot, sizeof(*boot)*(num-1)); + *boot = uefi_boot_part; + + /* + * Check if the UEFI partition already exists + */ + parts = pm->parts; + if (parts->parent != NULL) + parts = parts->parent; + for (pno = 0; pno < parts->num_part; pno++) { + if (!parts->pscheme->get_part_info(parts, pno, &info)) + continue; + if (info.nat_type->generic_ptype != boot->type) + continue; + boot->flags &= ~PUIFLAG_ADD_OUTER; + boot->flags |= PUIFLG_IS_OUTER|PUIFLAG_ADD_INNER; + boot->size = info.size; + boot->cur_start = info.start; + boot->cur_flags = info.flags; + break; + } +} + +/* no need to install bootblock if installing for UEFI */ +bool +x86_md_need_bootblock(struct install_partition_desc *install) +{ + + return !uefi_boot; +} + + Index: src/usr.sbin/sysinst/arch/i386/md.h diff -u src/usr.sbin/sysinst/arch/i386/md.h:1.5 src/usr.sbin/sysinst/arch/i386/md.h:1.6 --- src/usr.sbin/sysinst/arch/i386/md.h:1.5 Wed Jun 12 06:20:21 2019 +++ src/usr.sbin/sysinst/arch/i386/md.h Sun Jul 14 11:27:33 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: md.h,v 1.5 2019/06/12 06:20:21 martin Exp $ */ +/* $NetBSD: md.h,v 1.6 2019/07/14 11:27:33 martin Exp $ */ /* * Copyright 1997 Piermont Information Systems Inc. @@ -112,3 +112,14 @@ extern struct mbr_bootsel *mbs; * prototypes for MD code. */ +/* + * When we do an UEFI install, we have completely different default + * partitions and need to adjust the description at runtime. + */ +void x86_md_part_defaults(struct pm_devs*, struct part_usage_info**, + size_t *num_usage_infos); +#define MD_PART_DEFAULTS(A,B,C) x86_md_part_defaults(A,&(B),&(C)) + +/* no need to install bootblock if installing for UEFI */ +bool x86_md_need_bootblock(struct install_partition_desc *install); +#define MD_NEED_BOOTBLOCK(A) x86_md_need_bootblock(A)