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
;
65 Status
= gBS
->LocateProtocol (
66 &gEfiDevicePathFromTextProtocolGuid
,
68 (VOID
**)&EfiDevicePathFromTextProtocol
70 if (EFI_ERROR (Status
)) {
75 // Register the strings for the user interface in the HII Database.
76 // This shows the way to the multi-language support, even if
77 // only the English language is actually supported. The strings to register
78 // are stored in the "LinuxLoaderStrings[]" array. This array is
79 // built by the building process from the "*.uni" file associated to
80 // the present application (cf. LinuxLoader.inf). Examine the Build
81 // folder of the application and you will find the array defined in the
82 // LinuxLoaderStrDefs.h file.
84 mLinuxLoaderHiiHandle
= HiiAddPackages (
90 if (mLinuxLoaderHiiHandle
== NULL
) {
94 Status
= gBS
->HandleProtocol (
96 &gEfiShellParametersProtocolGuid
,
97 (VOID
**)&ShellParameters
100 KernelDevicePath
= NULL
;
101 FdtDevicePath
= NULL
;
102 InitrdDevicePath
= NULL
;
103 AsciiLinuxCommandLine
= NULL
;
106 // Call the proper function to handle the command line
107 // depending on whether the application has been called
108 // from the Shell or not.
111 if (!EFI_ERROR (Status
)) {
112 KernelTextDevicePath
= NULL
;
113 FdtTextDevicePath
= NULL
;
114 InitrdTextDevicePath
= NULL
;
116 Status
= ProcessShellParameters (
117 &KernelPath
, &FdtPath
, &InitrdPath
, &LinuxCommandLine
, &AtagMachineType
119 if (EFI_ERROR (Status
)) {
123 KernelDevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath (KernelPath
);
124 if (KernelDevicePath
!= NULL
) {
125 FreePool (KernelPath
);
127 KernelTextDevicePath
= KernelPath
;
130 if (FdtPath
!= NULL
) {
131 FdtDevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath (FdtPath
);
132 if (FdtDevicePath
!= NULL
) {
135 FdtTextDevicePath
= FdtPath
;
139 if (InitrdPath
!= NULL
) {
140 InitrdDevicePath
= gEfiShellProtocol
->GetDevicePathFromFilePath (InitrdPath
);
141 if (InitrdDevicePath
!= NULL
) {
142 FreePool (InitrdPath
);
144 InitrdTextDevicePath
= InitrdPath
;
149 Status
= ProcessAppCommandLine (
150 &KernelTextDevicePath
, &FdtTextDevicePath
,
151 &InitrdTextDevicePath
, &LinuxCommandLine
, &AtagMachineType
153 if (EFI_ERROR (Status
)) {
158 Status
= EFI_INVALID_PARAMETER
;
159 if (KernelTextDevicePath
!= NULL
) {
160 KernelDevicePath
= EfiDevicePathFromTextProtocol
->ConvertTextToDevicePath (
163 if (KernelDevicePath
== NULL
) {
167 if (FdtTextDevicePath
!= NULL
) {
168 FdtDevicePath
= EfiDevicePathFromTextProtocol
->ConvertTextToDevicePath (
171 if (FdtDevicePath
== NULL
) {
175 if (InitrdTextDevicePath
!= NULL
) {
176 InitrdDevicePath
= EfiDevicePathFromTextProtocol
->ConvertTextToDevicePath (
179 if (InitrdDevicePath
== NULL
) {
184 if (LinuxCommandLine
!= NULL
) {
185 AsciiLinuxCommandLine
= AllocatePool ((StrLen (LinuxCommandLine
) + 1) * sizeof (CHAR8
));
186 if (AsciiLinuxCommandLine
== NULL
) {
187 Status
= EFI_OUT_OF_RESOURCES
;
190 UnicodeStrToAsciiStr (LinuxCommandLine
, AsciiLinuxCommandLine
);
194 // Find Base of System Memory - we keep the lowest physical address
196 SystemMemoryBase
= ~0;
197 GetSystemMemoryResources (&ResourceList
);
198 ResourceLink
= ResourceList
.ForwardLink
;
199 while (ResourceLink
!= NULL
&& ResourceLink
!= &ResourceList
) {
200 Resource
= (SYSTEM_MEMORY_RESOURCE
*)ResourceLink
;
201 if (Resource
->PhysicalStart
< SystemMemoryBase
) {
202 SystemMemoryBase
= Resource
->PhysicalStart
;
204 ResourceLink
= ResourceLink
->ForwardLink
;
207 if (AtagMachineType
!= ARM_FDT_MACHINE_TYPE
) {
208 Status
= BootLinuxAtag (SystemMemoryBase
, KernelDevicePath
, InitrdDevicePath
, AsciiLinuxCommandLine
, AtagMachineType
);
210 Status
= BootLinuxFdt (SystemMemoryBase
, KernelDevicePath
, InitrdDevicePath
, FdtDevicePath
, AsciiLinuxCommandLine
);
214 if (KernelTextDevicePath
!= NULL
) {
215 FreePool (KernelTextDevicePath
);
217 if (FdtTextDevicePath
!= NULL
) {
218 FreePool (FdtTextDevicePath
);
220 if (InitrdTextDevicePath
!= NULL
) {
221 FreePool (InitrdTextDevicePath
);
223 if (LinuxCommandLine
!= NULL
) {
224 FreePool (LinuxCommandLine
);
226 if (KernelDevicePath
!= NULL
) {
227 FreePool (KernelDevicePath
);
229 if (FdtDevicePath
!= NULL
) {
230 FreePool (FdtDevicePath
);
232 if (InitrdDevicePath
!= NULL
) {
233 FreePool (InitrdDevicePath
);
235 if (AsciiLinuxCommandLine
!= NULL
) {
236 FreePool (AsciiLinuxCommandLine
);
239 if (EFI_ERROR (Status
)) {
240 PrintHii (NULL
, STRING_TOKEN (STR_ERROR
), Status
);
243 HiiRemovePackages (mLinuxLoaderHiiHandle
);