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:
@@ -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 */
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user