Support booting with EFI.

This commit is contained in:
Jonas 'Sortie' Termansen 2023-11-27 23:12:52 +00:00
parent d7635d5cf2
commit 7c8e0a7886
9 changed files with 222 additions and 16 deletions

View File

@ -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.

View File

@ -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"

View File

@ -0,0 +1,7 @@
NAME=grub-i386-efi
EDITION=2
BUILD_LIBRARIES='libiconv? libintl? libfreetype? liblzma?'
SOURCE_PORT=grub
BUILD_SYSTEM=configure
CONFIGURE_ARGS='--disable-werror --program-prefix= --with-platform=efi --target=i686-sortix'
MAKE_ARGS='-C grub-core'

View File

@ -0,0 +1,8 @@
NAME=grub-i386-pc
EDITION=2
RENAMES="grub@1: grub-i386-pc@2"
BUILD_LIBRARIES='libiconv? libintl? libfreetype? liblzma?'
SOURCE_PORT=grub
BUILD_SYSTEM=configure
CONFIGURE_ARGS='--disable-werror --program-prefix= --with-platform=pc'
MAKE_ARGS='-C grub-core'

View File

@ -0,0 +1,8 @@
NAME=grub-x86_64-efi
EDITION=2
BUILD_LIBRARIES='libiconv? libintl? libfreetype? liblzma?'
SOURCE_PORT=grub
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'

View File

@ -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 <grub/util/install.h>
+#ifdef __sortix__
+#include <sys/kernelinfo.h>
+
+#include <string.h>
+#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,44 @@ 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)
@@ -1803,6 +1806,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 +1814,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 +1059,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
+}

View File

@ -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
@ -8,6 +10,6 @@ SHA256SUM=82ac8faf257fb3476969a0b79a0b5fd53d4cdefb2e2aa5941381477e38c5f9c5
UPSTREAM_SITE=https://pub.sortix.org/sortix/toolchain
UPSTREAM_ARCHIVE=$ARCHIVE
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]+)?)

View File

@ -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"

View File

@ -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");