You are not logged in.
Hi ,
I'm trying to run Arch Linux from an external SSD on my latptop with secure boot enabled. I'm able to boot into the arch system just fine from the bootmenu but I want to directly boot into the arch system once the external ssd is plugged in without me having to interrupt the boot. Changing the boot order in the bios helps , but things go back to default once I remove the external ssd and boot into my windows main. If I create a UEFI boot entry manually (using efibootmgr), and give it priority over windows (0004) ; the same thing happens. It works till I boot into windows and the boot entry is simply wiped.
Is there any way to make the firmware keep a persistent UEFI boot entry for an external SSD, or is this simply a firmware limitation?
I also came across suggestions to rely on the removable media fallback path (EFI/BOOT/BOOTX64.EFI) instead of a Boot#### entry. Since I'm already using shim at EFI/BOOT/BOOTX64.EFI, I'm curious whether there's another approach I'm missing.
Any ideas or similar experiences would be appreciated.
Setup:
Lenovo
Arch Linux installed on an external USB SSD
Secure Boot enabled
Using shim
Boot chain:
EFI/BOOT/BOOTX64.EFI (shim)
EFI/BOOT/grubx64.efi
EFI/Linux/arch-linux.efi (signed UKI)
EFI partition layout:
/EFI/BOOT/BOOTX64.EFI
/EFI/BOOT/grubx64.efi
/EFI/Linux/arch-linux.efi
Offline
You can install grub on internal SSD (same partition on which windows bootloader is installed) and give it priority over windows bootloader. That way your bootloader is always present, so automatic priority change shall not happen.
Arch is home!
https://github.com/Docbroke
Offline
You should try as following
– delete internal esp flag (reset it after finishing)
– install on external device, partitioning as disired, includung an new ESP on the ext. device
– set 'BootOrder' to
* Windows first but set inactiv
* USB
* ...
Some firmware behaves strang specially concerning Windows first
If you ask the right question, you might get the right answer
Offline
Is there any way to make the firmware keep a persistent UEFI boot entry for an external SSD, or is this simply a firmware limitation?
I also came across suggestions to rely on the removable media fallback path (EFI/BOOT/BOOTX64.EFI) instead of a Boot#### entry. Since I'm already using shim at EFI/BOOT/BOOTX64.EFI, I'm curious whether there's another approach I'm missing.
It's unfortunately normal, if the bios likes to clean up missing entries, that's that. It's the same story on my Gigabyte mainboard.
You'd have to put it on an internal partition. Or use the removable entry. Or make sure to keep the USB plugged whenever you turn on the device so it's never "missing" ;-) Or find another way to reinstate the missing entries, like a tiny recovery-kernel+initrd that does just that.
Offline
check whether your bios has an option like "removable/external/usb hdd" and if that sticks when set high than windows
some implementations lower the priority back down when no removable media is detected during post - in that case you can't do anything
Offline
You can install grub on internal SSD (same partition on which windows bootloader is installed) and give it priority over windows bootloader. That way your bootloader is always present, so automatic priority change shall not happen.
I want to treat this as a last resort. I personally try to avoid dual booting. Also considering I'm using a shim, idk how the system would behave with the secure boot on.
Offline
You should try as following
– delete internal esp flag (reset it after finishing)
– install on external device, partitioning as disired, includung an new ESP on the ext. device
– set 'BootOrder' to
* Windows first but set inactiv
* USB
* ...
Some firmware behaves strang specially concerning Windows first
I don't understand how do I reset the esp flag. I already have bootable arch installed in the external usb and it does have esp set for the boot partition.
Last edited by baezan (Today 06:42:57)
Offline
baezan wrote:Is there any way to make the firmware keep a persistent UEFI boot entry for an external SSD, or is this simply a firmware limitation?
I also came across suggestions to rely on the removable media fallback path (EFI/BOOT/BOOTX64.EFI) instead of a Boot#### entry. Since I'm already using shim at EFI/BOOT/BOOTX64.EFI, I'm curious whether there's another approach I'm missing.
It's unfortunately normal, if the bios likes to clean up missing entries, that's that. It's the same story on my Gigabyte mainboard.
You'd have to put it on an internal partition. Or use the removable entry. Or make sure to keep the USB plugged whenever you turn on the device so it's never "missing" ;-) Or find another way to reinstate the missing entries, like a tiny recovery-kernel+initrd that does just that.
I don't think putting anything on the external ssd will help. If the firmware decided not to boot from it, nothing on that SSD will ever get executed. I think I will put a windows script that will get executed when I turn off /power on the system to recreate the missing boot entries and then prioritize it over windows.
Last edited by baezan (Today 06:44:19)
Offline
check whether your bios has an option like "removable/external/usb hdd" and if that sticks when set high than windows
some implementations lower the priority back down when no removable media is detected during post - in that case you can't do anything
I'm afraid it's the latter. My old hp laptop used to remember the boot order but this one unfortunately falls back once it encounters no external bootable drive.
Offline
Hi,
I don't understand how do I reset the esp flag
can be done either with 'gdisk' or e.g. 'gparted' -> EFI_system_partition chapt. 2.1
I already have arch installed in the external usb.
Look whether an ESP exists on ext. device.
Here’s how to analyse boot behaviour in EFI mode:
sudo parted -l# shows which device is the ESP
lsblk -o name,partuuid,uuid# displays the corresponding PartUUID, as well as the UUIDs of the ESP and ‘/’
sudo efibootmgr -v # shows which boot entry accesses which ESP (the long sequence of numbers)
“'BootOrder”' shows the order
sudo mount /dev/<ESP> /mnt && sudo ls -R /mnt && sudo umount /mnt# displays the contents of the ESP (and for arch, a …/efi/arch/grub.cfg (as I don’t have an EFI installation of Arch, I don’t know the exact name of the directory)
sudo mount /dev/<ESP> /mnt && sudo cat /mnt/efi/debian/grub.cfg && sudo umount /mnt # displays the contents of grub.cfg with the UUID for the corresponding “/” and thus the location of the grub.cfg file that is displayed as a menu during boot.
Furthermore, there must be an entry with the correct ESP in the relevant /etc/fstab file
# /boot/efi was on /dev/<device> during installation
UUID=<uuid> /boot/efi vfat umask=0077 0 1Archrixi
If you ask the right question, you might get the right answer
Offline
My old hp laptop used to remember the boot order but this one unfortunately falls back once it encounters no external bootable drive.
that's most unfortunate as due to this your original plan to have arch auto boot when its drive is connected is not possible by just have grub installed with --removable flag and have "external hdd" set higher priority than windows
i only see the option to have any linux capable bootloader installed on the internal drive and have it scripted to check for the arch drive and if present to boot arch - i'm not sure if grub can be configured that way
Offline
I don't know if this will help anyone, but I used an exe file, that will change the bootorder in windows :
```
#include <windows.h>
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cstring>
#pragma comment(lib, "Advapi32.lib")
#define EFI_VARIABLE_NON_VOLATILE 0x00000001
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
const wchar_t* EFI_GLOBAL_VARIABLE =
L"{8BE4DF61-93CA-11D2-AA0D-00E098032B8C}";
// Enable firmware variable privilege
bool EnablePrivilege(LPCWSTR privilege)
{
HANDLE token = nullptr;
if (!OpenProcessToken(
GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
&token))
{
return false;
}
LUID luid;
if (!LookupPrivilegeValueW(
nullptr,
privilege,
&luid))
{
CloseHandle(token);
return false;
}
TOKEN_PRIVILEGES tp{};
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
SetLastError(ERROR_SUCCESS);
if (!AdjustTokenPrivileges(
token,
FALSE,
&tp,
sizeof(tp),
nullptr,
nullptr))
{
CloseHandle(token);
return false;
}
DWORD error = GetLastError();
CloseHandle(token);
return error != ERROR_NOT_ALL_ASSIGNED;
}
// Read UEFI BootOrder
bool ReadBootOrder(std::vector<WORD>& order)
{
BYTE buffer[512];
DWORD size =
GetFirmwareEnvironmentVariableExW(
L"BootOrder",
EFI_GLOBAL_VARIABLE,
buffer,
sizeof(buffer),
nullptr);
if (size == 0)
{
std::cout
<< "Failed reading BootOrder. Error="
<< GetLastError()
<< "\n";
return false;
}
order.clear();
for (DWORD i = 0; i < size; i += sizeof(WORD))
{
WORD entry;
memcpy(
&entry,
buffer + i,
sizeof(WORD));
order.push_back(entry);
}
return true;
}
// Print BootOrder
void PrintBootOrder(const std::vector<WORD>& order)
{
for (WORD entry : order)
{
std::cout
<< "Boot"
<< std::uppercase
<< std::hex
<< std::setw(4)
<< std::setfill('0')
<< entry
<< "\n";
}
std::cout << std::dec;
}
// Write UEFI BootOrder
bool WriteBootOrder(const std::vector<WORD>& order)
{
BYTE buffer[512];
DWORD size = 0;
for (WORD entry : order)
{
memcpy(
buffer + size,
&entry,
sizeof(WORD));
size += sizeof(WORD);
}
BOOL result =
SetFirmwareEnvironmentVariableExW(
L"BootOrder",
EFI_GLOBAL_VARIABLE,
buffer,
size,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS);
if (!result)
{
std::cout
<< "Failed writing BootOrder. Error="
<< GetLastError()
<< "\n";
return false;
}
return true;
}
// Move a boot entry to first position
bool MoveToFront(std::vector<WORD>& order, WORD target)
{
auto it =
std::find(
order.begin(),
order.end(),
target);
if (it == order.end())
{
return false;
}
if (it == order.begin())
{
return false; // already first
}
WORD value = *it;
order.erase(it);
order.insert(
order.begin(),
value);
return true;
}
void WaitBeforeExit()
{
std::cout << "\nPress ENTER to exit...";
std::cin.get();
}
int main()
{
std::cout
<< "ArchBootRepair BootOrder updater\n\n";
if (!EnablePrivilege(SE_SYSTEM_ENVIRONMENT_NAME))
{
std::cout
<< "Could not enable firmware privilege\n";
WaitBeforeExit();
return 1;
}
std::vector<WORD> bootOrder;
if (!ReadBootOrder(bootOrder))
{
WaitBeforeExit();
return 1;
}
std::cout
<< "Current BootOrder:\n";
PrintBootOrder(bootOrder);
// Keep a copy for comparison
std::vector<WORD> originalOrder = bootOrder;
std::cout
<< "\nChecking Boot2001 priority...\n";
bool changed =
MoveToFront(
bootOrder,
0x2001);
if (!changed)
{
std::cout
<< "Boot2001 already first or not found.\n";
if (std::find(
originalOrder.begin(),
originalOrder.end(),
0x2001)
== originalOrder.end())
{
std::cout
<< "Boot2001 does not exist.\n";
}
WaitBeforeExit();
return 0;
}
std::cout
<< "\nNew BootOrder:\n";
PrintBootOrder(bootOrder);
std::cout
<< "\nWriting new BootOrder...\n";
if (!WriteBootOrder(bootOrder))
{
WaitBeforeExit();
return 1;
}
std::cout
<< "BootOrder updated successfully.\n";
std::vector<WORD> verify;
if (ReadBootOrder(verify))
{
std::cout
<< "\nFirmware now reports:\n";
PrintBootOrder(verify);
}
WaitBeforeExit();
return 0;
}```
This basically an equivalent of efibootmgr's updating the boot order. Windows by default, has the most priority (0004) followed by 2001 (USB). I automated to run this at startup. So whenever I boot into windows, the priority is automatically set to 2001 (USB) over 0004 for the next boot. That way if I plug in my external usb next time, it directly boots into Arch for the priority to boot from usb is already set. Remove the function WaitBeforeExit() if you plan to automate this. The downside is that it writes to your NVRAM , so you have to be careful using this.
Last edited by baezan (Today 05:34:54)
Offline
Look whether an ESP exists on ext. device.
Here’s how to analyse boot behaviour in EFI mode:sudo parted -l# shows which device is the ESP
lsblk -o name,partuuid,uuid# displays the corresponding PartUUID, as well as the UUIDs of the ESP and ‘/’
sudo efibootmgr -v# shows which boot entry accesses which ESP (the long sequence of numbers)
“'BootOrder”' shows the ordersudo mount /dev/<ESP> /mnt && sudo ls -R /mnt && sudo umount /mnt# displays the contents of the ESP (and for arch, a …/efi/arch/grub.cfg (as I don’t have an EFI installation of Arch, I don’t know the exact name of the directory)
sudo mount /dev/<ESP> /mnt && sudo cat /mnt/efi/debian/grub.cfg && sudo umount /mnt# displays the contents of grub.cfg with the UUID for the corresponding “/” and thus the location of the grub.cfg file that is displayed as a menu during boot.
Furthermore, there must be an entry with the correct ESP in the relevant /etc/fstab file# /boot/efi was on /dev/<device> during installation UUID=<uuid> /boot/efi vfat umask=0077 0 1Archrixi
Yes my external device does have esp flag. I did not remove the esp from the internal drive, but I'm still curious whether that affects booting into windows or not. The problem for me is that the firmware is prioritizing booting from the internal drive over external. Even if I change the boot preferences here, I'm afraid that once the external device is missing, the firmware will reset the boot order again.
Last edited by baezan (Today 03:07:05)
Offline
Hi,
no need to fullquote.
An NVRAM entry is not required; it is sufficient to ensure that a bootloader is installed on the external device and to set the boot order accordingly (normally™)
You should try as following
...
– set 'BootOrder' to
* Windows first but set inactiv
* USB
* ...
EDIT.:
sudo efibootmgr -b xxxx -Asets "xxxx" to 'inactiv'
...
That way if I plug in my external usb next time, it directly boots into Arch for the priority to boot from usb is already set.
so, it's solved?
Archrix
Last edited by archerixi (Yesterday 11:38:13)
If you ask the right question, you might get the right answer
Offline
You should try as following
...
– set 'BootOrder' to
* Windows first but set inactiv
* USB
* ...
efibootmgr
BootCurrent: 0000
Timeout: 0 seconds
BootOrder: 0004,2001,2002,2003The order is already set to default
Disk /dev/nvme0n1: 1024GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 274MB 273MB fat32 EFI system partition msftdata
2 274MB 290MB 16.8MB Microsoft reserved partition msftres
3 290MB 498GB 498GB Basic data partition msftdata
4 498GB 1022GB 524GB Basic data partition msftdata
5 1022GB 1024GB 2097MB ntfs Basic data partition hidden, diag, no_automountDisk /dev/sda: 256GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 1075MB 1074MB fat32 boot, esp
2 1075MB 256GB 255GB ext4So you see, I did set the esp flag inactive for my internal drive while it's still active on my external ssd. Yet, when I have my ssd pluugged in, it still booted windows.
That way if I plug in my external usb next time, it directly boots into Arch for the priority to boot from usb is already set.
so, it's solved?
The exe script that I run is a workaround, but I wouldn't call that a good solution. It relies on updating the NVRAM whenever I boot windows and whenever the priority was changed to default.
Last edited by baezan (Today 05:28:41)
Offline
so, the tl;dr seems to be: due to specific implementation of the uefi what you want is unfortunate not possible with your specific hardware although it should be by uefi spec
welcome to the wonderful world of what microsoft as monopolist got us with all thier marketing BS
another one: although M$ is one of the big players in the uefi spec commitee - so they, too, debated and decided and agreed upon the specs - they're one of the specs biggest offenders: the uefi spec defines <ESP>\BOOT\BOOT<architecture>.EFI clearly as "path for removable media" (note: the often communicated "fallback" is not true - it is not a fallback - it is specific for removable media!) and doesn't make any assumptions how a spec compliant implementation should handle if it's found on a fixed disk
so the fact that most common uefi implementations even recognize and utilize the removable media path on fixed disk is only a de-facto industry standard but it's not in the specs
more over: when ever windows boots it places a copy of its fwbootmgr.efi (or whatever that file is called these days) at that path - every single time - it doesn't care if there's anything else in place - it just overwrites it without giving a shit about maybe other OS on the system
but: m$ agreed upon specs to not do that - anyone sees what's wrong here?
in addition to that: most OEMs of mobile devices design thier uefi with only windows in mind and test with only windows - which is often reflected by that almost-instant-auto-reply from customer service: "we don't support linux" - so, if you want to run linux on a mobile device either make sure it's designed for linux (or at least with linux in mind) - or don't run dual-boot - rather use two devices instead then
the overall idea isn't that bad - i to have a full arch install on a 32gb thumbdrive - it's slow as hell - but i can boot pretty much any system with a full blown system instead of just some one-shot live environments - but your hardware (or rather its firmware) just doesn't play along - i doubt there's anything else possible then either your workaround - or modifying the uefi
Offline
Hi,
[...]
The order is already set to default
Unfortunately, this statement is of no use; apart from the sequence 0004, 2001..., we know nothing.
(Terminal input and output must always be shown in full, from prompt to prompt)
You need to set it to inactive using
sudo efibootmgr -b 0004 -A # if 0004 is the Windows entry
Btw, what sort of PC is it anyway? ACER PCs are particularly prone to this sort of behaviour, but I’ve also heard of it happening with some Lenovo models (and other).
☛
inxi -MSo you see, I did set the esp flag inactive for my internal drive while it's still active on my external ssd. Yet, when I have my ssd pluugged in, it still booted windows.
Sorry, my mistake – I should have pointed out that this procedure – the ESP flag – should be used when installing to an external storage device. Reason: During Installation the installer usually uses the first ESP it finds in the system, which is typically on the internal hard drive, not on a USB device.
Once the installation is complete, the flag can be set again, though this isn’t strictly necessary as the NVRAM entries use partUUID.
Archerixi
If you ask the right question, you might get the right answer
Offline