diff options
author | smh <smh@FreeBSD.org> | 2016-01-15 01:22:36 +0000 |
---|---|---|
committer | smh <smh@FreeBSD.org> | 2016-01-15 01:22:36 +0000 |
commit | 97799cc1a6e7cf381d3f16798ccbd1f7559231fe (patch) | |
tree | 079ce19f53f7ea26c2dffe6377b2698ecd53ee78 /sys/boot/efi/loader | |
parent | a3974d0c94003fd73cf6d36d76bd5d1493840538 (diff) | |
download | FreeBSD-src-97799cc1a6e7cf381d3f16798ccbd1f7559231fe.zip FreeBSD-src-97799cc1a6e7cf381d3f16798ccbd1f7559231fe.tar.gz |
Modularise EFI boot loader
Make EFI boot loader modular in preparation for adding ZFS support.
This is a partial commit of the D4515.
Submitted by: Eric McCorkle
Reviewed by: emaste (in part)
MFC after: 2 weeks
X-MFC-With: r293268
Sponsored by: Multiplay
Differential Revision: https://reviews.freebsd.org/D4515
Diffstat (limited to 'sys/boot/efi/loader')
-rw-r--r-- | sys/boot/efi/loader/devicename.c | 37 | ||||
-rw-r--r-- | sys/boot/efi/loader/main.c | 63 |
2 files changed, 68 insertions, 32 deletions
diff --git a/sys/boot/efi/loader/devicename.c b/sys/boot/efi/loader/devicename.c index 45f9871..c6591c8 100644 --- a/sys/boot/efi/loader/devicename.c +++ b/sys/boot/efi/loader/devicename.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include <stand.h> #include <string.h> #include <sys/disklabel.h> +#include <sys/param.h> #include <bootstrap.h> #include <efi.h> @@ -86,7 +87,7 @@ efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) struct devsw *dv; char *cp; const char *np; - int i, err; + int i; /* minimum length check */ if (strlen(devspec) < 2) @@ -101,24 +102,26 @@ efi_parsedev(struct devdesc **dev, const char *devspec, const char **path) if (devsw[i] == NULL) return (ENOENT); - idev = malloc(sizeof(struct devdesc)); - if (idev == NULL) - return (ENOMEM); - - idev->d_dev = dv; - idev->d_type = dv->dv_type; - idev->d_unit = -1; - - err = 0; np = devspec + strlen(dv->dv_name); - if (*np != '\0' && *np != ':') { - idev->d_unit = strtol(np, &cp, 0); - if (cp == np) { - idev->d_unit = -1; - free(idev); - return (EUNIT); + + { + idev = malloc(sizeof(struct devdesc)); + if (idev == NULL) + return (ENOMEM); + + idev->d_dev = dv; + idev->d_type = dv->dv_type; + idev->d_unit = -1; + if (*np != '\0' && *np != ':') { + idev->d_unit = strtol(np, &cp, 0); + if (cp == np) { + idev->d_unit = -1; + free(idev); + return (EUNIT); + } } } + if (*cp != '\0' && *cp != ':') { free(idev); return (EINVAL); @@ -137,7 +140,7 @@ char * efi_fmtdev(void *vdev) { struct devdesc *dev = (struct devdesc *)vdev; - static char buf[32]; /* XXX device length constant? */ + static char buf[SPECNAMELEN + 1]; switch(dev->d_type) { case DEVT_NONE: diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c index ddd96b4..43a015d 100644 --- a/sys/boot/efi/loader/main.c +++ b/sys/boot/efi/loader/main.c @@ -28,6 +28,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/param.h> #include <stand.h> #include <string.h> #include <setjmp.h> @@ -45,7 +46,6 @@ extern char bootprog_rev[]; extern char bootprog_date[]; extern char bootprog_maker[]; -struct devdesc currdev; /* our current device */ struct arch_switch archsw; /* MI/MD interface boundary */ EFI_GUID acpi = ACPI_TABLE_GUID; @@ -61,15 +61,36 @@ EFI_GUID memtype = MEMORY_TYPE_INFORMATION_TABLE_GUID; EFI_GUID debugimg = DEBUG_IMAGE_INFO_TABLE_GUID; EFI_GUID fdtdtb = FDT_TABLE_GUID; +/* + * Need this because EFI uses UTF-16 unicode string constants, but we + * use UTF-8. We can't use printf due to the possiblity of \0 and we + * don't support support wide characters either. + */ +static void +print_str16(const CHAR16 *str) +{ + int i; + + for (i = 0; str[i]; i++) + printf("%c", (char)str[i]); +} + EFI_STATUS main(int argc, CHAR16 *argv[]) { char var[128]; EFI_LOADED_IMAGE *img; EFI_GUID *guid; - int i, j, vargood; + int i, j, vargood, unit; + struct devsw *dev; UINTN k; + archsw.arch_autoload = efi_autoload; + archsw.arch_getdev = efi_getdev; + archsw.arch_copyin = efi_copyin; + archsw.arch_copyout = efi_copyout; + archsw.arch_readin = efi_readin; + /* * XXX Chicken-and-egg problem; we want to have console output * early, but some console attributes may depend on reading from @@ -116,6 +137,13 @@ main(int argc, CHAR16 *argv[]) /* Get our loaded image protocol interface structure. */ BS->HandleProtocol(IH, &imgid, (VOID**)&img); + printf("Command line arguments:"); + for (i = 0; i < argc; i++) { + printf(" "); + print_str16(argv[i]); + } + printf("\n"); + printf("Image base: 0x%lx\n", (u_long)img->ImageBase); printf("EFI version: %d.%02d\n", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff); @@ -129,9 +157,6 @@ main(int argc, CHAR16 *argv[]) printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); - efi_handle_lookup(img->DeviceHandle, &currdev.d_dev, &currdev.d_unit); - currdev.d_type = currdev.d_dev->dv_type; - /* * Disable the watchdog timer. By default the boot manager sets * the timer to 5 minutes before invoking a boot option. If we @@ -143,19 +168,27 @@ main(int argc, CHAR16 *argv[]) */ BS->SetWatchdogTimer(0, 0, 0, NULL); - env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev), - efi_setcurrdev, env_nounset); - env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset, - env_nounset); + if (efi_handle_lookup(img->DeviceHandle, &dev, &unit) != 0) + return (EFI_NOT_FOUND); + + switch (dev->dv_type) { + default: { + struct devdesc currdev; + + currdev.d_dev = dev; + currdev.d_unit = unit; + currdev.d_opendata = NULL; + currdev.d_type = currdev.d_dev->dv_type; + env_setenv("currdev", EV_VOLATILE, efi_fmtdev(&currdev), + efi_setcurrdev, env_nounset); + env_setenv("loaddev", EV_VOLATILE, efi_fmtdev(&currdev), env_noset, + env_nounset); + break; + } + } setenv("LINES", "24", 1); /* optional */ - archsw.arch_autoload = efi_autoload; - archsw.arch_getdev = efi_getdev; - archsw.arch_copyin = efi_copyin; - archsw.arch_copyout = efi_copyout; - archsw.arch_readin = efi_readin; - for (k = 0; k < ST->NumberOfTableEntries; k++) { guid = &ST->ConfigurationTable[k].VendorGuid; if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) { |