EFI_STATUS BootOptionStart ( IN BDS_LOAD_OPTION *BootOption ) { EFI_STATUS Status; EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol; UINT32 LoaderType; ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData; ARM_BDS_LINUX_ARGUMENTS* LinuxArguments; EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath; EFI_DEVICE_PATH_PROTOCOL* DefaultFdtDevicePath; UINTN FdtDevicePathSize; UINTN CmdLineSize; UINTN InitrdSize; EFI_DEVICE_PATH* Initrd; UINT16 LoadOptionIndexSize; if (IS_ARM_BDS_BOOTENTRY (BootOption)) { Status = EFI_UNSUPPORTED; OptionalData = BootOption->OptionalData; LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType); if (LoaderType == BDS_LOADER_EFI_APPLICATION) { if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) { // Need to connect every drivers to ensure no dependencies are missing for the application BdsConnectAllDrivers (); } Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, 0, NULL); } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) { LinuxArguments = &(OptionalData->Arguments.LinuxArguments); CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); } else { Initrd = NULL; } Status = BdsBootLinuxAtag (BootOption->FilePathList, Initrd, // Initrd (CHAR8*)(LinuxArguments + 1)); // CmdLine } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) { LinuxArguments = &(OptionalData->Arguments.LinuxArguments); CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); } else { Initrd = NULL; } // Get the default FDT device path Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); ASSERT_EFI_ERROR(Status); DefaultFdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath)); // Get the FDT device path FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath); Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", &gArmGlobalVariableGuid, DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath); ASSERT_EFI_ERROR(Status); Status = BdsBootLinuxFdt (BootOption->FilePathList, Initrd, // Initrd (CHAR8*)(LinuxArguments + 1), FdtDevicePath); FreePool (DefaultFdtDevicePath); FreePool (FdtDevicePath); } } else { // Connect all the drivers if the EFI Application is not a EFI OS Loader if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) { BdsConnectAllDrivers (); } // Set BootCurrent variable LoadOptionIndexSize = sizeof(UINT16); gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, LoadOptionIndexSize, &(BootOption->LoadOptionIndex)); Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData); // Clear BootCurrent variable LoadOptionIndexSize = sizeof(UINT16); gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL); } return Status; }
EFI_STATUS BootAndroidBootImg ( IN UINTN BufferSize, IN VOID *Buffer ) { EFI_STATUS Status; CHAR8 KernelArgs[BOOTIMG_KERNEL_ARGS_SIZE]; VOID *Kernel; UINTN KernelSize; VOID *Ramdisk; UINTN RamdiskSize; MEMORY_DEVICE_PATH KernelDevicePath; MEMORY_DEVICE_PATH* RamdiskDevicePath; Status = ParseAndroidBootImg ( Buffer, &Kernel, &KernelSize, &Ramdisk, &RamdiskSize, KernelArgs ); if (EFI_ERROR (Status)) { return Status; } KernelDevicePath = MemoryDevicePathTemplate; // Have to cast to UINTN before casting to EFI_PHYSICAL_ADDRESS in order to // appease GCC. KernelDevicePath.Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel; KernelDevicePath.Node1.EndingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Kernel + KernelSize; RamdiskDevicePath = NULL; if (RamdiskSize != 0) { RamdiskDevicePath = (MEMORY_DEVICE_PATH*)DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*) &MemoryDevicePathTemplate); RamdiskDevicePath->Node1.StartingAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk; RamdiskDevicePath->Node1.EndingAddress = ((EFI_PHYSICAL_ADDRESS)(UINTN) Ramdisk) + RamdiskSize; } Status = BdsBootLinuxFdt ( (EFI_DEVICE_PATH_PROTOCOL *) &KernelDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) RamdiskDevicePath, KernelArgs ); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Couldn't Boot Linux: %d\n", Status)); return EFI_DEVICE_ERROR; } if (RamdiskDevicePath) { FreePool (RamdiskDevicePath); } // If we got here we do a confused face because BootLinuxFdt returned, // reporting success. DEBUG ((EFI_D_ERROR, "WARNING: BdsBootLinuxFdt returned EFI_SUCCESS.\n")); return EFI_SUCCESS; }
EFI_STATUS BootOptionStart ( IN BDS_LOAD_OPTION *BootOption ) { EFI_STATUS Status; UINT32 LoaderType; ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData; ARM_BDS_LINUX_ARGUMENTS* LinuxArguments; UINTN CmdLineSize; UINTN InitrdSize; EFI_DEVICE_PATH* Initrd; UINT16 LoadOptionIndexSize; if (IS_ARM_BDS_BOOTENTRY (BootOption)) { Status = EFI_UNSUPPORTED; OptionalData = BootOption->OptionalData; LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType); if (LoaderType == BDS_LOADER_EFI_APPLICATION) { if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) { // Need to connect every drivers to ensure no dependencies are missing for the application BdsConnectAllDrivers (); } Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, 0, NULL); } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) { LinuxArguments = &(OptionalData->Arguments.LinuxArguments); CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); } else { Initrd = NULL; } Status = BdsBootLinuxAtag (BootOption->FilePathList, Initrd, // Initrd (CHAR8*)(LinuxArguments + 1)); // CmdLine } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) { LinuxArguments = &(OptionalData->Arguments.LinuxArguments); CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize); InitrdSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->InitrdSize); if (InitrdSize > 0) { Initrd = GetAlignedDevicePath ((EFI_DEVICE_PATH*)((UINTN)(LinuxArguments + 1) + CmdLineSize)); } else { Initrd = NULL; } Status = BdsBootLinuxFdt ( BootOption->FilePathList, Initrd, (CHAR8*)(LinuxArguments + 1) ); } } else { // Connect all the drivers if the EFI Application is not a EFI OS Loader if ((BootOption->Attributes & LOAD_OPTION_CATEGORY) == LOAD_OPTION_CATEGORY_APP) { BdsConnectAllDrivers (); } // Set BootCurrent variable LoadOptionIndexSize = sizeof(UINT16); gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, LoadOptionIndexSize, &(BootOption->LoadOptionIndex)); Status = BdsStartEfiApplication (gImageHandle, BootOption->FilePathList, BootOption->OptionalDataSize, BootOption->OptionalData); // Clear BootCurrent variable LoadOptionIndexSize = sizeof(UINT16); gRT->SetVariable (L"BootCurrent", &gEfiGlobalVariableGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL); } return Status; }