From e4ec6fb518f2d8ca3dfba4a358f9410c777c6ac8 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 2 Aug 2003 08:22:03 +0000 Subject: [PATCH] Don't hardcode unit 0 for the current device if we're loaded from an EFI file system. When booting from a CD and there's already an EFI system partition on the disk, setting the current device to unit 0 will select the harddisk. This invariably breaks installing FreeBSD when other operating systems have been installed before. We obviously want to do the same when we're booting over the network. Maybe later. Based on a patch (from memory) from: arun --- sys/boot/efi/libefi/efiboot.h | 3 +++ sys/boot/efi/libefi/efifs.c | 13 ++++++++++++- sys/boot/efi/loader/main.c | 25 ++++++++----------------- sys/boot/ia64/efi/main.c | 25 ++++++++----------------- 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/sys/boot/efi/libefi/efiboot.h b/sys/boot/efi/libefi/efiboot.h index 3b680d69f9a4..18af3f4bc087 100644 --- a/sys/boot/efi/libefi/efiboot.h +++ b/sys/boot/efi/libefi/efiboot.h @@ -69,6 +69,9 @@ extern struct netif_driver efi_net; /* Find EFI network resources */ extern void efinet_init_driver(void); +/* Map handles to units */ +int efifs_get_unit(EFI_HANDLE); + /* Wrapper over EFI filesystems. */ extern struct fs_ops efi_fsops; diff --git a/sys/boot/efi/libefi/efifs.c b/sys/boot/efi/libefi/efifs.c index ce76e707822b..cf89a9d44884 100644 --- a/sys/boot/efi/libefi/efifs.c +++ b/sys/boot/efi/libefi/efifs.c @@ -291,7 +291,18 @@ struct fs_ops efi_fsops = { }; static EFI_HANDLE *fs_handles; -UINTN fs_handle_count;; +UINTN fs_handle_count; + +int +efifs_get_unit(EFI_HANDLE h) +{ + UINTN u; + + u = 0; + while (u < fs_handle_count && fs_handles[u] != h) + u++; + return ((u < fs_handle_count) ? u : -1); +} static int efifs_dev_init(void) diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c index 58b962036677..752c243abfd1 100644 --- a/sys/boot/efi/loader/main.c +++ b/sys/boot/efi/loader/main.c @@ -54,6 +54,7 @@ extern u_int64_t ia64_pal_entry; EFI_GUID acpi = ACPI_TABLE_GUID; EFI_GUID acpi20 = ACPI_20_TABLE_GUID; +EFI_GUID devid = DEVICE_PATH_PROTOCOL; EFI_GUID hcdp = HCDP_TABLE_GUID; EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; EFI_GUID mps = MPS_TABLE_GUID; @@ -101,8 +102,6 @@ EFI_STATUS main(int argc, CHAR16 *argv[]) { EFI_LOADED_IMAGE *img; - EFI_SIMPLE_NETWORK *net; - EFI_STATUS status; int i; /* @@ -129,7 +128,6 @@ main(int argc, CHAR16 *argv[]) efinet_init_driver(); - /* Get our loaded image protocol interface structure. */ BS->HandleProtocol(IH, &imgid, (VOID**)&img); @@ -139,23 +137,16 @@ main(int argc, CHAR16 *argv[]) printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); - /* - * XXX quick and dirty check to see if we're loaded from the - * network. If so, we set the default device to 'net'. In all - * other cases we set the default device to 'disk'. We presume - * fixed positions in devsw for both net and disk. - */ - status = BS->HandleProtocol(img->DeviceHandle, &netid, (VOID**)&net); - if (status == EFI_SUCCESS && net != NULL) { - currdev.d_dev = devsw[1]; /* XXX net */ - currdev.d_kind.netif.unit = 0; - } else { - currdev.d_dev = devsw[0]; /* XXX disk */ - currdev.d_kind.efidisk.unit = 0; + i = efifs_get_unit(img->DeviceHandle); + if (i >= 0) { + currdev.d_dev = devsw[0]; /* XXX disk */ + currdev.d_kind.efidisk.unit = i; /* XXX should be able to detect this, default to autoprobe */ currdev.d_kind.efidisk.slice = -1; - /* default to 'a' */ currdev.d_kind.efidisk.partition = 0; + } else { + currdev.d_dev = devsw[1]; /* XXX net */ + currdev.d_kind.netif.unit = 0; /* XXX */ } currdev.d_type = currdev.d_dev->dv_type; diff --git a/sys/boot/ia64/efi/main.c b/sys/boot/ia64/efi/main.c index 58b962036677..752c243abfd1 100644 --- a/sys/boot/ia64/efi/main.c +++ b/sys/boot/ia64/efi/main.c @@ -54,6 +54,7 @@ extern u_int64_t ia64_pal_entry; EFI_GUID acpi = ACPI_TABLE_GUID; EFI_GUID acpi20 = ACPI_20_TABLE_GUID; +EFI_GUID devid = DEVICE_PATH_PROTOCOL; EFI_GUID hcdp = HCDP_TABLE_GUID; EFI_GUID imgid = LOADED_IMAGE_PROTOCOL; EFI_GUID mps = MPS_TABLE_GUID; @@ -101,8 +102,6 @@ EFI_STATUS main(int argc, CHAR16 *argv[]) { EFI_LOADED_IMAGE *img; - EFI_SIMPLE_NETWORK *net; - EFI_STATUS status; int i; /* @@ -129,7 +128,6 @@ main(int argc, CHAR16 *argv[]) efinet_init_driver(); - /* Get our loaded image protocol interface structure. */ BS->HandleProtocol(IH, &imgid, (VOID**)&img); @@ -139,23 +137,16 @@ main(int argc, CHAR16 *argv[]) printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); - /* - * XXX quick and dirty check to see if we're loaded from the - * network. If so, we set the default device to 'net'. In all - * other cases we set the default device to 'disk'. We presume - * fixed positions in devsw for both net and disk. - */ - status = BS->HandleProtocol(img->DeviceHandle, &netid, (VOID**)&net); - if (status == EFI_SUCCESS && net != NULL) { - currdev.d_dev = devsw[1]; /* XXX net */ - currdev.d_kind.netif.unit = 0; - } else { - currdev.d_dev = devsw[0]; /* XXX disk */ - currdev.d_kind.efidisk.unit = 0; + i = efifs_get_unit(img->DeviceHandle); + if (i >= 0) { + currdev.d_dev = devsw[0]; /* XXX disk */ + currdev.d_kind.efidisk.unit = i; /* XXX should be able to detect this, default to autoprobe */ currdev.d_kind.efidisk.slice = -1; - /* default to 'a' */ currdev.d_kind.efidisk.partition = 0; + } else { + currdev.d_dev = devsw[1]; /* XXX net */ + currdev.d_kind.netif.unit = 0; /* XXX */ } currdev.d_type = currdev.d_dev->dv_type;