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 BootAndroidBootImg ( IN UINTN BufferSize, IN VOID *Buffer ) { EFI_STATUS Status; CHAR8 KernelArgs[ANDROID_BOOTIMG_KERNEL_ARGS_SIZE]; VOID *Kernel; UINTN KernelSize; VOID *Ramdisk; UINTN RamdiskSize; MEMORY_DEVICE_PATH KernelDevicePath; CHAR16 *LoadOptions, *NewLoadOptions; 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; // Initialize Linux command line LoadOptions = CatSPrint (NULL, L"%a", KernelArgs); if (LoadOptions == NULL) { return EFI_OUT_OF_RESOURCES; } if (RamdiskSize != 0) { NewLoadOptions = CatSPrint (LoadOptions, L" initrd=0x%x,0x%x", (UINTN)Ramdisk, RamdiskSize); FreePool (LoadOptions); if (NewLoadOptions == NULL) { return EFI_OUT_OF_RESOURCES; } LoadOptions = NewLoadOptions; } Status = StartEfiApplication (gImageHandle, (EFI_DEVICE_PATH_PROTOCOL *) &KernelDevicePath, StrSize (LoadOptions), LoadOptions); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Couldn't Boot Linux: %d\n", Status)); Status = EFI_DEVICE_ERROR; goto FreeLoadOptions; } // 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; FreeLoadOptions: FreePool (LoadOptions); return Status; }