loader: fetch all potential boot partitions for boot device.

This allows the loader to skip BFS partitions that don't contain
a bootable system. Useful when you have a BFS data partition that
comes before the system partition when iterated over.

Currently, only the UEFI loader actually returns more than one
possible partition.
This commit is contained in:
Jessica Hamilton 2017-05-14 07:50:17 +12:00
parent 0fd22aa1bd
commit e888217124
10 changed files with 52 additions and 49 deletions

View File

@ -58,8 +58,8 @@ namespace boot {
extern status_t platform_add_boot_device(struct stage2_args *args, NodeList *devicesList);
extern status_t platform_add_block_devices(struct stage2_args *args, NodeList *devicesList);
extern status_t platform_get_boot_partition(struct stage2_args *args, Node *bootDevice,
NodeList *partitions, boot::Partition **_partition);
extern status_t platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
NodeList *partitions, NodeList *bootPartitions);
extern status_t platform_register_boot_device(Node *device);
/* menu functions */

View File

@ -659,28 +659,33 @@ get_boot_file_system(stage2_args* args, BootVolume& _bootVolume)
if (error != B_OK)
continue;
Partition *partition;
error = platform_get_boot_partition(args, device, &gPartitions, &partition);
NodeList bootPartitions;
error = platform_get_boot_partitions(args, device, &gPartitions, &bootPartitions);
if (error != B_OK)
continue;
Directory *fileSystem;
error = partition->Mount(&fileSystem, true);
if (error != B_OK) {
// this partition doesn't contain any known file system; we
// don't need it anymore
gPartitions.Remove(partition);
delete partition;
continue;
NodeIterator partitionIterator = bootPartitions.GetIterator();
while (partitionIterator.HasNext()) {
Partition *partition = (Partition*)partitionIterator.Next();
Directory *fileSystem;
error = partition->Mount(&fileSystem, true);
if (error != B_OK) {
// this partition doesn't contain any known file system; we
// don't need it anymore
gPartitions.Remove(partition);
delete partition;
continue;
}
// init the BootVolume
error = _bootVolume.SetTo(fileSystem);
if (error != B_OK)
continue;
sBootDevice = device;
return B_OK;
}
// init the BootVolume
error = _bootVolume.SetTo(fileSystem);
if (error != B_OK)
continue;
sBootDevice = device;
return B_OK;
}
return B_ERROR;

View File

@ -168,8 +168,8 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t
platform_get_boot_partition(struct stage2_args *args, Node *bootDevice,
NodeList *list, boot::Partition **_partition)
platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
NodeList *list, NodeList *partitions)
{
//TODO

View File

@ -1189,8 +1189,8 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t
platform_get_boot_partition(struct stage2_args *args, Node *bootDevice,
NodeList *list, boot::Partition **_partition)
platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
NodeList *list, NodeList *partitionList)
{
BlockHandle *drive = static_cast<BlockHandle *>(bootDevice);
off_t offset = (off_t)gBootPartitionOffset * drive->BlockSize();
@ -1205,7 +1205,7 @@ platform_get_boot_partition(struct stage2_args *args, Node *bootDevice,
// offset as reported by the BFS boot block
if (offset >= partition->offset
&& offset < partition->offset + partition->size) {
*_partition = partition;
partitionList->Insert(partition);
return B_OK;
}
}

View File

@ -878,8 +878,8 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t
platform_get_boot_partition(struct stage2_args *args, Node *bootDevice,
NodeList *list, boot::Partition **_partition)
platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
NodeList *list, NodeList *bootList)
{
BIOSDrive *drive = static_cast<BIOSDrive *>(bootDevice);
off_t offset = (off_t)gBootPartitionOffset * drive->BlockSize();
@ -894,7 +894,7 @@ platform_get_boot_partition(struct stage2_args *args, Node *bootDevice,
// offset as reported by the BFS boot block
if (offset >= partition->offset
&& offset < partition->offset + partition->size) {
*_partition = partition;
bootList->Insert(partition);
return B_OK;
}
}

View File

@ -34,14 +34,14 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t
platform_get_boot_partition(struct stage2_args *args, Node *device,
NodeList *list, boot::Partition **_partition)
platform_get_boot_partitions(struct stage2_args *args, Node *device,
NodeList *list, NodeList *partitionList)
{
NodeIterator iterator = list->GetIterator();
boot::Partition *partition = NULL;
while ((partition = (boot::Partition *)iterator.Next()) != NULL) {
// ToDo: just take the first partition for now
*_partition = partition;
partitionList->Insert(partition);
return B_OK;
}

View File

@ -440,7 +440,7 @@ device_contains_partition(EfiDevice *device, boot::Partition *partition)
}
if ((partition->offset + partition->size) <= device->Size())
return true;
return true;
return false;
}
@ -482,19 +482,17 @@ platform_add_block_devices(struct stage2_args *args, NodeList *devicesList)
status_t
platform_get_boot_partition(struct stage2_args *args, Node *bootDevice,
NodeList *partitions, boot::Partition **_partition)
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)) {
*_partition = partition;
return B_OK;
}
while ((partition = (boot::Partition*)iterator.Next()) != NULL) {
if (device_contains_partition((EfiDevice*)bootDevice, partition))
bootPartitions->Insert(partition);
}
return B_ENTRY_NOT_FOUND;
return bootPartitions->Count() > 0 ? B_OK : B_ENTRY_NOT_FOUND;
}

View File

@ -125,14 +125,14 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t
platform_get_boot_partition(struct stage2_args *args, Node *device,
NodeList *list, boot::Partition **_partition)
platform_get_boot_partitions(struct stage2_args *args, Node *device,
NodeList *list, NodeList *partitionList)
{
NodeIterator iterator = list->GetIterator();
boot::Partition *partition = NULL;
while ((partition = (boot::Partition *)iterator.Next()) != NULL) {
// ToDo: just take the first partition for now
*_partition = partition;
partitionList->Insert(partition);
return B_OK;
}

View File

@ -117,15 +117,15 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t
platform_get_boot_partition(struct stage2_args *args, Node *device,
NodeList *list, boot::Partition **_partition)
platform_get_boot_partitions(struct stage2_args *args, Node *device,
NodeList *list, NodeList *partitionList)
{
TRACE("platform_get_boot_partition\n");
NodeIterator iterator = list->GetIterator();
boot::Partition *partition = NULL;
while ((partition = (boot::Partition *)iterator.Next()) != NULL) {
// ToDo: just take the first partition for now
*_partition = partition;
partitionList->Insert(partition);
return B_OK;
}

View File

@ -47,8 +47,8 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t
platform_get_boot_partition(struct stage2_args *args, Node *device,
NodeList *list, boot::Partition **_partition)
platform_get_boot_partitions(struct stage2_args *args, Node *device,
NodeList *list, NodeList *partitionList)
{
TRACE("platform_get_boot_partition\n");
@ -56,7 +56,7 @@ platform_get_boot_partition(struct stage2_args *args, Node *device,
boot::Partition *partition = NULL;
while ((partition = (boot::Partition *)iterator.Next()) != NULL) {
// ToDo: just take the first partition for now
*_partition = partition;
partitionList->Insert(partition);
return B_OK;
}