mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-03 09:00:21 +00:00
Refactor currdev setting
Refactor the currdev setting to find the device we booted from. Limit searching when we don't already have a reasonable currdev from that to the same device only. Search a little harder for ZFS volumes as that's needed for loader.efi to live on an ESP. Sponsored by: Netflix Differential Review: https://reviews.freebsd.org/D13784
This commit is contained in:
parent
6986f98fc2
commit
fa9dc8d3ed
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=332416
@ -59,10 +59,13 @@ typedef struct pdinfo
|
||||
uint32_t pd_unit; /* unit number */
|
||||
uint32_t pd_open; /* reference counter */
|
||||
void *pd_bcache; /* buffer cache data */
|
||||
struct pdinfo *pd_parent; /* Linked items (eg partitions) */
|
||||
struct devsw *pd_devsw; /* Back pointer to devsw */
|
||||
} pdinfo_t;
|
||||
|
||||
pdinfo_list_t *efiblk_get_pdinfo_list(struct devsw *dev);
|
||||
pdinfo_t *efiblk_get_pdinfo(struct devdesc *dev);
|
||||
pdinfo_t *efiblk_get_pdinfo_by_handle(EFI_HANDLE h);
|
||||
|
||||
void *efi_get_table(EFI_GUID *tbl);
|
||||
|
||||
|
@ -48,6 +48,7 @@ extern void efi_zfs_probe(void);
|
||||
extern zfsinfo_list_t *efizfs_get_zfsinfo_list(void);
|
||||
extern bool efi_zfs_is_preferred(EFI_HANDLE *h);
|
||||
extern EFI_HANDLE efizfs_get_handle_by_guid(uint64_t);
|
||||
extern bool efizfs_get_guid_by_handle(EFI_HANDLE, uint64_t *);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -119,6 +119,7 @@ efiblk_get_pdinfo_list(struct devsw *dev)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* XXX this gets called way way too often, investigate */
|
||||
pdinfo_t *
|
||||
efiblk_get_pdinfo(struct devdesc *dev)
|
||||
{
|
||||
@ -136,6 +137,40 @@ efiblk_get_pdinfo(struct devdesc *dev)
|
||||
return (pd);
|
||||
}
|
||||
|
||||
static bool
|
||||
same_handle(pdinfo_t *pd, EFI_HANDLE h)
|
||||
{
|
||||
|
||||
return (pd->pd_handle == h || pd->pd_alias == h);
|
||||
}
|
||||
|
||||
pdinfo_t *
|
||||
efiblk_get_pdinfo_by_handle(EFI_HANDLE h)
|
||||
{
|
||||
pdinfo_t *dp, *pp;
|
||||
|
||||
/*
|
||||
* Check hard disks, then cd, then floppy
|
||||
*/
|
||||
STAILQ_FOREACH(dp, &hdinfo, pd_link) {
|
||||
if (same_handle(dp, h))
|
||||
return (dp);
|
||||
STAILQ_FOREACH(pp, &dp->pd_part, pd_link) {
|
||||
if (same_handle(pp, h))
|
||||
return (pp);
|
||||
}
|
||||
}
|
||||
STAILQ_FOREACH(dp, &cdinfo, pd_link) {
|
||||
if (same_handle(dp, h))
|
||||
return (dp);
|
||||
}
|
||||
STAILQ_FOREACH(dp, &fdinfo, pd_link) {
|
||||
if (same_handle(dp, h))
|
||||
return (dp);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
efiblk_pdinfo_count(pdinfo_list_t *pdi)
|
||||
{
|
||||
@ -294,6 +329,8 @@ efipart_fdinfo_add(EFI_HANDLE handle, uint32_t uid, EFI_DEVICE_PATH *devpath)
|
||||
fd->pd_unit = uid;
|
||||
fd->pd_handle = handle;
|
||||
fd->pd_devpath = devpath;
|
||||
fd->pd_parent = NULL;
|
||||
fd->pd_devsw = &efipart_fddev;
|
||||
STAILQ_INSERT_TAIL(&fdinfo, fd, pd_link);
|
||||
return (0);
|
||||
}
|
||||
@ -364,6 +401,8 @@ efipart_cdinfo_add(EFI_HANDLE handle, EFI_HANDLE alias,
|
||||
cd->pd_unit = unit;
|
||||
cd->pd_alias = alias;
|
||||
cd->pd_devpath = devpath;
|
||||
cd->pd_parent = NULL;
|
||||
cd->pd_devsw = &efipart_cddev;
|
||||
STAILQ_INSERT_TAIL(&cdinfo, cd, pd_link);
|
||||
return (0);
|
||||
}
|
||||
@ -489,6 +528,8 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle)
|
||||
pd->pd_handle = part_handle;
|
||||
pd->pd_unit = node->PartitionNumber;
|
||||
pd->pd_devpath = part_devpath;
|
||||
pd->pd_parent = hd;
|
||||
pd->pd_devsw = &efipart_hddev;
|
||||
STAILQ_INSERT_TAIL(&hd->pd_part, pd, pd_link);
|
||||
return (0);
|
||||
}
|
||||
@ -505,6 +546,8 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle)
|
||||
hd->pd_handle = disk_handle;
|
||||
hd->pd_unit = unit;
|
||||
hd->pd_devpath = disk_devpath;
|
||||
hd->pd_parent = NULL;
|
||||
hd->pd_devsw = &efipart_hddev;
|
||||
STAILQ_INSERT_TAIL(&hdinfo, hd, pd_link);
|
||||
|
||||
if (part_devpath == NULL)
|
||||
@ -521,6 +564,8 @@ efipart_hdinfo_add(EFI_HANDLE disk_handle, EFI_HANDLE part_handle)
|
||||
pd->pd_handle = part_handle;
|
||||
pd->pd_unit = node->PartitionNumber;
|
||||
pd->pd_devpath = part_devpath;
|
||||
pd->pd_parent = hd;
|
||||
pd->pd_devsw = &efipart_hddev;
|
||||
STAILQ_INSERT_TAIL(&hd->pd_part, pd, pd_link);
|
||||
|
||||
return (0);
|
||||
@ -579,6 +624,8 @@ efipart_hdinfo_add_filepath(EFI_HANDLE disk_handle)
|
||||
pd->pd_handle = disk_handle;
|
||||
pd->pd_unit = unit;
|
||||
pd->pd_devpath = devpath;
|
||||
pd->pd_parent = NULL;
|
||||
pd->pd_devsw = &efipart_hddev;
|
||||
STAILQ_INSERT_TAIL(&hdinfo, pd, pd_link);
|
||||
free(pathname);
|
||||
return (0);
|
||||
@ -609,6 +656,8 @@ efipart_hdinfo_add_filepath(EFI_HANDLE disk_handle)
|
||||
pd->pd_handle = disk_handle;
|
||||
pd->pd_unit = unit;
|
||||
pd->pd_devpath = devpath;
|
||||
pd->pd_parent = last;
|
||||
pd->pd_devsw = &efipart_hddev;
|
||||
STAILQ_INSERT_TAIL(&last->pd_part, pd, pd_link);
|
||||
free(pathname);
|
||||
return (0);
|
||||
|
@ -64,6 +64,22 @@ efizfs_get_handle_by_guid(uint64_t guid)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
bool
|
||||
efizfs_get_guid_by_handle(EFI_HANDLE handle, uint64_t *guid)
|
||||
{
|
||||
zfsinfo_t *zi;
|
||||
|
||||
if (guid == NULL)
|
||||
return (false);
|
||||
STAILQ_FOREACH(zi, &zfsinfo, zi_link) {
|
||||
if (zi->zi_handle == handle) {
|
||||
*guid = zi->zi_pool_guid;
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
static void
|
||||
insert_zfs(EFI_HANDLE handle, uint64_t guid)
|
||||
{
|
||||
|
@ -78,6 +78,15 @@ EFI_GUID inputid = SIMPLE_TEXT_INPUT_PROTOCOL;
|
||||
|
||||
static EFI_LOADED_IMAGE *img;
|
||||
|
||||
/*
|
||||
* Number of seconds to wait for a keystroke before exiting with failure
|
||||
* in the event no currdev is found. -2 means always break, -1 means
|
||||
* never break, 0 means poll once and then reboot, > 0 means wait for
|
||||
* that many seconds. "fail_timeout" can be set in the environment as
|
||||
* well.
|
||||
*/
|
||||
static int fail_timeout = 5;
|
||||
|
||||
#ifdef EFI_ZFS_BOOT
|
||||
bool
|
||||
efi_zfs_is_preferred(EFI_HANDLE *h)
|
||||
@ -169,113 +178,183 @@ has_keyboard(void)
|
||||
}
|
||||
|
||||
static void
|
||||
set_devdesc_currdev(struct devsw *dev, int unit)
|
||||
set_currdev_devdesc(struct devdesc *currdev)
|
||||
{
|
||||
const char *devname;
|
||||
|
||||
devname = efi_fmtdev(currdev);
|
||||
|
||||
printf("Setting currdev to %s\n", devname);
|
||||
|
||||
env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev, env_nounset);
|
||||
env_setenv("loaddev", EV_VOLATILE, devname, env_noset, env_nounset);
|
||||
}
|
||||
|
||||
static void
|
||||
set_currdev_devsw(struct devsw *dev, int unit)
|
||||
{
|
||||
struct devdesc currdev;
|
||||
char *devname;
|
||||
|
||||
currdev.d_dev = dev;
|
||||
currdev.d_unit = unit;
|
||||
devname = efi_fmtdev(&currdev);
|
||||
|
||||
env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev,
|
||||
env_nounset);
|
||||
env_setenv("loaddev", EV_VOLATILE, devname, env_noset, env_nounset);
|
||||
set_currdev_devdesc(&currdev);
|
||||
}
|
||||
|
||||
static void
|
||||
set_currdev_pdinfo(pdinfo_t *dp)
|
||||
{
|
||||
|
||||
/*
|
||||
* Disks are special: they have partitions. if the parent
|
||||
* pointer is non-null, we're a partition not a full disk
|
||||
* and we need to adjust currdev appropriately.
|
||||
*/
|
||||
if (dp->pd_devsw->dv_type == DEVT_DISK) {
|
||||
struct disk_devdesc currdev;
|
||||
|
||||
currdev.dd.d_dev = dp->pd_devsw;
|
||||
if (dp->pd_parent == NULL) {
|
||||
currdev.dd.d_unit = dp->pd_unit;
|
||||
currdev.d_slice = -1;
|
||||
currdev.d_partition = -1;
|
||||
} else {
|
||||
currdev.dd.d_unit = dp->pd_parent->pd_unit;
|
||||
currdev.d_slice = dp->pd_unit;
|
||||
currdev.d_partition = 255; /* Assumes GPT */
|
||||
}
|
||||
set_currdev_devdesc((struct devdesc *)&currdev);
|
||||
} else {
|
||||
set_currdev_devsw(dp->pd_devsw, dp->pd_unit);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
sanity_check_currdev(void)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
return (stat("/boot/defaults/loader.conf", &st) == 0);
|
||||
}
|
||||
|
||||
#ifdef EFI_ZFS_BOOT
|
||||
static bool
|
||||
probe_zfs_currdev(uint64_t guid)
|
||||
{
|
||||
char *devname;
|
||||
struct zfs_devdesc currdev;
|
||||
|
||||
currdev.dd.d_dev = &zfs_dev;
|
||||
currdev.dd.d_unit = 0;
|
||||
currdev.pool_guid = guid;
|
||||
currdev.root_guid = 0;
|
||||
set_currdev_devdesc((struct devdesc *)&currdev);
|
||||
devname = efi_fmtdev(&currdev);
|
||||
init_zfs_bootenv(devname);
|
||||
|
||||
return (sanity_check_currdev());
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
try_as_currdev(pdinfo_t *hd, pdinfo_t *pp)
|
||||
{
|
||||
uint64_t guid;
|
||||
|
||||
#ifdef EFI_ZFS_BOOT
|
||||
/*
|
||||
* If there's a zpool on this device, try it as a ZFS
|
||||
* filesystem, which has somewhat different setup than all
|
||||
* other types of fs due to imperfect loader integration.
|
||||
* This all stems from ZFS being both a device (zpool) and
|
||||
* a filesystem, plus the boot env feature.
|
||||
*/
|
||||
if (efizfs_get_guid_by_handle(pp->pd_handle, &guid))
|
||||
return (probe_zfs_currdev(guid));
|
||||
#endif
|
||||
/*
|
||||
* All other filesystems just need the pdinfo
|
||||
* initialized in the standard way.
|
||||
*/
|
||||
set_currdev_pdinfo(pp);
|
||||
return (sanity_check_currdev());
|
||||
}
|
||||
|
||||
static int
|
||||
find_currdev(EFI_LOADED_IMAGE *img)
|
||||
{
|
||||
pdinfo_list_t *pdi_list;
|
||||
pdinfo_t *dp, *pp;
|
||||
EFI_DEVICE_PATH *devpath, *copy;
|
||||
EFI_HANDLE h;
|
||||
char *devname;
|
||||
CHAR16 *text;
|
||||
struct devsw *dev;
|
||||
int unit;
|
||||
uint64_t extra;
|
||||
|
||||
#ifdef EFI_ZFS_BOOT
|
||||
/* Did efi_zfs_probe() detect the boot pool? */
|
||||
/*
|
||||
* Did efi_zfs_probe() detect the boot pool? If so, use the zpool
|
||||
* it found, if it's sane. ZFS is the only thing that looks for
|
||||
* disks and pools to boot. This may change in the future, however,
|
||||
* if we allow specifying which pool to boot from via UEFI variables
|
||||
* rather than the bootenv stuff that FreeBSD uses today.
|
||||
*/
|
||||
if (pool_guid != 0) {
|
||||
struct zfs_devdesc currdev;
|
||||
|
||||
currdev.dd.d_dev = &zfs_dev;
|
||||
currdev.dd.d_unit = 0;
|
||||
currdev.pool_guid = pool_guid;
|
||||
currdev.root_guid = 0;
|
||||
devname = efi_fmtdev(&currdev);
|
||||
|
||||
env_setenv("currdev", EV_VOLATILE, devname, efi_setcurrdev,
|
||||
env_nounset);
|
||||
env_setenv("loaddev", EV_VOLATILE, devname, env_noset,
|
||||
env_nounset);
|
||||
init_zfs_bootenv(devname);
|
||||
return (0);
|
||||
printf("Trying ZFS pool\n");
|
||||
if (probe_zfs_currdev(pool_guid))
|
||||
return (0);
|
||||
}
|
||||
#endif /* EFI_ZFS_BOOT */
|
||||
|
||||
/* We have device lists for hd, cd, fd, walk them all. */
|
||||
pdi_list = efiblk_get_pdinfo_list(&efipart_hddev);
|
||||
STAILQ_FOREACH(dp, pdi_list, pd_link) {
|
||||
struct disk_devdesc currdev;
|
||||
|
||||
currdev.dd.d_dev = &efipart_hddev;
|
||||
currdev.dd.d_unit = dp->pd_unit;
|
||||
currdev.d_slice = -1;
|
||||
currdev.d_partition = -1;
|
||||
|
||||
if (dp->pd_handle == img->DeviceHandle) {
|
||||
devname = efi_fmtdev(&currdev);
|
||||
|
||||
env_setenv("currdev", EV_VOLATILE, devname,
|
||||
efi_setcurrdev, env_nounset);
|
||||
env_setenv("loaddev", EV_VOLATILE, devname,
|
||||
env_noset, env_nounset);
|
||||
return (0);
|
||||
/*
|
||||
* Try to find the block device by its handle based on the
|
||||
* image we're booting. If we can't find a sane partition,
|
||||
* search all the other partitions of the disk. We do not
|
||||
* search other disks because it's a violation of the UEFI
|
||||
* boot protocol to do so. We fail and let UEFI go on to
|
||||
* the next candidate.
|
||||
*/
|
||||
dp = efiblk_get_pdinfo_by_handle(img->DeviceHandle);
|
||||
if (dp != NULL) {
|
||||
text = efi_devpath_name(dp->pd_devpath);
|
||||
if (text != NULL) {
|
||||
printf("Trying ESP: %S\n", text);
|
||||
efi_free_devpath_name(text);
|
||||
}
|
||||
/* Assuming GPT partitioning. */
|
||||
STAILQ_FOREACH(pp, &dp->pd_part, pd_link) {
|
||||
if (pp->pd_handle == img->DeviceHandle) {
|
||||
currdev.d_slice = pp->pd_unit;
|
||||
currdev.d_partition = 255;
|
||||
devname = efi_fmtdev(&currdev);
|
||||
|
||||
env_setenv("currdev", EV_VOLATILE, devname,
|
||||
efi_setcurrdev, env_nounset);
|
||||
env_setenv("loaddev", EV_VOLATILE, devname,
|
||||
env_noset, env_nounset);
|
||||
return (0);
|
||||
set_currdev_pdinfo(dp);
|
||||
if (sanity_check_currdev())
|
||||
return (0);
|
||||
if (dp->pd_parent != NULL) {
|
||||
dp = dp->pd_parent;
|
||||
STAILQ_FOREACH(pp, &dp->pd_part, pd_link) {
|
||||
text = efi_devpath_name(pp->pd_devpath);
|
||||
if (text != NULL) {
|
||||
printf("And now the part: %S\n", text);
|
||||
efi_free_devpath_name(text);
|
||||
}
|
||||
/*
|
||||
* Roll up the ZFS special case
|
||||
* for those partitions that have
|
||||
* zpools on them
|
||||
*/
|
||||
if (try_as_currdev(dp, pp))
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pdi_list = efiblk_get_pdinfo_list(&efipart_cddev);
|
||||
STAILQ_FOREACH(dp, pdi_list, pd_link) {
|
||||
if (dp->pd_handle == img->DeviceHandle ||
|
||||
dp->pd_alias == img->DeviceHandle) {
|
||||
set_devdesc_currdev(&efipart_cddev, dp->pd_unit);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
pdi_list = efiblk_get_pdinfo_list(&efipart_fddev);
|
||||
STAILQ_FOREACH(dp, pdi_list, pd_link) {
|
||||
if (dp->pd_handle == img->DeviceHandle) {
|
||||
set_devdesc_currdev(&efipart_fddev, dp->pd_unit);
|
||||
return (0);
|
||||
}
|
||||
} else {
|
||||
printf("Can't find device by handle\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Try the device handle from our loaded image first. If that
|
||||
* fails, use the device path from the loaded image and see if
|
||||
* any of the nodes in that path match one of the enumerated
|
||||
* handles.
|
||||
* handles. Currently, this handle list is only for netboot.
|
||||
*/
|
||||
if (efi_handle_lookup(img->DeviceHandle, &dev, &unit, &extra) == 0) {
|
||||
set_devdesc_currdev(dev, unit);
|
||||
return (0);
|
||||
set_currdev_devsw(dev, unit);
|
||||
if (sanity_check_currdev())
|
||||
return (0);
|
||||
}
|
||||
|
||||
copy = NULL;
|
||||
@ -289,8 +368,9 @@ find_currdev(EFI_LOADED_IMAGE *img)
|
||||
copy = NULL;
|
||||
|
||||
if (efi_handle_lookup(h, &dev, &unit, &extra) == 0) {
|
||||
set_devdesc_currdev(dev, unit);
|
||||
return (0);
|
||||
set_currdev_devsw(dev, unit);
|
||||
if (sanity_check_currdev())
|
||||
return (0);
|
||||
}
|
||||
|
||||
devpath = efi_lookup_devpath(h);
|
||||
@ -304,6 +384,33 @@ find_currdev(EFI_LOADED_IMAGE *img)
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
static bool
|
||||
interactive_interrupt(const char *msg)
|
||||
{
|
||||
time_t now, then, last;
|
||||
|
||||
last = 0;
|
||||
now = then = getsecs();
|
||||
printf("%s\n", msg);
|
||||
if (fail_timeout == -2) /* Always break to OK */
|
||||
return (true);
|
||||
if (fail_timeout == -1) /* Never break to OK */
|
||||
return (false);
|
||||
do {
|
||||
if (last != now) {
|
||||
printf("press any key to interrupt reboot in %d seconds\r",
|
||||
fail_timeout - (int)(now - then));
|
||||
last = now;
|
||||
}
|
||||
|
||||
/* XXX no pause or timeout wait for char */
|
||||
if (ischar())
|
||||
return (true);
|
||||
now = getsecs();
|
||||
} while (now - then < fail_timeout);
|
||||
return (false);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
main(int argc, CHAR16 *argv[])
|
||||
{
|
||||
@ -312,12 +419,13 @@ main(int argc, CHAR16 *argv[])
|
||||
int i, j, vargood, howto;
|
||||
UINTN k;
|
||||
int has_kbd;
|
||||
char *s;
|
||||
EFI_DEVICE_PATH *imgpath;
|
||||
CHAR16 *text;
|
||||
EFI_STATUS status;
|
||||
UINT16 boot_current;
|
||||
size_t sz;
|
||||
UINT16 boot_order[100];
|
||||
EFI_DEVICE_PATH *imgpath;
|
||||
EFI_STATUS status;
|
||||
#if !defined(__arm__)
|
||||
char buf[40];
|
||||
#endif
|
||||
@ -356,12 +464,15 @@ main(int argc, CHAR16 *argv[])
|
||||
/*
|
||||
* Parse the args to set the console settings, etc
|
||||
* boot1.efi passes these in, if it can read /boot.config or /boot/config
|
||||
* or iPXE may be setup to pass these in.
|
||||
* or iPXE may be setup to pass these in. Or the optional argument in the
|
||||
* boot environment was used to pass these arguments in (in which case
|
||||
* neither /boot.config nor /boot/config are consulted).
|
||||
*
|
||||
* Loop through the args, and for each one that contains an '=' that is
|
||||
* not the first character, add it to the environment. This allows
|
||||
* loader and kernel env vars to be passed on the command line. Convert
|
||||
* args from UCS-2 to ASCII (16 to 8 bit) as they are copied.
|
||||
* args from UCS-2 to ASCII (16 to 8 bit) as they are copied (though this
|
||||
* method is flawed for non-ASCII characters).
|
||||
*/
|
||||
howto = 0;
|
||||
for (i = 1; i < argc; i++) {
|
||||
@ -441,6 +552,10 @@ main(int argc, CHAR16 *argv[])
|
||||
for (i = 0; howto_names[i].ev != NULL; i++)
|
||||
if (howto & howto_names[i].mask)
|
||||
setenv(howto_names[i].ev, "YES", 1);
|
||||
|
||||
/*
|
||||
* XXX we need fallback to this stuff after looking at the ConIn, ConOut and ConErr variables
|
||||
*/
|
||||
if (howto & RB_MULTIPLE) {
|
||||
if (howto & RB_SERIAL)
|
||||
setenv("console", "comconsole efi" , 1);
|
||||
@ -448,13 +563,17 @@ main(int argc, CHAR16 *argv[])
|
||||
setenv("console", "efi comconsole" , 1);
|
||||
} else if (howto & RB_SERIAL) {
|
||||
setenv("console", "comconsole" , 1);
|
||||
}
|
||||
} else
|
||||
setenv("console", "efi", 1);
|
||||
|
||||
if (efi_copy_init()) {
|
||||
printf("failed to allocate staging area\n");
|
||||
return (EFI_BUFFER_TOO_SMALL);
|
||||
}
|
||||
|
||||
if ((s = getenv("fail_timeout")) != NULL)
|
||||
fail_timeout = strtol(s, NULL, 10);
|
||||
|
||||
/*
|
||||
* Scan the BLOCK IO MEDIA handles then
|
||||
* march through the device switch probing for things.
|
||||
@ -479,6 +598,7 @@ main(int argc, CHAR16 *argv[])
|
||||
|
||||
printf("\n%s", bootprog_info);
|
||||
|
||||
/* Determine the devpath of our image so we can prefer it. */
|
||||
text = efi_devpath_name(img->FilePath);
|
||||
if (text != NULL) {
|
||||
printf(" Load Path: %S\n", text);
|
||||
@ -520,8 +640,16 @@ main(int argc, CHAR16 *argv[])
|
||||
*/
|
||||
BS->SetWatchdogTimer(0, 0, 0, NULL);
|
||||
|
||||
/*
|
||||
* Try and find a good currdev based on the image that was booted.
|
||||
* It might be desirable here to have a short pause to allow falling
|
||||
* through to the boot loader instead of returning instantly to follow
|
||||
* the boot protocol and also allow an escape hatch for users wishing
|
||||
* to try something different.
|
||||
*/
|
||||
if (find_currdev(img) != 0)
|
||||
return (EFI_NOT_FOUND);
|
||||
if (!interactive_interrupt("Failed to find bootable partition"))
|
||||
return (EFI_NOT_FOUND);
|
||||
|
||||
efi_init_environment();
|
||||
setenv("LINES", "24", 1); /* optional */
|
||||
|
Loading…
Reference in New Issue
Block a user