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-17 12:51:09 +12:00
parent 0fd22aa1bd
commit e888217124
10 changed files with 52 additions and 49 deletions
+2 -2
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_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_add_block_devices(struct stage2_args *args, NodeList *devicesList);
extern status_t platform_get_boot_partition(struct stage2_args *args, Node *bootDevice, extern status_t platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
NodeList *partitions, boot::Partition **_partition); NodeList *partitions, NodeList *bootPartitions);
extern status_t platform_register_boot_device(Node *device); extern status_t platform_register_boot_device(Node *device);
/* menu functions */ /* menu functions */
+23 -18
View File
@@ -659,28 +659,33 @@ get_boot_file_system(stage2_args* args, BootVolume& _bootVolume)
if (error != B_OK) if (error != B_OK)
continue; continue;
Partition *partition; NodeList bootPartitions;
error = platform_get_boot_partition(args, device, &gPartitions, &partition); error = platform_get_boot_partitions(args, device, &gPartitions, &bootPartitions);
if (error != B_OK) if (error != B_OK)
continue; continue;
Directory *fileSystem; NodeIterator partitionIterator = bootPartitions.GetIterator();
error = partition->Mount(&fileSystem, true); while (partitionIterator.HasNext()) {
if (error != B_OK) { Partition *partition = (Partition*)partitionIterator.Next();
// this partition doesn't contain any known file system; we
// don't need it anymore Directory *fileSystem;
gPartitions.Remove(partition); error = partition->Mount(&fileSystem, true);
delete partition; if (error != B_OK) {
continue; // 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; return B_ERROR;
@@ -168,8 +168,8 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t status_t
platform_get_boot_partition(struct stage2_args *args, Node *bootDevice, platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
NodeList *list, boot::Partition **_partition) NodeList *list, NodeList *partitions)
{ {
//TODO //TODO
@@ -1189,8 +1189,8 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t status_t
platform_get_boot_partition(struct stage2_args *args, Node *bootDevice, platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
NodeList *list, boot::Partition **_partition) NodeList *list, NodeList *partitionList)
{ {
BlockHandle *drive = static_cast<BlockHandle *>(bootDevice); BlockHandle *drive = static_cast<BlockHandle *>(bootDevice);
off_t offset = (off_t)gBootPartitionOffset * drive->BlockSize(); 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 // offset as reported by the BFS boot block
if (offset >= partition->offset if (offset >= partition->offset
&& offset < partition->offset + partition->size) { && offset < partition->offset + partition->size) {
*_partition = partition; partitionList->Insert(partition);
return B_OK; return B_OK;
} }
} }
@@ -878,8 +878,8 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t status_t
platform_get_boot_partition(struct stage2_args *args, Node *bootDevice, platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
NodeList *list, boot::Partition **_partition) NodeList *list, NodeList *bootList)
{ {
BIOSDrive *drive = static_cast<BIOSDrive *>(bootDevice); BIOSDrive *drive = static_cast<BIOSDrive *>(bootDevice);
off_t offset = (off_t)gBootPartitionOffset * drive->BlockSize(); 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 // offset as reported by the BFS boot block
if (offset >= partition->offset if (offset >= partition->offset
&& offset < partition->offset + partition->size) { && offset < partition->offset + partition->size) {
*_partition = partition; bootList->Insert(partition);
return B_OK; return B_OK;
} }
} }
+3 -3
View File
@@ -34,14 +34,14 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t status_t
platform_get_boot_partition(struct stage2_args *args, Node *device, platform_get_boot_partitions(struct stage2_args *args, Node *device,
NodeList *list, boot::Partition **_partition) NodeList *list, NodeList *partitionList)
{ {
NodeIterator iterator = list->GetIterator(); NodeIterator iterator = list->GetIterator();
boot::Partition *partition = NULL; boot::Partition *partition = NULL;
while ((partition = (boot::Partition *)iterator.Next()) != NULL) { while ((partition = (boot::Partition *)iterator.Next()) != NULL) {
// ToDo: just take the first partition for now // ToDo: just take the first partition for now
*_partition = partition; partitionList->Insert(partition);
return B_OK; return B_OK;
} }
+7 -9
View File
@@ -440,7 +440,7 @@ device_contains_partition(EfiDevice *device, boot::Partition *partition)
} }
if ((partition->offset + partition->size) <= device->Size()) if ((partition->offset + partition->size) <= device->Size())
return true; return true;
return false; return false;
} }
@@ -482,19 +482,17 @@ platform_add_block_devices(struct stage2_args *args, NodeList *devicesList)
status_t status_t
platform_get_boot_partition(struct stage2_args *args, Node *bootDevice, platform_get_boot_partitions(struct stage2_args *args, Node *bootDevice,
NodeList *partitions, boot::Partition **_partition) NodeList *partitions, NodeList *bootPartitions)
{ {
NodeIterator iterator = partitions->GetIterator(); NodeIterator iterator = partitions->GetIterator();
boot::Partition *partition = NULL; boot::Partition *partition = NULL;
while ((partition = (boot::Partition *)iterator.Next()) != NULL) { while ((partition = (boot::Partition*)iterator.Next()) != NULL) {
if (device_contains_partition((EfiDevice*)bootDevice, partition)) { if (device_contains_partition((EfiDevice*)bootDevice, partition))
*_partition = partition; bootPartitions->Insert(partition);
return B_OK;
}
} }
return B_ENTRY_NOT_FOUND; return bootPartitions->Count() > 0 ? B_OK : B_ENTRY_NOT_FOUND;
} }
@@ -125,14 +125,14 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t status_t
platform_get_boot_partition(struct stage2_args *args, Node *device, platform_get_boot_partitions(struct stage2_args *args, Node *device,
NodeList *list, boot::Partition **_partition) NodeList *list, NodeList *partitionList)
{ {
NodeIterator iterator = list->GetIterator(); NodeIterator iterator = list->GetIterator();
boot::Partition *partition = NULL; boot::Partition *partition = NULL;
while ((partition = (boot::Partition *)iterator.Next()) != NULL) { while ((partition = (boot::Partition *)iterator.Next()) != NULL) {
// ToDo: just take the first partition for now // ToDo: just take the first partition for now
*_partition = partition; partitionList->Insert(partition);
return B_OK; return B_OK;
} }
@@ -117,15 +117,15 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t status_t
platform_get_boot_partition(struct stage2_args *args, Node *device, platform_get_boot_partitions(struct stage2_args *args, Node *device,
NodeList *list, boot::Partition **_partition) NodeList *list, NodeList *partitionList)
{ {
TRACE("platform_get_boot_partition\n"); TRACE("platform_get_boot_partition\n");
NodeIterator iterator = list->GetIterator(); NodeIterator iterator = list->GetIterator();
boot::Partition *partition = NULL; boot::Partition *partition = NULL;
while ((partition = (boot::Partition *)iterator.Next()) != NULL) { while ((partition = (boot::Partition *)iterator.Next()) != NULL) {
// ToDo: just take the first partition for now // ToDo: just take the first partition for now
*_partition = partition; partitionList->Insert(partition);
return B_OK; return B_OK;
} }
+3 -3
View File
@@ -47,8 +47,8 @@ platform_add_boot_device(struct stage2_args *args, NodeList *devicesList)
status_t status_t
platform_get_boot_partition(struct stage2_args *args, Node *device, platform_get_boot_partitions(struct stage2_args *args, Node *device,
NodeList *list, boot::Partition **_partition) NodeList *list, NodeList *partitionList)
{ {
TRACE("platform_get_boot_partition\n"); TRACE("platform_get_boot_partition\n");
@@ -56,7 +56,7 @@ platform_get_boot_partition(struct stage2_args *args, Node *device,
boot::Partition *partition = NULL; boot::Partition *partition = NULL;
while ((partition = (boot::Partition *)iterator.Next()) != NULL) { while ((partition = (boot::Partition *)iterator.Next()) != NULL) {
// ToDo: just take the first partition for now // ToDo: just take the first partition for now
*_partition = partition; partitionList->Insert(partition);
return B_OK; return B_OK;
} }