summaryrefslogtreecommitdiff
path: root/ArmPlatformPkg/Bds/BootOption.c
diff options
context:
space:
mode:
authoroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2011-08-18 13:21:14 +0000
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>2011-08-18 13:21:14 +0000
commit656416bc2ee1409492343cde3f27ce717e90fdf7 (patch)
tree13b6a4458149cd6a4360afb4515b4a9c299d51e3 /ArmPlatformPkg/Bds/BootOption.c
parent326d1df9193fae2be1cce85be9c361eb6eabe182 (diff)
downloadedk2-platforms-656416bc2ee1409492343cde3f27ce717e90fdf7.tar.xz
ArmPlatformPkg/Bds: Add Linux 'initrd' support to BDS
An 'initrd' file can be specified for a Linux kernel. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12169 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPlatformPkg/Bds/BootOption.c')
-rw-r--r--ArmPlatformPkg/Bds/BootOption.c66
1 files changed, 57 insertions, 9 deletions
diff --git a/ArmPlatformPkg/Bds/BootOption.c b/ArmPlatformPkg/Bds/BootOption.c
index dba0d0f639..f4ff182ef2 100644
--- a/ArmPlatformPkg/Bds/BootOption.c
+++ b/ArmPlatformPkg/Bds/BootOption.c
@@ -35,14 +35,21 @@ BootOptionStart (
Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList);
} else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {
- Status = BdsBootLinux (BootOption->FilePathList, BootOption->OptionalData->Arguments, NULL);
+ Status = BdsBootLinux (BootOption->FilePathList,
+ (EFI_DEVICE_PATH_PROTOCOL*)ReadUnaligned32((UINT32*)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList)),
+ BootOption->OptionalData->Arguments.LinuxAtagArguments.CmdLine,
+ NULL);
} else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {
// Convert the FDT path into a Device Path
Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
ASSERT_EFI_ERROR(Status);
FdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath));
- Status = BdsBootLinux (BootOption->FilePathList, BootOption->OptionalData->Arguments, FdtDevicePath);
+ Status = BdsBootLinux (BootOption->FilePathList,
+ NULL,
+ NULL,
+ FdtDevicePath);
+
FreePool(FdtDevicePath);
}
@@ -184,8 +191,8 @@ BootOptionSetFields (
IN UINT32 Attributes,
IN CHAR16* BootDescription,
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
- IN BDS_LOADER_TYPE BootType,
- IN CHAR8* BootArguments
+ IN BDS_LOADER_TYPE BootType,
+ IN BDS_LOADER_ARGUMENTS* BootArguments
)
{
EFI_LOAD_OPTION EfiLoadOption;
@@ -193,9 +200,12 @@ BootOptionSetFields (
UINTN BootDescriptionSize;
UINTN BootOptionalDataSize;
UINT16 FilePathListLength;
+ UINT16 InitrdPathListLength;
EFI_DEVICE_PATH_PROTOCOL* DevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL* InitrdPathNode;
UINTN NodeLength;
UINT8* EfiLoadOptionPtr;
+ UINT8 *InitrdPathListPtr;
// If we are overwriting an existent Boot Option then we have to free previously allocated memory
if (BootOption->LoadOption) {
@@ -203,8 +213,9 @@ BootOptionSetFields (
}
BootDescriptionSize = StrSize(BootDescription);
- BootOptionalDataSize = sizeof(BDS_LOADER_OPTIONAL_DATA) +
- (BootArguments == NULL ? 0 : AsciiStrSize(BootArguments));
+ BootOptionalDataSize = sizeof(BDS_LOADER_TYPE) + (BootType == BDS_LOADER_KERNEL_LINUX_ATAG ?
+ (sizeof(UINT16) + sizeof(EFI_DEVICE_PATH_PROTOCOL*) + BOOT_DEVICE_OPTION_MAX + 1)
+ : 0);
// Compute the size of the FilePath list
FilePathListLength = 0;
@@ -216,6 +227,18 @@ BootOptionSetFields (
// Add the length of the DevicePath EndType
FilePathListLength += DevicePathNodeLength (DevicePathNode);
+ InitrdPathListLength = 0;
+ if (BootType == BDS_LOADER_KERNEL_LINUX_ATAG && BootArguments->LinuxAtagArguments.InitrdPathList != NULL) {
+ // Compute the size of the InitrdPath list
+ InitrdPathNode = BootArguments->LinuxAtagArguments.InitrdPathList;
+ while (!IsDevicePathEndType (InitrdPathNode)) {
+ InitrdPathListLength += DevicePathNodeLength (InitrdPathNode);
+ InitrdPathNode = NextDevicePathNode (InitrdPathNode);
+ }
+ // Add the length of the DevicePath EndType
+ InitrdPathListLength += DevicePathNodeLength (InitrdPathNode);
+ }
+
// Allocate the memory for the EFI Load Option
EfiLoadOptionSize = sizeof(UINT32) + sizeof(UINT16) + BootDescriptionSize + FilePathListLength + BootOptionalDataSize;
EfiLoadOption = (EFI_LOAD_OPTION)AllocatePool(EfiLoadOptionSize);
@@ -257,9 +280,34 @@ BootOptionSetFields (
// Optional Data fields, Do unaligned writes
WriteUnaligned32 ((UINT32 *)EfiLoadOptionPtr, BootType);
- CopyMem (&((BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments, BootArguments, AsciiStrSize(BootArguments));
BootOption->OptionalData = (BDS_LOADER_OPTIONAL_DATA *)EfiLoadOptionPtr;
+ if (BootType == BDS_LOADER_KERNEL_LINUX_ATAG) {
+ CopyMem (&((BDS_LOADER_OPTIONAL_DATA*)EfiLoadOptionPtr)->Arguments.LinuxAtagArguments.CmdLine,
+ BootArguments->LinuxAtagArguments.CmdLine,
+ AsciiStrSize(BootArguments->LinuxAtagArguments.CmdLine));
+
+ WriteUnaligned32 ((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathListLength), InitrdPathListLength);
+
+ if ((EFI_DEVICE_PATH_PROTOCOL*)ReadUnaligned32((UINT32 *)&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList) != NULL
+ && BootArguments->LinuxAtagArguments.InitrdPathList != NULL) {
+ InitrdPathListPtr = AllocatePool(InitrdPathListLength);
+ WriteUnaligned32 ((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList), (UINT32)InitrdPathListPtr);
+ InitrdPathNode = BootArguments->LinuxAtagArguments.InitrdPathList;
+
+ while (!IsDevicePathEndType (InitrdPathNode)) {
+ NodeLength = DevicePathNodeLength(InitrdPathNode);
+ CopyMem (InitrdPathListPtr, InitrdPathNode, NodeLength);
+ InitrdPathListPtr += NodeLength;
+ InitrdPathNode = NextDevicePathNode (InitrdPathNode);
+ }
+
+ // Set the End Device Path Type
+ SetDevicePathEndNode (InitrdPathListPtr);
+ } else {
+ WriteUnaligned32 ((UINT32 *)(&BootOption->OptionalData->Arguments.LinuxAtagArguments.InitrdPathList), (UINT32)NULL);
+ }
+ }
// If this function is called at the creation of the Boot Device entry (not at the update) the
// BootOption->LoadOptionSize must be zero then we get a new BootIndex for this entry
if (BootOption->LoadOptionSize == 0) {
@@ -279,7 +327,7 @@ BootOptionCreate (
IN CHAR16* BootDescription,
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
IN BDS_LOADER_TYPE BootType,
- IN CHAR8* BootArguments,
+ IN BDS_LOADER_ARGUMENTS* BootArguments,
OUT BDS_LOAD_OPTION **BdsLoadOption
)
{
@@ -344,7 +392,7 @@ BootOptionUpdate (
IN CHAR16* BootDescription,
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
IN BDS_LOADER_TYPE BootType,
- IN CHAR8* BootArguments
+ IN BDS_LOADER_ARGUMENTS* BootArguments
)
{
EFI_STATUS Status;