aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/efibootmgr
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/efibootmgr')
-rw-r--r--usr.sbin/efibootmgr/efibootmgr.c101
1 files changed, 73 insertions, 28 deletions
diff --git a/usr.sbin/efibootmgr/efibootmgr.c b/usr.sbin/efibootmgr/efibootmgr.c
index 0137fd9fb158..ef8b7f80cc6e 100644
--- a/usr.sbin/efibootmgr/efibootmgr.c
+++ b/usr.sbin/efibootmgr/efibootmgr.c
@@ -67,7 +67,7 @@ __FBSDID("$FreeBSD$");
#endif
#define BAD_LENGTH ((size_t)-1)
-
+
typedef struct _bmgr_opts {
char *env;
char *loader;
@@ -130,7 +130,8 @@ struct entry {
char *name;
char *label;
int idx;
- int part;
+ int flags;
+#define SEEN 1
LIST_ENTRY(entry) entries;
};
@@ -758,6 +759,31 @@ get_descr(uint8_t *data)
}
+static bool
+print_boot_var(const char *name, bool verbose, bool curboot)
+{
+ size_t size;
+ uint32_t load_attrs;
+ uint8_t *data;
+ int ret;
+ char *d;
+
+ ret = efi_get_variable(EFI_GLOBAL_GUID, name, &data, &size, NULL);
+ if (ret < 0)
+ return false;
+ load_attrs = le32dec(data);
+ d = get_descr(data);
+ printf("%c%s%c %s", curboot ? '+' : ' ', name,
+ ((load_attrs & LOAD_OPTION_ACTIVE) ? '*': ' '), d);
+ free(d);
+ if (verbose)
+ print_loadopt_str(data, size);
+ else
+ printf("\n");
+ return true;
+}
+
+
/* Cmd epilogue, or just the default with no args.
* The order is [bootnext] bootcurrent, timeout, order, and the bootvars [-v]
*/
@@ -770,10 +796,10 @@ print_boot_vars(bool verbose)
*/
struct entry *v;
uint8_t *data;
- char *d;
size_t size;
- uint32_t attrs, load_attrs;
- int ret;
+ uint32_t attrs;
+ int ret, bolen;
+ uint16_t *boot_order = NULL, current;
ret = efi_get_variable(EFI_GLOBAL_GUID, "BootNext", &data, &size, &attrs);
if (ret > 0) {
@@ -781,39 +807,58 @@ print_boot_vars(bool verbose)
}
ret = efi_get_variable(EFI_GLOBAL_GUID, "BootCurrent", &data, &size,&attrs);
- printf("BootCurrent: %04x\n", le16dec(data));
+ current = le16dec(data);
+ printf("BootCurrent: %04x\n", current);
ret = efi_get_variable(EFI_GLOBAL_GUID, "Timeout", &data, &size, &attrs);
if (ret > 0) {
- printf("Timeout : %d seconds\n", le16dec(data));
+ printf("Timeout : %d seconds\n", le16dec(data));
}
if (efi_get_variable(EFI_GLOBAL_GUID, "BootOrder", &data, &size, &attrs) > 0) {
if (size % 2 == 1)
warn("Bad BootOrder variable: odd length %d", (int)size);
- printf("BootOrder : ");
- for (size_t i = 0; i < size; i += 2)
- printf("%04x%s", le16dec(data + i), i == size - 2 ? "\n" : ", ");
+ boot_order = malloc(size);
+ bolen = size / 2;
+ printf("BootOrder : ");
+ for (size_t i = 0; i < size; i += 2) {
+ boot_order[i / 2] = le16dec(data + i);
+ printf("%04X%s", boot_order[i / 2], i == size - 2 ? "\n" : ", ");
+ }
}
- /* now we want to fetch 'em all fresh again
- * which possibly includes a newly created bootvar
- */
- LIST_FOREACH(v, &efivars, entries) {
- attrs = 0;
- ret = efi_get_variable(EFI_GLOBAL_GUID, v->name, &data,
- &size, &attrs);
- if (ret < 0)
- continue; /* we must have deleted it */
- load_attrs = le32dec(data);
- d = get_descr(data);
- printf("%s%c %s", v->name,
- ((load_attrs & LOAD_OPTION_ACTIVE) ? '*': ' '), d);
- free(d);
- if (verbose)
- print_loadopt_str(data, size);
- else
- printf("\n");
+ if (boot_order == NULL) {
+ /*
+ * now we want to fetch 'em all fresh again
+ * which possibly includes a newly created bootvar
+ */
+ LIST_FOREACH(v, &efivars, entries) {
+ print_boot_var(v->name, verbose, v->idx == current);
+ }
+ } else {
+ LIST_FOREACH(v, &efivars, entries) {
+ v->flags = 0;
+ }
+ for (int i = 0; i < bolen; i++) {
+ char buffer[10];
+
+ snprintf(buffer, sizeof(buffer), "Boot%04X", boot_order[i]);
+ if (!print_boot_var(buffer, verbose, boot_order[i] == current))
+ printf("%s: MISSING!\n", buffer);
+ LIST_FOREACH(v, &efivars, entries) {
+ if (v->idx == boot_order[i]) {
+ v->flags |= SEEN;
+ break;
+ }
+ }
+ }
+ if (verbose) {
+ printf("\n\nUnreferenced Variables:\n");
+ LIST_FOREACH(v, &efivars, entries) {
+ if (v->flags == 0)
+ print_boot_var(v->name, verbose, v->idx == current);
+ }
+ }
}
return 0;
}