Skip to content
This repository has been archived by the owner on Aug 24, 2022. It is now read-only.

support dedicated data partition #89

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/storage.h
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,6 @@ BOOLEAN is_boot_device_virtual(void);
EFI_STATUS set_logical_unit(UINT64 user_lun, UINT64 factory_lun);
void print_progress(EFI_LBA done, EFI_LBA total, uint32_t sec, uint32_t *prev_sec, uint32_t *prev);
void set_exclude_device(EFI_HANDLE device);
EFI_DEVICE_PATH *get_exclude_device(void);

#endif /* _STORAGE_H_ */
90 changes: 90 additions & 0 deletions libkernelflinger/gpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "gpt.h"
#include "gpt_bin.h"
#include "storage.h"
#include "pci.h"

#define PROTECTIVE_MBR 0xEE

Expand Down Expand Up @@ -437,6 +438,84 @@ static void copy_part(struct gpt_partition *in, struct gpt_partition *out)
sizeof(out->name) - PREFIX_LEN * sizeof(CHAR16));
}

EFI_STATUS get_dedicated_disk(struct gpt_partition_interface *gpart)
{
EFI_STATUS ret;
EFI_HANDLE *handles;
UINTN nb_handle = 0;
PCI_DEVICE_PATH *boot_device;
PCI_DEVICE_PATH *exclude_device;
EFI_DEVICE_PATH *device;
PCI_DEVICE_PATH *pci;
EFI_BLOCK_IO *bio;
UINTN i;
EFI_HANDLE boot_handle = get_boot_device_handle();
EFI_DEVICE_PATH *exclude_device_path = get_exclude_device();

device = DevicePathFromHandle(boot_handle);
if (!device)
return EFI_NOT_FOUND;

boot_device = get_pci_device_path(device);
if (boot_device == NULL)
return EFI_NOT_FOUND;

if(exclude_device_path != NULL) {
exclude_device = get_pci_device_path(exclude_device_path);
if (exclude_device == NULL)
return EFI_NOT_FOUND;
}
else
exclude_device = NULL;

ret = uefi_call_wrapper(BS->LocateHandleBuffer, 5, ByProtocol,
&BlockIoProtocol, NULL, &nb_handle, &handles);
if (EFI_ERROR(ret))
return EFI_NOT_FOUND;

gpart->bio = NULL;
gpart->handle = 0;
memset(&gpart->part, 0, sizeof(gpart->part));
for (i = 0; i < nb_handle; i++) {
device = DevicePathFromHandle(handles[i]);
if (device == NULL)
continue;

pci = get_pci_device_path(device);
if (pci == NULL)
continue;

if (boot_device->Function == pci->Function &&
boot_device->Device == pci->Device)
continue;

if (exclude_device != NULL && exclude_device->Function == pci->Function &&
exclude_device->Device == pci->Device)
continue;

ret = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i], &BlockIoProtocol, (VOID *)&bio);
if (EFI_ERROR(ret))
continue;

ret = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i], &DiskIoProtocol, (VOID *)&gpart->dio);
if (EFI_ERROR(ret))
continue;

gpart->handle = handles[i];
gpart->bio = bio;
gpart->part.starting_lba = 0;
gpart->part.ending_lba = bio->Media->LastBlock;
break;
}
FreePool(handles);

if (gpart->handle == 0)
return EFI_NOT_FOUND;

debug(L"dedicated data parition blocks: 0x%X", gpart->part.ending_lba + 1);
return EFI_SUCCESS;
}

EFI_STATUS gpt_get_partition_by_label(const CHAR16 *label,
struct gpt_partition_interface *gpart,
logical_unit_t log_unit)
Expand All @@ -447,6 +526,17 @@ EFI_STATUS gpt_get_partition_by_label(const CHAR16 *label,
if (!label || !gpart)
return EFI_INVALID_PARAMETER;

/* if dynamic partition enabled, data partition's name is "userdata";
* if dynamic partition disabled, data partition's name is "data"
*/
if (!StrCmp(label, L"userdata") || !StrCmp(label, L"data")) {
ret = get_dedicated_disk(gpart);
if (ret == EFI_SUCCESS) {
CopyMem(gpart->part.name, label, sizeof(gpart->part.name));
return EFI_SUCCESS;
}
}

ret = gpt_cache_partition(log_unit);
if (EFI_ERROR(ret))
return ret;
Expand Down
6 changes: 6 additions & 0 deletions libkernelflinger/storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,3 +621,9 @@ void set_exclude_device(EFI_HANDLE device)
warning(L"Exclude device from installation: %s", dps);
FreePool(dps);
}

EFI_DEVICE_PATH *get_exclude_device(void)
{
return exclude_device;
}