2 * Copyright (c) 1998 Robert Nordier
4 * Copyright (c) 2001 Robert Drehmel
6 * Copyright (c) 2014 Nathan Whitehorn
8 * Copyright (c) 2015 Eric McCorkle
11 * Redistribution and use in source and binary forms are freely
12 * permitted provided that the above copyright notice and this
13 * paragraph and the following disclaimer are duplicated in all
16 * This software is provided "AS IS" and without any express or
17 * implied warranties, including, without limitation, the implied
18 * warranties of merchantability and fitness for a particular
22 #include <sys/cdefs.h>
23 __FBSDID("$FreeBSD$");
25 #include <sys/param.h>
26 #include <machine/elf.h>
27 #include <machine/stdarg.h>
31 #include <eficonsctl.h>
33 #include "boot_module.h"
36 static const boot_module_t *boot_modules[] =
46 #define NUM_BOOT_MODULES (sizeof(boot_modules) / sizeof(boot_module_t*))
47 /* The initial number of handles used to query EFI for partitions. */
48 #define NUM_HANDLES_INIT 24
51 EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
53 EFI_SYSTEM_TABLE *systab;
54 EFI_BOOT_SERVICES *bs;
55 static EFI_HANDLE *image;
57 static EFI_GUID BlockIoProtocolGUID = BLOCK_IO_PROTOCOL;
58 static EFI_GUID DevicePathGUID = DEVICE_PATH_PROTOCOL;
59 static EFI_GUID LoadedImageGUID = LOADED_IMAGE_PROTOCOL;
60 static EFI_GUID ConsoleControlGUID = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
63 * Provide Malloc / Free backed by EFIs AllocatePool / FreePool which ensures
64 * memory is correctly aligned avoiding EFI_INVALID_PARAMETER returns from
68 Malloc(size_t len, const char *file __unused, int line __unused)
72 if (bs->AllocatePool(EfiLoaderData, len, &out) == EFI_SUCCESS)
79 Free(void *buf, const char *file __unused, int line __unused)
81 (void)bs->FreePool(buf);
85 * nodes_match returns TRUE if the imgpath isn't NULL and the nodes match,
89 nodes_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
93 if (imgpath == NULL || imgpath->Type != devpath->Type ||
94 imgpath->SubType != devpath->SubType)
97 len = DevicePathNodeLength(imgpath);
98 if (len != DevicePathNodeLength(devpath))
101 return (memcmp(imgpath, devpath, (size_t)len) == 0);
105 * device_paths_match returns TRUE if the imgpath isn't NULL and all nodes
106 * in imgpath and devpath match up to their respective occurrences of a
107 * media node, FALSE otherwise.
110 device_paths_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
116 while (!IsDevicePathEnd(imgpath) && !IsDevicePathEnd(devpath)) {
117 if (IsDevicePathType(imgpath, MEDIA_DEVICE_PATH) &&
118 IsDevicePathType(devpath, MEDIA_DEVICE_PATH))
121 if (!nodes_match(imgpath, devpath))
124 imgpath = NextDevicePathNode(imgpath);
125 devpath = NextDevicePathNode(devpath);
132 * devpath_last returns the last non-path end node in devpath.
134 static EFI_DEVICE_PATH *
135 devpath_last(EFI_DEVICE_PATH *devpath)
138 while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
139 devpath = NextDevicePathNode(devpath);
145 * devpath_node_str is a basic output method for a devpath node which
146 * only understands a subset of the available sub types.
148 * If we switch to UEFI 2.x then we should update it to use:
149 * EFI_DEVICE_PATH_TO_TEXT_PROTOCOL.
152 devpath_node_str(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
155 switch (devpath->Type) {
156 case MESSAGING_DEVICE_PATH:
157 switch (devpath->SubType) {
159 ATAPI_DEVICE_PATH *atapi;
161 atapi = (ATAPI_DEVICE_PATH *)(void *)devpath;
162 return snprintf(buf, size, "ata(%s,%s,0x%x)",
163 (atapi->PrimarySecondary == 1) ? "Sec" : "Pri",
164 (atapi->SlaveMaster == 1) ? "Slave" : "Master",
168 USB_DEVICE_PATH *usb;
170 usb = (USB_DEVICE_PATH *)devpath;
171 return snprintf(buf, size, "usb(0x%02x,0x%02x)",
172 usb->ParentPortNumber, usb->InterfaceNumber);
175 SCSI_DEVICE_PATH *scsi;
177 scsi = (SCSI_DEVICE_PATH *)(void *)devpath;
178 return snprintf(buf, size, "scsi(0x%02x,0x%02x)",
179 scsi->Pun, scsi->Lun);
182 SATA_DEVICE_PATH *sata;
184 sata = (SATA_DEVICE_PATH *)(void *)devpath;
185 return snprintf(buf, size, "sata(0x%x,0x%x,0x%x)",
186 sata->HBAPortNumber, sata->PortMultiplierPortNumber,
190 return snprintf(buf, size, "msg(0x%02x)",
194 case HARDWARE_DEVICE_PATH:
195 switch (devpath->SubType) {
197 PCI_DEVICE_PATH *pci;
199 pci = (PCI_DEVICE_PATH *)devpath;
200 return snprintf(buf, size, "pci(0x%02x,0x%02x)",
201 pci->Device, pci->Function);
204 return snprintf(buf, size, "hw(0x%02x)",
208 case ACPI_DEVICE_PATH: {
209 ACPI_HID_DEVICE_PATH *acpi;
211 acpi = (ACPI_HID_DEVICE_PATH *)(void *)devpath;
212 if ((acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
213 switch (EISA_ID_TO_NUM(acpi->HID)) {
215 return snprintf(buf, size, "pciroot(0x%x)",
218 return snprintf(buf, size, "pcieroot(0x%x)",
221 return snprintf(buf, size, "floppy(0x%x)",
224 return snprintf(buf, size, "keyboard(0x%x)",
227 return snprintf(buf, size, "serial(0x%x)",
230 return snprintf(buf, size, "parallelport(0x%x)",
233 return snprintf(buf, size, "acpi(pnp%04x,0x%x)",
234 EISA_ID_TO_NUM(acpi->HID), acpi->UID);
238 return snprintf(buf, size, "acpi(0x%08x,0x%x)", acpi->HID,
241 case MEDIA_DEVICE_PATH:
242 switch (devpath->SubType) {
243 case MEDIA_CDROM_DP: {
244 CDROM_DEVICE_PATH *cdrom;
246 cdrom = (CDROM_DEVICE_PATH *)(void *)devpath;
247 return snprintf(buf, size, "cdrom(%x)",
250 case MEDIA_HARDDRIVE_DP: {
251 HARDDRIVE_DEVICE_PATH *hd;
253 hd = (HARDDRIVE_DEVICE_PATH *)(void *)devpath;
254 return snprintf(buf, size, "hd(%x)",
255 hd->PartitionNumber);
258 return snprintf(buf, size, "media(0x%02x)",
261 case BBS_DEVICE_PATH:
262 return snprintf(buf, size, "bbs(0x%02x)", devpath->SubType);
263 case END_DEVICE_PATH_TYPE:
267 return snprintf(buf, size, "type(0x%02x, 0x%02x)", devpath->Type,
272 * devpath_strlcat appends a text description of devpath to buf but not more
273 * than size - 1 characters followed by NUL-terminator.
276 devpath_strlcat(char *buf, size_t size, EFI_DEVICE_PATH *devpath)
283 while (!IsDevicePathEnd(devpath)) {
284 len = snprintf(buf, size - used, "%s", sep);
290 len = devpath_node_str(buf, size - used, devpath);
295 devpath = NextDevicePathNode(devpath);
303 * devpath_str is convenience method which returns the text description of
304 * devpath using a static buffer, so it isn't thread safe!
307 devpath_str(EFI_DEVICE_PATH *devpath)
309 static char buf[256];
311 devpath_strlcat(buf, sizeof(buf), devpath);
317 * load_loader attempts to load the loader image data.
319 * It tries each module and its respective devices, identified by mod->probe,
320 * in order until a successful load occurs at which point it returns EFI_SUCCESS
321 * and EFI_NOT_FOUND otherwise.
323 * Only devices which have preferred matching the preferred parameter are tried.
326 load_loader(const boot_module_t **modp, dev_info_t **devinfop, void **bufp,
327 size_t *bufsize, BOOLEAN preferred)
331 const boot_module_t *mod;
333 for (i = 0; i < NUM_BOOT_MODULES; i++) {
334 if (boot_modules[i] == NULL)
336 mod = boot_modules[i];
337 for (dev = mod->devices(); dev != NULL; dev = dev->next) {
338 if (dev->preferred != preferred)
341 if (mod->load(PATH_LOADER_EFI, dev, bufp, bufsize) ==
345 return (EFI_SUCCESS);
350 return (EFI_NOT_FOUND);
354 * try_boot only returns if it fails to load the loader. If it succeeds
355 * it simply boots, otherwise it returns the status of last EFI call.
360 size_t bufsize, loadersize, cmdsize;
361 void *buf, *loaderbuf;
364 const boot_module_t *mod;
365 EFI_HANDLE loaderhandle;
366 EFI_LOADED_IMAGE *loaded_image;
369 status = load_loader(&mod, &dev, &loaderbuf, &loadersize, TRUE);
370 if (status != EFI_SUCCESS) {
371 status = load_loader(&mod, &dev, &loaderbuf, &loadersize,
373 if (status != EFI_SUCCESS) {
374 printf("Failed to load '%s'\n", PATH_LOADER_EFI);
380 * Read in and parse the command line from /boot.config or /boot/config,
381 * if present. We'll pass it the next stage via a simple ASCII
382 * string. loader.efi has a hack for ASCII strings, so we'll use that to
383 * keep the size down here. We only try to read the alternate file if
384 * we get EFI_NOT_FOUND because all other errors mean that the boot_module
385 * had troubles with the filesystem. We could return early, but we'll let
386 * loading the actual kernel sort all that out. Since these files are
387 * optional, we don't report errors in trying to read them.
391 status = mod->load(PATH_DOTCONFIG, dev, &buf, &bufsize);
392 if (status == EFI_NOT_FOUND)
393 status = mod->load(PATH_CONFIG, dev, &buf, &bufsize);
394 if (status == EFI_SUCCESS) {
395 cmdsize = bufsize + 1;
396 cmd = malloc(cmdsize);
399 memcpy(cmd, buf, bufsize);
405 if ((status = bs->LoadImage(TRUE, image, devpath_last(dev->devpath),
406 loaderbuf, loadersize, &loaderhandle)) != EFI_SUCCESS) {
407 printf("Failed to load image provided by %s, size: %zu, (%lu)\n",
408 mod->name, loadersize, EFI_ERROR_CODE(status));
412 if ((status = bs->HandleProtocol(loaderhandle, &LoadedImageGUID,
413 (VOID**)&loaded_image)) != EFI_SUCCESS) {
414 printf("Failed to query LoadedImage provided by %s (%lu)\n",
415 mod->name, EFI_ERROR_CODE(status));
420 printf(" command args: %s\n", cmd);
422 loaded_image->DeviceHandle = dev->devhandle;
423 loaded_image->LoadOptionsSize = cmdsize;
424 loaded_image->LoadOptions = cmd;
426 DPRINTF("Starting '%s' in 5 seconds...", PATH_LOADER_EFI);
438 if ((status = bs->StartImage(loaderhandle, NULL, NULL)) !=
440 printf("Failed to start image provided by %s (%lu)\n",
441 mod->name, EFI_ERROR_CODE(status));
442 loaded_image->LoadOptionsSize = 0;
443 loaded_image->LoadOptions = NULL;
451 if (loaderbuf != NULL)
458 * probe_handle determines if the passed handle represents a logical partition
459 * if it does it uses each module in order to probe it and if successful it
460 * returns EFI_SUCCESS.
463 probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN *preferred)
467 EFI_DEVICE_PATH *devpath;
471 /* Figure out if we're dealing with an actual partition. */
472 status = bs->HandleProtocol(h, &DevicePathGUID, (void **)&devpath);
473 if (status == EFI_UNSUPPORTED)
476 if (status != EFI_SUCCESS) {
477 DPRINTF("\nFailed to query DevicePath (%lu)\n",
478 EFI_ERROR_CODE(status));
482 DPRINTF("probing: %s\n", devpath_str(devpath));
484 status = bs->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio);
485 if (status == EFI_UNSUPPORTED)
488 if (status != EFI_SUCCESS) {
489 DPRINTF("\nFailed to query BlockIoProtocol (%lu)\n",
490 EFI_ERROR_CODE(status));
494 if (!blkio->Media->LogicalPartition)
495 return (EFI_UNSUPPORTED);
497 *preferred = device_paths_match(imgpath, devpath);
499 /* Run through each module, see if it can load this partition */
500 for (i = 0; i < NUM_BOOT_MODULES; i++) {
501 if (boot_modules[i] == NULL)
504 if ((status = bs->AllocatePool(EfiLoaderData,
505 sizeof(*devinfo), (void **)&devinfo)) !=
507 DPRINTF("\nFailed to allocate devinfo (%lu)\n",
508 EFI_ERROR_CODE(status));
511 devinfo->dev = blkio;
512 devinfo->devpath = devpath;
513 devinfo->devhandle = h;
514 devinfo->devdata = NULL;
515 devinfo->preferred = *preferred;
516 devinfo->next = NULL;
518 status = boot_modules[i]->probe(devinfo);
519 if (status == EFI_SUCCESS)
520 return (EFI_SUCCESS);
521 (void)bs->FreePool(devinfo);
524 return (EFI_UNSUPPORTED);
528 * probe_handle_status calls probe_handle and outputs the returned status
532 probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath)
537 status = probe_handle(h, imgpath, &preferred);
541 case EFI_UNSUPPORTED:
543 DPRINTF(" not supported\n");
548 DPRINTF(" supported (preferred)\n");
551 DPRINTF(" supported\n");
556 DPRINTF(" error (%lu)\n", EFI_ERROR_CODE(status));
563 efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
566 EFI_LOADED_IMAGE *img;
567 EFI_DEVICE_PATH *imgpath;
569 EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
570 SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
571 UINTN i, max_dim, best_mode, cols, rows, hsize, nhandles;
573 /* Basic initialization*/
576 bs = Xsystab->BootServices;
578 /* Set up the console, so printf works. */
579 status = bs->LocateProtocol(&ConsoleControlGUID, NULL,
580 (VOID **)&ConsoleControl);
581 if (status == EFI_SUCCESS)
582 (void)ConsoleControl->SetMode(ConsoleControl,
583 EfiConsoleControlScreenText);
585 * Reset the console and find the best text mode.
587 conout = systab->ConOut;
588 conout->Reset(conout, TRUE);
589 max_dim = best_mode = 0;
591 status = conout->QueryMode(conout, i, &cols, &rows);
592 if (EFI_ERROR(status))
594 if (cols * rows > max_dim) {
595 max_dim = cols * rows;
600 conout->SetMode(conout, best_mode);
601 conout->EnableCursor(conout, TRUE);
602 conout->ClearScreen(conout);
604 printf("\n>> FreeBSD EFI boot block\n");
605 printf(" Loader path: %s\n\n", PATH_LOADER_EFI);
606 printf(" Initializing modules:");
607 for (i = 0; i < NUM_BOOT_MODULES; i++) {
608 if (boot_modules[i] == NULL)
611 printf(" %s", boot_modules[i]->name);
612 if (boot_modules[i]->init != NULL)
613 boot_modules[i]->init();
617 /* Get all the device handles */
618 hsize = (UINTN)NUM_HANDLES_INIT * sizeof(EFI_HANDLE);
619 if ((status = bs->AllocatePool(EfiLoaderData, hsize, (void **)&handles))
621 panic("Failed to allocate %d handles (%lu)", NUM_HANDLES_INIT,
622 EFI_ERROR_CODE(status));
624 status = bs->LocateHandle(ByProtocol, &BlockIoProtocolGUID, NULL,
629 case EFI_BUFFER_TOO_SMALL:
630 (void)bs->FreePool(handles);
631 if ((status = bs->AllocatePool(EfiLoaderData, hsize,
632 (void **)&handles) != EFI_SUCCESS)) {
633 panic("Failed to allocate %zu handles (%lu)", hsize /
634 sizeof(*handles), EFI_ERROR_CODE(status));
636 status = bs->LocateHandle(ByProtocol, &BlockIoProtocolGUID,
637 NULL, &hsize, handles);
638 if (status != EFI_SUCCESS)
639 panic("Failed to get device handles (%lu)\n",
640 EFI_ERROR_CODE(status));
643 panic("Failed to get device handles (%lu)",
644 EFI_ERROR_CODE(status));
647 /* Scan all partitions, probing with all modules. */
648 nhandles = hsize / sizeof(*handles);
649 printf(" Probing %zu block devices...", nhandles);
652 /* Determine the devpath of our image so we can prefer it. */
653 status = bs->HandleProtocol(image, &LoadedImageGUID, (VOID**)&img);
655 if (status == EFI_SUCCESS) {
656 status = bs->HandleProtocol(img->DeviceHandle, &DevicePathGUID,
658 if (status != EFI_SUCCESS)
659 DPRINTF("Failed to get image DevicePath (%lu)\n",
660 EFI_ERROR_CODE(status));
661 DPRINTF("boot1 imagepath: %s\n", devpath_str(imgpath));
664 for (i = 0; i < nhandles; i++)
665 probe_handle_status(handles[i], imgpath);
668 /* Status summary. */
669 for (i = 0; i < NUM_BOOT_MODULES; i++) {
670 if (boot_modules[i] != NULL) {
672 boot_modules[i]->status();
678 /* If we get here, we're out of luck... */
679 panic("No bootable partitions found!");
683 * add_device adds a device to the passed devinfo list.
686 add_device(dev_info_t **devinfop, dev_info_t *devinfo)
690 if (*devinfop == NULL) {
695 for (dev = *devinfop; dev->next != NULL; dev = dev->next)
702 panic(const char *fmt, ...)
723 systab->ConOut->OutputString(systab->ConOut, buf);
727 systab->ConOut->OutputString(systab->ConOut, buf);