From 2ee030f4092ca53e394b161b94b384e86f49d651 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Mon, 27 Nov 2023 23:12:52 +0000 Subject: [PATCH] Support booting with EFI. --- build-aux/iso-grub-cfg.sh | 2 +- build-aux/ports.conf | 4 +- ports/grub-i386-efi/grub-i386-efi.port | 8 + ports/grub-i386-pc/grub-i386-pc.port | 9 ++ ports/grub-x86_64-efi/grub-x86_64-efi.port | 9 ++ ports/grub/grub.patch | 169 ++++++++++++++++++++- ports/grub/grub.port | 7 +- ports/grub/grub.post-install | 3 + ports/signify/signify.port | 1 + share/man/man7/installation.7 | 80 +++++++--- sysinstall/sysinstall.c | 63 ++++++-- sysinstall/sysmerge.c | 7 +- sysinstall/sysupgrade.c | 3 +- 13 files changed, 328 insertions(+), 37 deletions(-) create mode 100644 ports/grub-i386-efi/grub-i386-efi.port create mode 100644 ports/grub-i386-pc/grub-i386-pc.port create mode 100644 ports/grub-x86_64-efi/grub-x86_64-efi.port diff --git a/build-aux/iso-grub-cfg.sh b/build-aux/iso-grub-cfg.sh index 6f526761..49d24153 100755 --- a/build-aux/iso-grub-cfg.sh +++ b/build-aux/iso-grub-cfg.sh @@ -325,7 +325,7 @@ esac cat << EOF hook_kernel_pre echo -n "Loading /$kernel ($(human_size $kernel)) ... " - multiboot /$kernel \$no_random_seed \$enable_network_drivers \$chain "\$@" + multiboot /$kernel --firmware=\$grub_platform \$no_random_seed \$enable_network_drivers \$chain "\$@" echo done hook_kernel_post # TODO: Injecting configuration doesn't work for mounted cdroms. diff --git a/build-aux/ports.conf b/build-aux/ports.conf index d27b3a99..7fdf6e6d 100644 --- a/build-aux/ports.conf +++ b/build-aux/ports.conf @@ -1,3 +1,3 @@ -set_minimal="cut dash e2fsprogs grep grub libssl mdocml sed signify tar wget xargs xz" -set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip irssi libcurl libcurses libstdc++ m4 make nano ntpd patch perl pkg-config python ssh texinfo vim xorriso" +set_minimal="cut dash dosfstools e2fsprogs grep grub grub-i386-pc grub-i386-efi grub-x86_64-efi libssl mdocml sed signify tar wget xargs xz" +set_basic="$set_minimal binutils bison bzip2 diffutils ed flex gawk gcc git gzip irssi libcurl libcurses libstdc++ m4 make mtools nano ntpd patch perl pkg-config python ssh texinfo vim xorriso" sets="basic minimal" diff --git a/ports/grub-i386-efi/grub-i386-efi.port b/ports/grub-i386-efi/grub-i386-efi.port new file mode 100644 index 00000000..cae01e49 --- /dev/null +++ b/ports/grub-i386-efi/grub-i386-efi.port @@ -0,0 +1,8 @@ +NAME=grub-i386-efi +EDITION=2 +BUILD_LIBRARIES='libiconv? libintl? libfreetype? liblzma?' +SOURCE_PORT=grub +LICENSE=GPL-3.0-or-later +BUILD_SYSTEM=configure +CONFIGURE_ARGS='--disable-werror --program-prefix= --with-platform=efi --target=i686-sortix' +MAKE_ARGS='-C grub-core' diff --git a/ports/grub-i386-pc/grub-i386-pc.port b/ports/grub-i386-pc/grub-i386-pc.port new file mode 100644 index 00000000..5df58227 --- /dev/null +++ b/ports/grub-i386-pc/grub-i386-pc.port @@ -0,0 +1,9 @@ +NAME=grub-i386-pc +EDITION=2 +RENAMES="grub@1: grub-i386-pc@2" +BUILD_LIBRARIES='libiconv? libintl? libfreetype? liblzma?' +SOURCE_PORT=grub +LICENSE=GPL-3.0-or-later +BUILD_SYSTEM=configure +CONFIGURE_ARGS='--disable-werror --program-prefix= --with-platform=pc' +MAKE_ARGS='-C grub-core' diff --git a/ports/grub-x86_64-efi/grub-x86_64-efi.port b/ports/grub-x86_64-efi/grub-x86_64-efi.port new file mode 100644 index 00000000..f6d0866a --- /dev/null +++ b/ports/grub-x86_64-efi/grub-x86_64-efi.port @@ -0,0 +1,9 @@ +NAME=grub-x86_64-efi +EDITION=2 +BUILD_LIBRARIES='libiconv? libintl? libfreetype? liblzma?' +SOURCE_PORT=grub +LICENSE=GPL-3.0-or-later +BUILD_SYSTEM=configure +# TODO: Unfortunately 32-bit sortix gcc fails due to no 64-bit support. +CONFIGURE_ARGS='--disable-werror --program-prefix= --with-platform=efi --target=x86_64-sortix' +MAKE_ARGS='-C grub-core' diff --git a/ports/grub/grub.patch b/ports/grub/grub.patch index 813397d2..a5593672 100644 --- a/ports/grub/grub.patch +++ b/ports/grub/grub.patch @@ -253,6 +253,36 @@ diff -Paur --no-dereference -- grub.upstream/grub-core/lib/libgcrypt-grub/cipher { k[i >> 2][i & 3] = key[i]; } +diff -Paur --no-dereference -- grub.upstream/grub-core/osdep/basic/platform.c grub/grub-core/osdep/basic/platform.c +--- grub.upstream/grub-core/osdep/basic/platform.c ++++ grub/grub-core/osdep/basic/platform.c +@@ -18,9 +18,25 @@ + + #include + ++#ifdef __sortix__ ++#include ++ ++#include ++#endif ++ + const char * + grub_install_get_default_x86_platform (void) +-{ ++{ ++#ifdef __sortix__ ++ char firmware[16]; ++ if (!kernelinfo("firmware", firmware, sizeof(firmware)) && ++ !strcmp(firmware, "efi")) ++#ifdef __i386__ ++ return "i386-efi"; ++#else ++ return "x86_64-efi"; ++#endif ++#endif + return "i386-pc"; + } + diff -Paur --no-dereference -- grub.upstream/grub-core/osdep/getroot.c grub/grub-core/osdep/getroot.c --- grub.upstream/grub-core/osdep/getroot.c +++ grub/grub-core/osdep/getroot.c @@ -564,6 +594,41 @@ diff -Paur --no-dereference -- grub.upstream/grub-core/osdep/sortix/random.c gru + arc4random_buf(out, len); + return 0; +} +diff -Paur --no-dereference -- grub.upstream/grub-core/osdep/unix/config.c grub/grub-core/osdep/unix/config.c +--- grub.upstream/grub-core/osdep/unix/config.c ++++ grub/grub-core/osdep/unix/config.c +@@ -35,8 +35,7 @@ + { + static char *value = NULL; + if (!value) +- value = grub_util_path_concat (3, GRUB_SYSCONFDIR, +- "default", "grub"); ++ value = grub_util_path_concat (2, GRUB_SYSCONFDIR, "grub"); + return value; + } + +@@ -78,6 +77,10 @@ + if (v && v[0] == 'y' && v[1] == '\0') + cfg->is_cryptodisk_enabled = 1; + ++ v = getenv ("GRUB_REMOVABLE"); ++ if (v && grub_strcmp (v, "true") == 0) ++ cfg->is_removable = 1; ++ + v = getenv ("GRUB_DISTRIBUTOR"); + if (v) + cfg->grub_distributor = xstrdup (v); +@@ -105,8 +108,8 @@ + *ptr++ = *iptr; + } + +- strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\n\" " +- "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\""); ++ strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_REMOVABLE=%s\\nGRUB_DISTRIBUTOR=%s\\n\" " ++ "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_REMOVABLE\" \"$GRUB_DISTRIBUTOR\""); + + argv[2] = script; + argv[3] = '\0'; diff -Paur --no-dereference -- grub.upstream/grub-core/osdep/unix/getroot.c grub/grub-core/osdep/unix/getroot.c --- grub.upstream/grub-core/osdep/unix/getroot.c +++ grub/grub-core/osdep/unix/getroot.c @@ -640,6 +705,17 @@ diff -Paur --no-dereference -- grub.upstream/grub-core/osdep/unix/platform.c gru bootnum = line + sizeof ("Boot") - 1; bootnum[4] = '\0'; if (!verbosity) +diff -Paur --no-dereference -- grub.upstream/include/grub/emu/config.h grub/include/grub/emu/config.h +--- grub.upstream/include/grub/emu/config.h ++++ grub/include/grub/emu/config.h +@@ -36,6 +36,7 @@ + struct grub_util_config + { + int is_cryptodisk_enabled; ++ int is_removable; + char *grub_distributor; + }; + diff -Paur --no-dereference -- grub.upstream/include/grub/emu/getroot.h grub/include/grub/emu/getroot.h --- grub.upstream/include/grub/emu/getroot.h +++ grub/include/grub/emu/getroot.h @@ -670,6 +746,27 @@ diff -Paur --no-dereference -- grub.upstream/util/bash-completion.d/Makefile.in bashcompletion_DATA = $(bash_completion_script) all: all-am +diff -Paur --no-dereference -- grub.upstream/util/config.c grub/util/config.c +--- grub.upstream/util/config.c ++++ grub/util/config.c +@@ -42,6 +42,17 @@ + cfg->is_cryptodisk_enabled = 1; + continue; + } ++ if (grub_strncmp (ptr, "GRUB_REMOVABLE=", ++ sizeof ("GRUB_REMOVABLE=") - 1) == 0) ++ { ++ ptr += sizeof ("GRUB_REMOVABLE=") - 1; ++ if (*ptr == '"' || *ptr == '\'') ++ ptr++; ++ if (grub_strncmp (ptr, "true", sizeof ("true") - 1) == 0) ++ cfg->is_removable = 1; ++ continue; ++ } ++ + if (grub_strncmp (ptr, "GRUB_DISTRIBUTOR=", + sizeof ("GRUB_DISTRIBUTOR=") - 1) == 0) + { diff -Paur --no-dereference -- grub.upstream/util/getroot.c grub/util/getroot.c --- grub.upstream/util/getroot.c +++ grub/util/getroot.c @@ -724,6 +821,76 @@ diff -Paur --no-dereference -- grub.upstream/util/grub-fstest.c grub/util/grub-f root = alloc_root; } } +diff -Paur --no-dereference -- grub.upstream/util/grub-install.c grub/util/grub-install.c +--- grub.upstream/util/grub-install.c ++++ grub/util/grub-install.c +@@ -848,6 +848,9 @@ + + grub_util_load_config (&config); + ++ if (config.is_removable) ++ removable = 1; ++ + if (!bootloader_id && config.grub_distributor) + { + char *ptr; +@@ -860,7 +863,7 @@ + if (!bootloader_id || bootloader_id[0] == '\0') + { + free (bootloader_id); +- bootloader_id = xstrdup ("grub"); ++ bootloader_id = xstrdup ("sortix"); + } + + if (!grub_install_source_directory) +@@ -923,12 +926,20 @@ + break; + } + ++ if (!bootdir) ++ bootdir = grub_util_path_concat (3, "/", rootdir, GRUB_BOOT_DIR_NAME); ++ + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + if (!install_device) +- grub_util_error ("%s", _("install device isn't specified")); ++ { ++ grub_devices = grub_guess_root_devices (bootdir); ++ if (!grub_devices || !grub_devices[0] || ++ !(install_device = grub_util_get_os_disk (grub_devices[0]))) ++ grub_util_error ("%s", _("install device isn't specified")); ++ } + break; + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + if (install_device) +@@ -961,9 +972,6 @@ + break; + } + +- if (!bootdir) +- bootdir = grub_util_path_concat (3, "/", rootdir, GRUB_BOOT_DIR_NAME); +- + { + char * t = grub_util_path_concat (2, bootdir, GRUB_DIR_NAME); + grub_install_mkdir_p (t); +@@ -1803,6 +1811,7 @@ + break; + + case GRUB_INSTALL_PLATFORM_I386_EFI: ++#ifndef __sortix__ + if (!efidir_is_mac) + { + char *dst = grub_util_path_concat (2, efidir, "grub.efi"); +@@ -1810,6 +1819,7 @@ + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } ++#endif + /* Fallthrough. */ + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + if (efidir_is_mac) diff -Paur --no-dereference -- grub.upstream/util/grub-mkconfig.in grub/util/grub-mkconfig.in --- grub.upstream/util/grub-mkconfig.in +++ grub/util/grub-mkconfig.in @@ -924,7 +1091,7 @@ diff -Paur --no-dereference -- grub.upstream/util/grub.d/10_sortix.in grub/util/ + insmod part_$PARTMAP + insmod $FS + search --no-floppy --fs-uuid --set=root $HINTS_STRING $FS_UUID -+ multiboot $BOOT_REL/sortix.bin $GRUB_CMDLINE_SORTIX ++ multiboot $BOOT_REL/sortix.bin --firmware=\$grub_platform $GRUB_CMDLINE_SORTIX + module $OLD_BOOT_REL/random.seed --random-seed + module $BOOT_REL/sortix.initrd +} diff --git a/ports/grub/grub.port b/ports/grub/grub.port index 957735ed..f425ecb1 100644 --- a/ports/grub/grub.port +++ b/ports/grub/grub.port @@ -1,4 +1,6 @@ NAME=grub +EDITION=2 +RENAMES="grub@1: grub@2" BUILD_LIBRARIES='libiconv? libintl? libfreetype? liblzma?' VERSION=1.0-rc1 DISTNAME=sortix-grub-$VERSION @@ -7,7 +9,8 @@ ARCHIVE=$DISTNAME.$COMPRESSION SHA256SUM=82ac8faf257fb3476969a0b79a0b5fd53d4cdefb2e2aa5941381477e38c5f9c5 UPSTREAM_SITE=https://pub.sortix.org/sortix/toolchain UPSTREAM_ARCHIVE=$ARCHIVE +LICENSE=GPL-3.0-or-later BUILD_SYSTEM=configure -CONFIGURE_ARGS='--disable-werror --program-prefix=' +CONFIGURE_ARGS='--disable-werror --program-prefix= --with-platform=none' POST_INSTALL=../grub.post-install -VERSION_REGEX='([0-9]+\.[0-9]+(\.[0-9]+)*(-rc[0-9]+)?)' +VERSION_REGEX='([0-9]+\.[0-9]+(\.[0-9]+)*(-rc[0-9]+)?) diff --git a/ports/grub/grub.post-install b/ports/grub/grub.post-install index ffa35618..3a7464d4 100755 --- a/ports/grub/grub.post-install +++ b/ports/grub/grub.post-install @@ -7,3 +7,6 @@ if [ ! -e "$TIX_INSTALL_DIR$PREFIX/share/grub/unicode.pf2" ]; then [ -e /usr/share/grub/unicode.pf2 ] && cp /usr/share/grub/unicode.pf2 "$TIX_INSTALL_DIR$PREFIX/share/grub/unicode.pf2" fi +rm -rf "$TIX_INSTALL_DIR$PREFIX/lib/grub/"*"-none" +rmdir --ignore-fail-on-non-empty "$TIX_INSTALL_DIR$PREFIX/lib/grub" +rmdir --ignore-fail-on-non-empty "$TIX_INSTALL_DIR$PREFIX/lib" diff --git a/ports/signify/signify.port b/ports/signify/signify.port index af51e7c7..2bb3bb62 100644 --- a/ports/signify/signify.port +++ b/ports/signify/signify.port @@ -7,5 +7,6 @@ ARCHIVE=$DISTNAME.$COMPRESSION SHA256SUM=0b423119a27a69d417bb67cd38ccfb03d2a7387706911ee04e5d3c3f50e3619b UPSTREAM_SITE=https://pub.sortix.org/fork/signify UPSTREAM_ARCHIVE=$ARCHIVE +LICENSE=ISC BUILD_SYSTEM=makefile VERSION_REGEX='([0-9]{4}-[0-9]{2}-[0-9]{2})' diff --git a/share/man/man7/installation.7 b/share/man/man7/installation.7 index f7a0b69e..60c061d6 100644 --- a/share/man/man7/installation.7 +++ b/share/man/man7/installation.7 @@ -36,7 +36,7 @@ installation. .It ATA or AHCI harddisk with at least 1 GiB of unpartitioned space. .It -BIOS firmware, or UEFI firmware in legacy mode. +BIOS or EFI firmware. .It PS/2 keyboard/mouse firmware emulation to use those devices. .It @@ -68,6 +68,9 @@ or to copy the release physically onto a USB portable storage device. If the target machine has a cdrom drive, you can burn the release to a cdrom. Insert the installation medium in the computer and power it on. +If you have EFI firmware, you need to disable secure boot. +EFI boot is preferred over the legacy BIOS boot, but you can use whatever method +you prefer if your firmware supports it. If needed, change the boot order in the firmware to prefer the installation medium over any existing operating system installations. .Pp @@ -241,14 +244,28 @@ The answer will default to yes if no existing partitions are found, or if an existing Sortix installation is found that uses the provided bootloader; and will otherwise default to no. .Pp -The bootloader will be installed on the boot harddisk, which is the harddisk -containing the +On +.Sy EFI , +the bootloader will be installed onto the EFI System Partition that you +mount as +.Pa /boot/efi . +EFI installations should accept the bootloader and then pick the default +bootloader through the firmware. +TODO: The bootloader is currently installed as the fallback +.Pa EFI/BOOT/BOOTX64.EFI +or +.Pa EFI/BOOT/BOOTIA32.EFI +paths which doesn't dual-boot very well with other operating systems. +.Pp +On +.Sy BIOS, +the bootloader will be installed on the boot harddisk, which is the +harddisk containing the .Pa /boot partition if any, and otherwise the harddisk containing the root filesystem. -.Pp -Single-boot configurations should use the offered bootloader. -Dual-boot configurations should refuse it and arrange for bootloading by other -means. +Single-boot BIOS configurations should use the offered bootloader. +Dual-boot BIOS configurations should refuse it and arrange for bootloading by +other means. The installer will generate .Pa /etc/grub.d/10_sortix.cache which is a fragment of GRUB configuration that offers the menu option of running @@ -304,15 +321,17 @@ You can view all devices with the command. .Pp If the current device does not already have a partition table, you can create a -.Xr mbr 7 -or .Xr gpt 7 +or +.Xr mbr 7 partition table using the .Sy mktable command. .Xr gpt 7 is the preferred choice for new partition tables as .Xr mbr 7 has unfortunate limitations. +EFI installations should use +.Xr gpt 7 . If you are dissatisfied with the current partition table, you can use the .Sy rmtable @@ -336,17 +355,44 @@ The command removes a partition table entry and effectively deletes all data on the partition. .Pp -If you accepted the included bootloader, it will be installed on the boot -harddisk, which is the harddisk containing the -.Pa /boot -partition if any, and otherwise the harddisk containing the root filesystem. -If the boot harddisk uses the -.Xr gpt 7 -partitioning scheme, then you must create a +If you accepted the included bootloader: +.Bl -bullet +.It +On +.Sy EFI +you need an +.Sy EFI System Partition +mounted at +.Pa /boot/efi . +It should be at least 16 MB to provide room for growth in future versions of the +operating system. +The partition is shared with other operating systems, enlargen it as required +if you wish to dual-boot other operating systems. +The minimum size is 1 MB, however this size is unsupported for operating system +upgrades and doesn't leave room for other operating systems. +.It +On +.Sy BIOS +with +.Sy GPT +you need a .Sy biosboot -partition on the boot harddisk which is where the bootloader will be installed. +partition on the harddisk containing the +.Pa /boot +directory. It should be at the start of the boot harddisk and a size of 1 MiB will be more than sufficient. +.It +On +.Sy BIOS +with +.Sy MBR +you don't need any bootloader partition. +However, the bootloader will be installed unprotected in the unpartitioned +space before the first partition on the harddisk containing the +.Pa /boot +directory. +.El .Pp You need to make a partition containing the root filesystem mounted at .Pa / . diff --git a/sysinstall/sysinstall.c b/sysinstall/sysinstall.c index 3bfe8242..24e3eb1e 100644 --- a/sysinstall/sysinstall.c +++ b/sysinstall/sysinstall.c @@ -69,11 +69,6 @@ const char* prompt_man_page = "installation"; static struct partition_table* search_bios_boot_pt(struct filesystem* root_fs) { - char firmware[64]; - if ( kernelinfo("firmware", firmware, sizeof(firmware)) != 0 ) - return NULL; - if ( strcmp(firmware, "bios") != 0 ) - return NULL; struct blockdevice* bdev = root_fs->bdev; while ( bdev->p ) bdev = bdev->p->parent_bdev; @@ -194,6 +189,10 @@ static bool should_install_bootloader_bdev(struct blockdevice* bdev) static bool should_install_bootloader(void) { + char firmware[16]; + if ( !kernelinfo("firmware", firmware, sizeof(firmware)) && + !strcmp(firmware, "efi") ) + return true; bool any_systems = false; for ( size_t i = 0; i < hds_count; i++ ) { @@ -354,6 +353,9 @@ static void grub_hash_password(char* buffer, size_t buffer_size, const char* pw) static const char* const ignore_kernel_options[] = { + "--firmware=bios", + "--firmware=efi", + "--firmware=pc", "--no-random-seed", "--random-seed", NULL, @@ -511,7 +513,12 @@ int main(void) err(2, "chdir: %s", etc); struct utsname uts; - uname(&uts); + if ( uname(&uts) < 0 ) + err(1, "uname"); + + char firmware[16]; + if ( kernelinfo("firmware", firmware, sizeof(firmware)) != 0 ) + err(1, "kernelinfo"); struct conf conf; conf_init(&conf); @@ -572,6 +579,7 @@ int main(void) missing_program("fsck.ext2") | missing_program("grub-install") | missing_program("man") | + (!strcmp(firmware, "efi") && missing_program("mkfs.fat")) | missing_program("sed") | missing_program("xargs") ) { @@ -909,6 +917,7 @@ int main(void) mktable_tip, devices_tip); struct filesystem* root_filesystem = NULL; struct filesystem* boot_filesystem = NULL; + struct filesystem* esp_filesystem = NULL; struct filesystem* bootloader_filesystem = NULL; bool not_first = false; while ( true ) @@ -951,6 +960,7 @@ int main(void) } root_filesystem = NULL; boot_filesystem = NULL; + esp_filesystem = NULL; bool cant_mount = false; for ( size_t i = 0; i < mountpoints_used; i++ ) { @@ -976,6 +986,8 @@ int main(void) root_filesystem = mnt->fs; if ( !strcmp(mnt->entry.fs_file, "/boot") ) boot_filesystem = mnt->fs; + if ( !strcmp(mnt->entry.fs_file, "/boot/efi") ) + esp_filesystem = mnt->fs; } if ( cant_mount ) continue; @@ -983,12 +995,13 @@ int main(void) bootloader_filesystem = boot_filesystem ? boot_filesystem : root_filesystem; assert(bootloader_filesystem); if ( !strcasecmp(accept_grub, "yes") && + !strcmp(firmware, "bios") && missing_bios_boot_partition(bootloader_filesystem) ) { const char* where = boot_filesystem ? "/boot" : "root"; const char* dev = device_path_of_blockdevice(bootloader_filesystem->bdev); assert(dev); - textf("You are a installing BIOS bootloader and the %s " + textf("You are installing a BIOS bootloader and the %s " "filesystem is located on a GPT partition, but you haven't " "made a BIOS boot partition on the %s GPT disk. Pick " "biosboot during mkpart and make a 1 MiB partition.\n", @@ -1007,10 +1020,41 @@ int main(void) continue; text("Proceeding, but expect the installation to fail.\n"); } + else if ( !strcasecmp(accept_grub, "yes") && + !strcmp(firmware, "efi") && + !esp_filesystem ) + { + textf("You are installing an EFI bootloader, but you haven't made " + "an EFI System Partition. Pick efi during mkpart and make a " + "partition and mount it as /boot/efi.\n"); + char return_to_disked[10]; + while ( true ) + { + // TODO: Document autoinstall key. + prompt(return_to_disked, sizeof(return_to_disked), + "missing_esp_partition", + "Return to disked to make an EFI partition?", "yes"); + if ( strcasecmp(accept_grub, "no") == 0 || + strcasecmp(accept_grub, "yes") == 0 ) + break; + } + if ( !strcasecmp(return_to_disked, "yes") ) + continue; + text("Proceeding, but expect the installation to fail.\n"); + } + // TODO: Verify the ESP is actually FAT and has the correct ID/GUID. + break; } text("\n"); + if ( !strcmp(firmware, "efi") ) + { + // TODO: Ask for GRUB_DISTRIBUTOR when FAT LFN is implemented and make + // GRUB_REMOVABLE optional. + install_configurationf("grub", "w", "GRUB_REMOVABLE=true\n"); + } + textf("We are now ready to install %s %s. Take a moment to verify " "everything is in order.\n", BRAND_DISTRIBUTION_NAME, VERSIONSTR); text("\n"); @@ -1022,7 +1066,7 @@ int main(void) const char* where = mnt->entry.fs_file; printf(" %-16s use as %s\n", devname, where); } - if ( strcasecmp(accept_grub, "yes") == 0 ) + if ( strcasecmp(accept_grub, "yes") == 0 && !strcmp(firmware, "bios") ) { struct partition* bbp = search_bios_boot_partition(bootloader_filesystem); if ( bbp ) @@ -1118,8 +1162,7 @@ int main(void) { printf(" - Installing bootloader...\n"); execute((const char*[]) { "chroot", "-d", ".", "grub-install", - device_path_of_blockdevice(bootloader_filesystem->bdev), NULL }, - "_eqQ"); + NULL }, "_eqQ"); printf(" - Configuring bootloader...\n"); execute((const char*[]) { "chroot", "-d", ".", "update-grub", NULL }, "_eqQ"); diff --git a/sysinstall/sysmerge.c b/sysinstall/sysmerge.c index dde4e4f3..b4aa9151 100644 --- a/sysinstall/sysmerge.c +++ b/sysinstall/sysmerge.c @@ -523,6 +523,10 @@ int main(int argc, char* argv[]) if ( conf.grub ) { + // TODO: After releasing Sortix 1.1, remove the boot device operand. + // It's kept for now to allow a mixed port environment with a + // new base system and old grub when bootstrapping Sortix 1.1 + // on Sortix 1.0. char* boot_path = join_paths(target, "boot"); if ( !boot_path ) err(2, "malloc"); @@ -534,12 +538,11 @@ int main(int argc, char* argv[]) err(2, "Failed to find device of filesystem: %s", boot_path); close(boot_fd); free(boot_path); - // TODO: A better design for finding the parent block device. if ( is_partition_name(boot_device) ) *strrchr(boot_device, 'p') = '\0'; printf(" - Installing bootloader...\n"); execute((const char*[]) { "grub-install", boot_device, - NULL }, "ceqQ", target); + NULL }, "ceqQ", target); free(boot_device); } diff --git a/sysinstall/sysupgrade.c b/sysinstall/sysupgrade.c index 3bb31b26..e777270f 100644 --- a/sysinstall/sysupgrade.c +++ b/sysinstall/sysupgrade.c @@ -913,8 +913,7 @@ int main(void) if ( do_upgrade_bootloader ) { printf(" - Installing bootloader...\n"); - execute((const char*[]) { "chroot", "-d", ".", "grub-install", - bootloader_dev_path, NULL }, + execute((const char*[]) { "chroot", "-d", ".", "grub-install", NULL }, "_eqQ"); printf(" - Configuring bootloader...\n"); execute((const char*[]) { "chroot", "-d", ".", "update-grub", NULL },