Skip to content

Commit 7c4b7ca

Browse files
lib/bli: implement entry control
Implement oneshot & default entry control
1 parent e0f78b9 commit 7c4b7ca

File tree

3 files changed

+106
-17
lines changed

3 files changed

+106
-17
lines changed

common/lib/bli.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ void init_bli(void) {
9191

9292
uint64_t features = (1 << 0) | // Timeout control
9393
(1 << 1) | // Oneshot timeout control
94+
(1 << 2) | // Default entry control
95+
(1 << 3) | // Oneshot entry control
9496
(1 << 13); // menu-disabled support
9597
gRT->SetVariable(L"LoaderFeatures",
9698
&bli_vendor_guid,
@@ -160,4 +162,51 @@ bool bli_update_timeout(size_t *timeout, bool *skip_timeout) {
160162
return handle_timeout(L"LoaderConfigTimeout", false, timeout, skip_timeout);
161163
}
162164

165+
static bool handle_entry(wchar_t *variable, bool erase, char *path, size_t buf_size) {
166+
wchar_t wide_path[256];
167+
UINTN getvar_size = sizeof(wide_path) - 2;
168+
uint32_t attrs;
169+
if (gRT->GetVariable(variable,
170+
&bli_vendor_guid,
171+
&attrs,
172+
&getvar_size,
173+
wide_path) == 0 && getvar_size > 0) {
174+
if (erase) {
175+
gRT->SetVariable(variable, &bli_vendor_guid,
176+
attrs,
177+
0, NULL);
178+
}
179+
180+
size_t i;
181+
for (i = 0; i < buf_size-1 && i * 2 < getvar_size; i++) {
182+
path[i] = wide_path[i] & 0xff; // Assume 0x00 - 0x7f
183+
}
184+
path[i] = 0;
185+
186+
return true;
187+
}
188+
return false;
189+
}
190+
191+
bool bli_get_default_entry(char *path, size_t buf_size) {
192+
return handle_entry(L"LoaderEntryDefault", false, path, buf_size);
193+
}
194+
195+
bool bli_get_oneshot_entry(char *path, size_t buf_size) {
196+
return handle_entry(L"LoaderEntryOneShot", true, path, buf_size);
197+
}
198+
199+
void bli_set_selected_entry(const char *path) {
200+
wchar_t wide_path[256];
201+
size_t pos = 0;
202+
for (; pos < 256 && pos < strlen(path); pos++) {
203+
wide_path[pos] = path[pos];
204+
}
205+
gRT->SetVariable(L"LoaderEntrySelected",
206+
&bli_vendor_guid,
207+
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
208+
strlen(path)*2 + 1,
209+
wide_path);
210+
}
211+
163212
#endif

common/lib/bli.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ void init_bli(void);
77
void bli_on_boot(void);
88
bool bli_update_oneshot_timeout(size_t *timeout, bool *skip_timeout);
99
bool bli_update_timeout(size_t *timeout, bool *skip_timeout);
10+
void bli_set_selected_entry(const char *path);
11+
bool bli_get_default_entry(char *path, size_t buf_size);
12+
bool bli_get_oneshot_entry(char *path, size_t buf_size);
1013

1114
#endif
1215

common/menu.c

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -990,31 +990,67 @@ noreturn void _menu(bool first_run) {
990990

991991
size_t selected_entry = 0;
992992

993-
char *default_entry = config_get_value(NULL, 0, "DEFAULT_ENTRY");
994-
if (default_entry != NULL) {
995-
selected_entry = strtoui(default_entry, NULL, 10);
996-
if (selected_entry)
997-
selected_entry--;
993+
bool has_entry = false;
994+
995+
#if defined (UEFI)
996+
{
997+
char path[256];
998+
if (bli_get_oneshot_entry(path, 256)) {
999+
// Find the entry with this path, expand directories, and get its index.
1000+
struct menu_entry *found_entry = NULL;
1001+
size_t found_index = 0;
1002+
find_entry_by_path(path, menu_tree, 0, &found_entry, &found_index, true);
1003+
if (found_entry != NULL) {
1004+
selected_entry = found_index;
1005+
has_entry = true;
1006+
}
1007+
}
1008+
}
1009+
#endif
1010+
1011+
if (!has_entry) {
1012+
char *default_entry = config_get_value(NULL, 0, "DEFAULT_ENTRY");
1013+
if (default_entry != NULL) {
1014+
selected_entry = strtoui(default_entry, NULL, 10);
1015+
if (selected_entry)
1016+
selected_entry--;
1017+
}
9981018
}
9991019

10001020
#if defined (UEFI)
1001-
char *remember_last = config_get_value(NULL, 0, "REMEMBER_LAST_ENTRY");
1002-
if (remember_last != NULL && strcasecmp(remember_last, "yes") == 0) {
1003-
char last_entry_path[256];
1004-
UINTN getvar_size = sizeof(last_entry_path);
1005-
if (gRT->GetVariable(L"LimineLastBootedEntry",
1006-
&limine_efi_vendor_guid,
1007-
NULL,
1008-
&getvar_size,
1009-
last_entry_path) == 0 && getvar_size > 0) {
1010-
// Ensure NUL termination
1011-
last_entry_path[getvar_size < sizeof(last_entry_path) ? getvar_size : sizeof(last_entry_path) - 1] = '\0';
1021+
if (!has_entry) {
1022+
char *remember_last = config_get_value(NULL, 0, "REMEMBER_LAST_ENTRY");
1023+
if (remember_last != NULL && strcasecmp(remember_last, "yes") == 0) {
1024+
char last_entry_path[256];
1025+
UINTN getvar_size = sizeof(last_entry_path);
1026+
if (gRT->GetVariable(L"LimineLastBootedEntry",
1027+
&limine_efi_vendor_guid,
1028+
NULL,
1029+
&getvar_size,
1030+
last_entry_path) == 0 && getvar_size > 0) {
1031+
// Ensure NUL termination
1032+
last_entry_path[getvar_size < sizeof(last_entry_path) ? getvar_size : sizeof(last_entry_path) - 1] = '\0';
1033+
// Find the entry with this path, expand directories, and get its index.
1034+
struct menu_entry *found_entry = NULL;
1035+
size_t found_index = 0;
1036+
find_entry_by_path(last_entry_path, menu_tree, 0, &found_entry, &found_index, true);
1037+
if (found_entry != NULL) {
1038+
selected_entry = found_index;
1039+
has_entry = true;
1040+
}
1041+
}
1042+
}
1043+
}
1044+
if (!has_entry) {
1045+
char path[256];
1046+
if (bli_get_default_entry(path, 256)) {
10121047
// Find the entry with this path, expand directories, and get its index.
10131048
struct menu_entry *found_entry = NULL;
10141049
size_t found_index = 0;
1015-
find_entry_by_path(last_entry_path, menu_tree, 0, &found_entry, &found_index, true);
1050+
find_entry_by_path(path, menu_tree, 0, &found_entry, &found_index, true);
10161051
if (found_entry != NULL) {
10171052
selected_entry = found_index;
1053+
has_entry = true;
10181054
}
10191055
}
10201056
}
@@ -1309,6 +1345,7 @@ noreturn void _menu(bool first_run) {
13091345
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
13101346
strlen(entry_path) + 1,
13111347
entry_path);
1348+
bli_set_selected_entry(entry_path);
13121349
#endif
13131350

13141351
boot(selected_menu_entry->body);

0 commit comments

Comments
 (0)