3 * Copyright (c) 2011-2015, ARM Limited. All rights reserved.
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include <Library/UefiApplicationEntryPoint.h>
16 #include <Library/BaseMemoryLib.h>
18 #include <Protocol/DevicePathFromText.h>
20 #include "LinuxLoader.h"
23 The user Entry Point for Application. The user code starts with this function
24 as the real entry point for the application.
26 @param[in] ImageHandle The firmware allocated handle for the EFI image.
27 @param[in] SystemTable A pointer to the EFI System Table.
29 @retval EFI_SUCCESS The entry point was executed successfully.
30 @retval EFI_NOT_FOUND Protocol not found.
31 @retval EFI_NOT_FOUND Path to the Linux kernel not found.
32 @retval EFI_ABORTED The initialisation of the Shell Library failed.
33 @retval EFI_INVALID_PARAMETER At least one parameter is not valid or there is a
34 conflict between two parameters.
35 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
40 LinuxLoaderEntryPoint (
41 IN EFI_HANDLE ImageHandle
,
42 IN EFI_SYSTEM_TABLE
*SystemTable
46 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL
*EfiDevicePathFromTextProtocol
;
47 EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
;
51 CHAR16
*KernelTextDevicePath
;
52 CHAR16
*FdtTextDevicePath
;
53 CHAR16
*InitrdTextDevicePath
;
54 CHAR16
*LinuxCommandLine
;
55 UINTN AtagMachineType
;
56 EFI_DEVICE_PATH
*KernelDevicePath
;
57 EFI_DEVICE_PATH
*FdtDevicePath
;
58 EFI_DEVICE_PATH
*InitrdDevicePath
;
59 CHAR8
*AsciiLinuxCommandLine
;
60 LIST_ENTRY ResourceList
;
61 LIST_ENTRY
*ResourceLink
;
62 SYSTEM_MEMORY_RESOURCE
*Resource
;
63 EFI_PHYSICAL_ADDRESS SystemMemoryBase
;
66 Status
= gBS
->LocateProtocol (
67 &gEfiDevicePathFromTextProtocolGuid
,
69 (VOID
**)&EfiDevicePathFromTextProtocol
71 if (EFI_ERROR (Status
)) {
76 // Register the strings for the user interface in the HII Database.
77 // This shows the way to the multi-language support, even if
78 // only the English language is actually supported. The strings to register
79 // are stored in the "LinuxLoaderStrings[]" array. This array is
80 // built by the building process from the "*.uni" file associated to
81 // the present application (cf. LinuxLoader.inf). Examine the Build
82 // folder of the application and you will find the array defined in the
83 // LinuxLoaderStrDefs.h file.
85 mLinuxLoaderHiiHandle
= HiiAddPackages (
91 if (mLinuxLoaderHiiHandle
== NULL
) {
95 Status
= gBS
->HandleProtocol (
97 &gEfiShellParametersProtocolGuid
,
98 (VOID
**)&ShellParameters
101 KernelDevicePath
= NULL
;
102 FdtDevicePath
= NULL
;
103 InitrdDevicePath
= NULL
;
104 AsciiLinuxCommandLine
= NULL
;
107 // Call the proper function to handle the command line
108 // depending on whether the application has been called
109 // from the Shell or not.
112 if (!EFI_ERROR (Status
)) {
113 KernelTextDevicePath
= NULL
;
114 FdtTextDevicePath
= NULL
;
115 InitrdTextDevicePath
= NULL
;
117 Status
= ProcessShellParameters (
118 &KernelPath
, &FdtPath
, &InitrdPath
, &LinuxCommandLine
, &AtagMachineType
120 if (EFI_ERROR (Status
)) {
124 KernelDevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath (KernelPath
);
125 if (KernelDevicePath
!= NULL
) {
126 FreePool (KernelPath
);
128 KernelTextDevicePath
= KernelPath
;
131 if (FdtPath
!= NULL
) {
132 FdtDevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath (FdtPath
);
133 if (FdtDevicePath
!= NULL
) {
136 FdtTextDevicePath
= FdtPath
;
140 if (InitrdPath
!= NULL
) {
141 InitrdDevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath (InitrdPath
);
142 if (InitrdDevicePath
!= NULL
) {
143 FreePool (InitrdPath
);
145 InitrdTextDevicePath
= InitrdPath
;
150 Status
= ProcessAppCommandLine (
151 &KernelTextDevicePath
, &FdtTextDevicePath
,
152 &InitrdTextDevicePath
, &LinuxCommandLine
, &AtagMachineType
154 if (EFI_ERROR (Status
)) {
159 Status
= EFI_INVALID_PARAMETER
;
160 if (KernelTextDevicePath
!= NULL
) {
161 KernelDevicePath
= EfiDevicePathFromTextProtocol
->ConvertTextToDevicePath (
164 if (KernelDevicePath
== NULL
) {
168 if (FdtTextDevicePath
!= NULL
) {
169 FdtDevicePath
= EfiDevicePathFromTextProtocol
->ConvertTextToDevicePath (
172 if (FdtDevicePath
== NULL
) {
176 if (InitrdTextDevicePath
!= NULL
) {
177 InitrdDevicePath
= EfiDevicePathFromTextProtocol
->ConvertTextToDevicePath (
180 if (InitrdDevicePath
== NULL
) {
185 if (LinuxCommandLine
!= NULL
) {
186 Length
= StrLen (LinuxCommandLine
) + 1;
187 AsciiLinuxCommandLine
= AllocatePool (Length
);
188 if (AsciiLinuxCommandLine
== NULL
) {
189 Status
= EFI_OUT_OF_RESOURCES
;
192 UnicodeStrToAsciiStrS (LinuxCommandLine
, AsciiLinuxCommandLine
, Length
);
196 // Find Base of System Memory - we keep the lowest physical address
198 SystemMemoryBase
= ~0;
199 GetSystemMemoryResources (&ResourceList
);
200 ResourceLink
= ResourceList
.ForwardLink
;
201 while (ResourceLink
!= NULL
&& ResourceLink
!= &ResourceList
) {
202 Resource
= (SYSTEM_MEMORY_RESOURCE
*)ResourceLink
;
203 if (Resource
->PhysicalStart
< SystemMemoryBase
) {
204 SystemMemoryBase
= Resource
->PhysicalStart
;
206 ResourceLink
= ResourceLink
->ForwardLink
;
209 if (AtagMachineType
!= ARM_FDT_MACHINE_TYPE
) {
210 Status
= BootLinuxAtag (SystemMemoryBase
, KernelDevicePath
, InitrdDevicePath
, AsciiLinuxCommandLine
, AtagMachineType
);
212 Status
= BootLinuxFdt (SystemMemoryBase
, KernelDevicePath
, InitrdDevicePath
, FdtDevicePath
, AsciiLinuxCommandLine
);
216 if (KernelTextDevicePath
!= NULL
) {
217 FreePool (KernelTextDevicePath
);
219 if (FdtTextDevicePath
!= NULL
) {
220 FreePool (FdtTextDevicePath
);
222 if (InitrdTextDevicePath
!= NULL
) {
223 FreePool (InitrdTextDevicePath
);
225 if (LinuxCommandLine
!= NULL
) {
226 FreePool (LinuxCommandLine
);
228 if (KernelDevicePath
!= NULL
) {
229 FreePool (KernelDevicePath
);
231 if (FdtDevicePath
!= NULL
) {
232 FreePool (FdtDevicePath
);
234 if (InitrdDevicePath
!= NULL
) {
235 FreePool (InitrdDevicePath
);
237 if (AsciiLinuxCommandLine
!= NULL
) {
238 FreePool (AsciiLinuxCommandLine
);
241 if (EFI_ERROR (Status
)) {
242 PrintHii (NULL
, STRING_TOKEN (STR_ERROR
), Status
);
245 HiiRemovePackages (mLinuxLoaderHiiHandle
);