Changeset View
Changeset View
Standalone View
Standalone View
head/stand/efi/boot1/boot1.c
Show First 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
* It tries each module and its respective devices, identified by mod->probe, | * It tries each module and its respective devices, identified by mod->probe, | ||||
* in order until a successful load occurs at which point it returns EFI_SUCCESS | * in order until a successful load occurs at which point it returns EFI_SUCCESS | ||||
* and EFI_NOT_FOUND otherwise. | * and EFI_NOT_FOUND otherwise. | ||||
* | * | ||||
* Only devices which have preferred matching the preferred parameter are tried. | * Only devices which have preferred matching the preferred parameter are tried. | ||||
*/ | */ | ||||
static EFI_STATUS | static EFI_STATUS | ||||
load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp, | load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp, | ||||
size_t *bufsize, BOOLEAN preferred) | size_t *bufsize, int preferred) | ||||
{ | { | ||||
UINTN i; | UINTN i; | ||||
dev_info_t *dev; | dev_info_t *dev; | ||||
const boot_module_t *mod; | const boot_module_t *mod; | ||||
for (i = 0; i < NUM_BOOT_MODULES; i++) { | for (i = 0; i < NUM_BOOT_MODULES; i++) { | ||||
mod = boot_modules[i]; | mod = boot_modules[i]; | ||||
for (dev = mod->devices(); dev != NULL; dev = dev->next) { | for (dev = mod->devices(); dev != NULL; dev = dev->next) { | ||||
Show All 23 Lines | try_boot(void) | ||||
void *buf, *loaderbuf; | void *buf, *loaderbuf; | ||||
char *cmd; | char *cmd; | ||||
dev_info_t *dev; | dev_info_t *dev; | ||||
const boot_module_t *mod; | const boot_module_t *mod; | ||||
EFI_HANDLE loaderhandle; | EFI_HANDLE loaderhandle; | ||||
EFI_LOADED_IMAGE *loaded_image; | EFI_LOADED_IMAGE *loaded_image; | ||||
EFI_STATUS status; | EFI_STATUS status; | ||||
status = load_loader(&mod, &dev, &loaderbuf, &loadersize, TRUE); | status = load_loader(&mod, &dev, &loaderbuf, &loadersize, 1); | ||||
if (status != EFI_SUCCESS) { | if (status != EFI_SUCCESS) { | ||||
status = load_loader(&mod, &dev, &loaderbuf, &loadersize, | status = load_loader(&mod, &dev, &loaderbuf, &loadersize, 0); | ||||
FALSE); | |||||
if (status != EFI_SUCCESS) { | if (status != EFI_SUCCESS) { | ||||
printf("Failed to load '%s'\n", PATH_LOADER_EFI); | printf("Failed to load '%s'\n", PATH_LOADER_EFI); | ||||
return (status); | return (status); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Read in and parse the command line from /boot.config or /boot/config, | * Read in and parse the command line from /boot.config or /boot/config, | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | if (loaderbuf != NULL) | ||||
free(loaderbuf); | free(loaderbuf); | ||||
return (status); | return (status); | ||||
} | } | ||||
/* | /* | ||||
* probe_handle determines if the passed handle represents a logical partition | * probe_handle determines if the passed handle represents a logical partition | ||||
* if it does it uses each module in order to probe it and if successful it | * if it does it uses each module in order to probe it and if successful it | ||||
* returns EFI_SUCCESS. | * returns 0. | ||||
*/ | */ | ||||
static EFI_STATUS | static int | ||||
probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN *preferred) | probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath) | ||||
{ | { | ||||
dev_info_t *devinfo; | dev_info_t *devinfo; | ||||
EFI_BLOCK_IO *blkio; | EFI_BLOCK_IO *blkio; | ||||
EFI_DEVICE_PATH *devpath; | EFI_DEVICE_PATH *devpath; | ||||
EFI_STATUS status; | EFI_STATUS status; | ||||
UINTN i; | UINTN i; | ||||
int preferred; | |||||
/* Figure out if we're dealing with an actual partition. */ | /* Figure out if we're dealing with an actual partition. */ | ||||
status = BS->HandleProtocol(h, &DevicePathGUID, (void **)&devpath); | status = BS->HandleProtocol(h, &DevicePathGUID, (void **)&devpath); | ||||
if (status == EFI_UNSUPPORTED) | if (status == EFI_UNSUPPORTED) | ||||
return (status); | return (0); | ||||
if (status != EFI_SUCCESS) { | if (status != EFI_SUCCESS) { | ||||
DPRINTF("\nFailed to query DevicePath (%lu)\n", | DPRINTF("\nFailed to query DevicePath (%lu)\n", | ||||
EFI_ERROR_CODE(status)); | EFI_ERROR_CODE(status)); | ||||
return (status); | return (-1); | ||||
} | } | ||||
#ifdef EFI_DEBUG | #ifdef EFI_DEBUG | ||||
{ | { | ||||
CHAR16 *text = efi_devpath_name(devpath); | CHAR16 *text = efi_devpath_name(devpath); | ||||
DPRINTF("probing: %S\n", text); | DPRINTF("probing: %S ", text); | ||||
efi_free_devpath_name(text); | efi_free_devpath_name(text); | ||||
} | } | ||||
#endif | #endif | ||||
status = BS->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio); | status = BS->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio); | ||||
if (status == EFI_UNSUPPORTED) | if (status == EFI_UNSUPPORTED) | ||||
return (status); | return (0); | ||||
if (status != EFI_SUCCESS) { | if (status != EFI_SUCCESS) { | ||||
DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n", | DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n", | ||||
EFI_ERROR_CODE(status)); | EFI_ERROR_CODE(status)); | ||||
return (status); | return (-1); | ||||
} | } | ||||
if (!blkio->Media->LogicalPartition) | if (!blkio->Media->LogicalPartition) | ||||
return (EFI_UNSUPPORTED); | return (0); | ||||
*preferred = efi_devpath_same_disk(imgpath, devpath); | preferred = efi_devpath_same_disk(imgpath, devpath); | ||||
/* Run through each module, see if it can load this partition */ | /* Run through each module, see if it can load this partition */ | ||||
devinfo = malloc(sizeof(*devinfo)); | devinfo = malloc(sizeof(*devinfo)); | ||||
if (devinfo == NULL) { | if (devinfo == NULL) { | ||||
DPRINTF("\nFailed to allocate devinfo\n"); | DPRINTF("\nFailed to allocate devinfo\n"); | ||||
return (EFI_UNSUPPORTED); | return (-1); | ||||
} | } | ||||
devinfo->dev = blkio; | devinfo->dev = blkio; | ||||
devinfo->devpath = devpath; | devinfo->devpath = devpath; | ||||
devinfo->devhandle = h; | devinfo->devhandle = h; | ||||
devinfo->preferred = *preferred; | devinfo->preferred = preferred; | ||||
devinfo->next = NULL; | devinfo->next = NULL; | ||||
for (i = 0; i < NUM_BOOT_MODULES; i++) { | for (i = 0; i < NUM_BOOT_MODULES; i++) { | ||||
devinfo->devdata = NULL; | devinfo->devdata = NULL; | ||||
status = boot_modules[i]->probe(devinfo); | status = boot_modules[i]->probe(devinfo); | ||||
if (status == EFI_SUCCESS) | if (status == EFI_SUCCESS) | ||||
return (EFI_SUCCESS); | return (preferred + 1); | ||||
} | } | ||||
free(devinfo); | free(devinfo); | ||||
return (EFI_UNSUPPORTED); | return (0); | ||||
} | } | ||||
/* | const char *prio_str[] = { | ||||
* probe_handle_status calls probe_handle and outputs the returned status | "error", | ||||
* of the call. | "not supported", | ||||
*/ | "good", | ||||
static void | "better" | ||||
probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath) | }; | ||||
{ | |||||
EFI_STATUS status; | |||||
BOOLEAN preferred; | |||||
preferred = FALSE; | |||||
status = probe_handle(h, imgpath, &preferred); | |||||
DPRINTF("probe: "); | |||||
switch (status) { | |||||
case EFI_UNSUPPORTED: | |||||
printf("."); | |||||
DPRINTF(" not supported\n"); | |||||
break; | |||||
case EFI_SUCCESS: | |||||
if (preferred) { | |||||
printf("%c", '*'); | |||||
DPRINTF(" supported (preferred)\n"); | |||||
} else { | |||||
printf("%c", '+'); | |||||
DPRINTF(" supported\n"); | |||||
} | |||||
break; | |||||
default: | |||||
printf("x"); | |||||
DPRINTF(" error (%lu)\n", EFI_ERROR_CODE(status)); | |||||
break; | |||||
} | |||||
DSTALL(500000); | |||||
} | |||||
EFI_STATUS | EFI_STATUS | ||||
efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab) | efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab) | ||||
{ | { | ||||
EFI_HANDLE *handles; | EFI_HANDLE *handles; | ||||
EFI_LOADED_IMAGE *img; | EFI_LOADED_IMAGE *img; | ||||
EFI_DEVICE_PATH *imgpath; | EFI_DEVICE_PATH *imgpath; | ||||
EFI_STATUS status; | EFI_STATUS status; | ||||
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL; | EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL; | ||||
SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL; | SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL; | ||||
UINTN i, hsize, nhandles; | UINTN i, hsize, nhandles; | ||||
CHAR16 *text; | CHAR16 *text; | ||||
UINT16 boot_current; | UINT16 boot_current; | ||||
size_t sz; | size_t sz; | ||||
UINT16 boot_order[100]; | UINT16 boot_order[100]; | ||||
int rv; | |||||
/* Basic initialization*/ | /* Basic initialization*/ | ||||
ST = Xsystab; | ST = Xsystab; | ||||
IH = Ximage; | IH = Ximage; | ||||
BS = ST->BootServices; | BS = ST->BootServices; | ||||
RS = ST->RuntimeServices; | RS = ST->RuntimeServices; | ||||
/* Set up the console, so printf works. */ | /* Set up the console, so printf works. */ | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | #endif | ||||
if (status != EFI_SUCCESS) | if (status != EFI_SUCCESS) | ||||
efi_panic(status, "Failed to get device handles\n"); | efi_panic(status, "Failed to get device handles\n"); | ||||
/* Scan all partitions, probing with all modules. */ | /* Scan all partitions, probing with all modules. */ | ||||
nhandles = hsize / sizeof(*handles); | nhandles = hsize / sizeof(*handles); | ||||
printf(" Probing %zu block devices...", nhandles); | printf(" Probing %zu block devices...", nhandles); | ||||
DPRINTF("\n"); | DPRINTF("\n"); | ||||
for (i = 0; i < nhandles; i++) | for (i = 0; i < nhandles; i++) { | ||||
probe_handle_status(handles[i], imgpath); | rv = probe_handle(handles[i], imgpath); | ||||
#ifdef EFI_DEBUG | |||||
printf("%c", "x.+*"[rv + 1]); | |||||
#else | |||||
printf("%s\n", prio_str[rv + 1]); | |||||
#endif | |||||
} | |||||
printf(" done\n"); | printf(" done\n"); | ||||
/* Status summary. */ | /* Status summary. */ | ||||
for (i = 0; i < NUM_BOOT_MODULES; i++) { | for (i = 0; i < NUM_BOOT_MODULES; i++) { | ||||
printf(" "); | printf(" "); | ||||
boot_modules[i]->status(); | boot_modules[i]->status(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines |