]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Application/LinuxLoader/LinuxLoader.c
ArmPkg/LinuxLoader: eliminate calls to deprecated string functions
[mirror_edk2.git] / ArmPkg / Application / LinuxLoader / LinuxLoader.c
1 /** @file
2 *
3 * Copyright (c) 2011-2015, ARM Limited. All rights reserved.
4 *
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
9 *
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.
12 *
13 **/
14
15 #include <Library/UefiApplicationEntryPoint.h>
16 #include <Library/BaseMemoryLib.h>
17
18 #include <Protocol/DevicePathFromText.h>
19
20 #include "LinuxLoader.h"
21
22 /**
23 The user Entry Point for Application. The user code starts with this function
24 as the real entry point for the application.
25
26 @param[in] ImageHandle The firmware allocated handle for the EFI image.
27 @param[in] SystemTable A pointer to the EFI System Table.
28
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.
36
37 **/
38 EFI_STATUS
39 EFIAPI
40 LinuxLoaderEntryPoint (
41 IN EFI_HANDLE ImageHandle,
42 IN EFI_SYSTEM_TABLE *SystemTable
43 )
44 {
45 EFI_STATUS Status;
46 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
47 EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;
48 CHAR16 *KernelPath;
49 CHAR16 *FdtPath;
50 CHAR16 *InitrdPath;
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;
64 UINTN Length;
65
66 Status = gBS->LocateProtocol (
67 &gEfiDevicePathFromTextProtocolGuid,
68 NULL,
69 (VOID **)&EfiDevicePathFromTextProtocol
70 );
71 if (EFI_ERROR (Status)) {
72 return EFI_NOT_FOUND;
73 }
74
75 //
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.
84 //
85 mLinuxLoaderHiiHandle = HiiAddPackages (
86 &mLinuxLoaderHiiGuid,
87 ImageHandle,
88 LinuxLoaderStrings,
89 NULL
90 );
91 if (mLinuxLoaderHiiHandle == NULL) {
92 return EFI_NOT_FOUND;
93 }
94
95 Status = gBS->HandleProtocol (
96 ImageHandle,
97 &gEfiShellParametersProtocolGuid,
98 (VOID**)&ShellParameters
99 );
100
101 KernelDevicePath = NULL;
102 FdtDevicePath = NULL;
103 InitrdDevicePath = NULL;
104 AsciiLinuxCommandLine = NULL;
105
106 //
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.
110 //
111
112 if (!EFI_ERROR (Status)) {
113 KernelTextDevicePath = NULL;
114 FdtTextDevicePath = NULL;
115 InitrdTextDevicePath = NULL;
116
117 Status = ProcessShellParameters (
118 &KernelPath, &FdtPath, &InitrdPath, &LinuxCommandLine, &AtagMachineType
119 );
120 if (EFI_ERROR (Status)) {
121 goto Error;
122 }
123
124 KernelDevicePath = gEfiShellProtocol->GetDevicePathFromFilePath (KernelPath);
125 if (KernelDevicePath != NULL) {
126 FreePool (KernelPath);
127 } else {
128 KernelTextDevicePath = KernelPath;
129 }
130
131 if (FdtPath != NULL) {
132 FdtDevicePath = gEfiShellProtocol->GetDevicePathFromFilePath (FdtPath);
133 if (FdtDevicePath != NULL) {
134 FreePool (FdtPath);
135 } else {
136 FdtTextDevicePath = FdtPath;
137 }
138 }
139
140 if (InitrdPath != NULL) {
141 InitrdDevicePath = gEfiShellProtocol->GetDevicePathFromFilePath (InitrdPath);
142 if (InitrdDevicePath != NULL) {
143 FreePool (InitrdPath);
144 } else {
145 InitrdTextDevicePath = InitrdPath;
146 }
147 }
148
149 } else {
150 Status = ProcessAppCommandLine (
151 &KernelTextDevicePath, &FdtTextDevicePath,
152 &InitrdTextDevicePath, &LinuxCommandLine, &AtagMachineType
153 );
154 if (EFI_ERROR (Status)) {
155 goto Error;
156 }
157 }
158
159 Status = EFI_INVALID_PARAMETER;
160 if (KernelTextDevicePath != NULL) {
161 KernelDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (
162 KernelTextDevicePath
163 );
164 if (KernelDevicePath == NULL) {
165 goto Error;
166 }
167 }
168 if (FdtTextDevicePath != NULL) {
169 FdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (
170 FdtTextDevicePath
171 );
172 if (FdtDevicePath == NULL) {
173 goto Error;
174 }
175 }
176 if (InitrdTextDevicePath != NULL) {
177 InitrdDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (
178 InitrdTextDevicePath
179 );
180 if (InitrdDevicePath == NULL) {
181 goto Error;
182 }
183 }
184
185 if (LinuxCommandLine != NULL) {
186 Length = StrLen (LinuxCommandLine) + 1;
187 AsciiLinuxCommandLine = AllocatePool (Length);
188 if (AsciiLinuxCommandLine == NULL) {
189 Status = EFI_OUT_OF_RESOURCES;
190 goto Error;
191 }
192 UnicodeStrToAsciiStrS (LinuxCommandLine, AsciiLinuxCommandLine, Length);
193 }
194
195 //
196 // Find Base of System Memory - we keep the lowest physical address
197 //
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;
205 }
206 ResourceLink = ResourceLink->ForwardLink;
207 }
208
209 if (AtagMachineType != ARM_FDT_MACHINE_TYPE) {
210 Status = BootLinuxAtag (SystemMemoryBase, KernelDevicePath, InitrdDevicePath, AsciiLinuxCommandLine, AtagMachineType);
211 } else {
212 Status = BootLinuxFdt (SystemMemoryBase, KernelDevicePath, InitrdDevicePath, FdtDevicePath, AsciiLinuxCommandLine);
213 }
214
215 Error:
216 if (KernelTextDevicePath != NULL) {
217 FreePool (KernelTextDevicePath);
218 }
219 if (FdtTextDevicePath != NULL) {
220 FreePool (FdtTextDevicePath);
221 }
222 if (InitrdTextDevicePath != NULL) {
223 FreePool (InitrdTextDevicePath);
224 }
225 if (LinuxCommandLine != NULL) {
226 FreePool (LinuxCommandLine);
227 }
228 if (KernelDevicePath != NULL) {
229 FreePool (KernelDevicePath);
230 }
231 if (FdtDevicePath != NULL) {
232 FreePool (FdtDevicePath);
233 }
234 if (InitrdDevicePath != NULL) {
235 FreePool (InitrdDevicePath);
236 }
237 if (AsciiLinuxCommandLine != NULL) {
238 FreePool (AsciiLinuxCommandLine);
239 }
240
241 if (EFI_ERROR (Status)) {
242 PrintHii (NULL, STRING_TOKEN (STR_ERROR), Status);
243 }
244
245 HiiRemovePackages (mLinuxLoaderHiiHandle);
246
247 return Status;
248 }