Opened 3 years ago

Closed 3 years ago

#17051 closed bug (fixed)

EFI Boot Menu not showing other partitions

Reported by: beaglejoe Owned by:
Priority: normal Milestone: Unscheduled
Component: System/Boot Loader/EFI Version: R1/Development
Keywords: Cc: jessicah
Blocked By: Blocking:
Platform: All

Description

The <SpaceBar> EFI Boot Menu does not show any bootable partitions after the one it selects to boot.

Attachments (4)

Screenshot at 2021-07-05 10-15-49.png (34.3 KB ) - added by beaglejoe 3 years ago.
Screenshot at 2021-07-05 10-18-27.png (142.8 KB ) - added by beaglejoe 3 years ago.
Screenshot at 2021-07-05 11-31-39.png (29.8 KB ) - added by beaglejoe 3 years ago.
t17051.patch (834 bytes ) - added by beaglejoe 3 years ago.

Download all attachments as: .zip

Change History (17)

by beaglejoe, 3 years ago

by beaglejoe, 3 years ago

comment:1 by beaglejoe, 3 years ago

To duplicate:

qemu-system-x86_64 -m 4096 -enable-kvm -machine q35 -smp 3 -net nic -net user \
	-hda disk1.img \
	-hdb disk2.img \
	-cdrom /haiku/haiku/generated.x86_64/haiku-nightly-anyboot.iso \
	-bios /usr/share/qemu/OVMF.fd

Hit <SpaceBar> to bring up the Boot Menu

Partition layout: ( all Haiku partitions have installs)

comment:2 by beaglejoe, 3 years ago

When the user invokes the menu mount_file_systems() (in src/system/boot/loader/vfs.cpp) to mount any remaining partitions.

This function gets short-circuited at this block:

	// add all block devices the platform has for us

	status_t status = platform_add_block_devices(args, &gBootDevices);
	if (status < B_OK)
		return status;

(In src/system/boot/platform/efi/devices.cpp)

status_t
platform_add_block_devices(struct stage2_args *args, NodeList *devicesList)
{
	TRACE("%s: called\n", __func__);

	//TODO: Currently we add all in platform_add_boot_device
	return B_ENTRY_NOT_FOUND;
}

Changing this to return B_OK fixes some of the problem. Presumably affects other architectures.

by beaglejoe, 3 years ago

comment:3 by beaglejoe, 3 years ago

Now, I am only missing Haiku2 partition from the menu. This is because it is on the same drive as the selected partition. In get_boot_file_system() (vfs.cpp) the iteration (and thus the partition mounting) stops when the bootable partition is discovered.


comment:4 by beaglejoe, 3 years ago

I am thinking that the best way to fix this is to add a mounted flag to the partition. Then mount_file_systems() could be simplified to just iterating over gPartitions and mount any without the flag set.

comment:5 by kallisti5, 3 years ago

Cc: jessicah added

Which hrev is this @beaglejoe?

Any opinions here @jessicah?

This behavior is still an improvement over having to re-select the partition on every startup. (though obviously not ideal)

comment:6 by jessicah, 3 years ago

Likely fallout from the too simplistic device scan. I would personally recommend going back to my code, and fix the bugs. These were all the sorts of complex cases that it used to handle.

As for platform_add_block_devices, this should look something like devicesList->Count() > 0 ? B_OK : B_ENTRY_NOT_FOUND, as if there's none, then obviously it's still an error. From what I understand of tqh's code without looking, it adds all disks to the list.

by beaglejoe, 3 years ago

Attachment: t17051.patch added

in reply to:  5 comment:7 by beaglejoe, 3 years ago

Replying to kallisti5:

Which hrev is this @beaglejoe?

hrev55217

in reply to:  6 comment:8 by beaglejoe, 3 years ago

Replying to jessicah:

Likely fallout from the too simplistic device scan. I would personally recommend going back to my code, and fix the bugs. These were all the sorts of complex cases that it used to handle.

As for platform_add_block_devices, this should look something like devicesList->Count() > 0 ? B_OK : B_ENTRY_NOT_FOUND, as if there's none, then obviously it's still an error. From what I understand of tqh's code without looking, it adds all disks to the list.

It seems that currently 'platform_add_boot_device()' does the work of platform_add_block_devices so returning an error from platform_add_block_devices seems a mistake??

Also, in this code:

status_t
platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
		NodeList *partitions, NodeList *bootPartitions)
{
	NodeIterator iterator = partitions->GetIterator();
	boot::Partition *partition = NULL;
	while ((partition = (boot::Partition*)iterator.Next()) != NULL) {
		if (device_contains_partition((EfiDevice*)bootDevice, partition)) {
			iterator.Remove();
			bootPartitions->Insert(partition);
		}
	}

	return bootPartitions->Count() > 0 ? B_OK : B_ENTRY_NOT_FOUND;
}

Why the call to 'iterator.Remove();' ?
If I comment that out (see attached patch). The partitions show up in the menu. (My previous thought about the flag are unneeded)

comment:9 by jessicah, 3 years ago

I just said it should return B_OK if the passed in list is non-empty. If it's empty, then it should return an error, because it has no bootable devices to pass to the generic loader code.

Regarding iterator.Remove(), that may have been dependent on the old scanning behaviour, and may not be required in the new code. What used to happen is that an entry would end up duplicated when using the select a boot volume in the menu.

If you can confirm that removing iterator.Remove() doesn't result in duplicate entries, then it is safe to remove.

This is all why I had marked my patch as WIP on Gerrit, as it does need extensive testing, which I haven't done.

in reply to:  9 comment:11 by beaglejoe, 3 years ago

Replying to jessicah:

I just said it should return B_OK if the passed in list is non-empty. If it's empty, then it should return an error, because it has no bootable devices to pass to the generic loader code.

Thanks, that makes perfect sense.

Regarding iterator.Remove(), that may have been dependent on the old scanning behaviour, and may not be required in the new code. What used to happen is that an entry would end up duplicated when using the select a boot volume in the menu.

I have seen that also.

If you can confirm that removing iterator.Remove() doesn't result in duplicate entries, then it is safe to remove.

This is all why I had marked my patch as WIP on Gerrit, as it does need extensive testing, which I haven't done.

Indeed. Testing the EFI stuff is difficult (and time consuming!). I only have one hardware system to test on. (plus of course qemu).

in reply to:  10 comment:12 by beaglejoe, 3 years ago

Replying to jessicah:

please test https://review.haiku-os.org/c/haiku/+/4160

No duplicate entries and all partitions listed. Tested on Intel NUC (with nvme drive and sata drive) Tested on qemu with two GPT drives. Tested on qemu with one GPT drive and one MBR drive. All bootable partitions were listed. Non-bootable partitions were not listed.

comment:13 by jessicah, 3 years ago

Resolution: fixed
Status: newclosed

Fixed in hrev55221.

Note: See TracTickets for help on using tickets.