]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/Library/PlatformBdsLib/QemuKernel.c
47ebed9f6d157cfea16b1de39072da7a6121b7c2
[mirror_edk2.git] / OvmfPkg / Library / PlatformBdsLib / QemuKernel.c
1 /** @file
2
3 Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 **/
13
14 #include <Uefi.h>
15
16 #include <Library/BaseLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/LoadLinuxLib.h>
19 #include <Library/MemoryAllocationLib.h>
20 #include <Library/QemuFwCfgLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22
23
24 EFI_STATUS
25 TryRunningQemuKernel (
26 VOID
27 )
28 {
29 EFI_STATUS Status;
30 UINTN KernelSize;
31 UINTN KernelInitialSize;
32 VOID *KernelBuf;
33 UINTN SetupSize;
34 VOID *SetupBuf;
35 UINTN CommandLineSize;
36 CHAR8 *CommandLine;
37 UINTN InitrdSize;
38 VOID* InitrdData;
39
40 SetupBuf = NULL;
41 SetupSize = 0;
42 KernelBuf = NULL;
43 KernelInitialSize = 0;
44 CommandLine = NULL;
45 CommandLineSize = 0;
46 InitrdData = NULL;
47 InitrdSize = 0;
48
49 if (!QemuFwCfgIsAvailable ()) {
50 return EFI_NOT_FOUND;
51 }
52
53 QemuFwCfgSelectItem (QemuFwCfgItemKernelSize);
54 KernelSize = (UINTN) QemuFwCfgRead64 ();
55
56 QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupSize);
57 SetupSize = (UINTN) QemuFwCfgRead64 ();
58
59 if (KernelSize == 0 || SetupSize == 0) {
60 DEBUG ((EFI_D_INFO, "qemu -kernel was not used.\n"));
61 return EFI_NOT_FOUND;
62 }
63
64 SetupBuf = LoadLinuxAllocateKernelSetupPages (EFI_SIZE_TO_PAGES (SetupSize));
65 if (SetupBuf == NULL) {
66 DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel setup!\n"));
67 return EFI_OUT_OF_RESOURCES;
68 }
69
70 DEBUG ((EFI_D_INFO, "Setup size: 0x%x\n", (UINT32) SetupSize));
71 DEBUG ((EFI_D_INFO, "Reading kernel setup image ..."));
72 QemuFwCfgSelectItem (QemuFwCfgItemKernelSetupData);
73 QemuFwCfgReadBytes (SetupSize, SetupBuf);
74 DEBUG ((EFI_D_INFO, " [done]\n"));
75
76 Status = LoadLinuxCheckKernelSetup (SetupBuf, SetupSize);
77 if (EFI_ERROR (Status)) {
78 goto FreeAndReturn;
79 }
80
81 Status = LoadLinuxInitializeKernelSetup (SetupBuf);
82 if (EFI_ERROR (Status)) {
83 goto FreeAndReturn;
84 }
85
86 KernelInitialSize = LoadLinuxGetKernelSize (SetupBuf, KernelSize);
87 if (KernelInitialSize == 0) {
88 Status = EFI_UNSUPPORTED;
89 goto FreeAndReturn;
90 }
91
92 KernelBuf = LoadLinuxAllocateKernelPages (
93 SetupBuf,
94 EFI_SIZE_TO_PAGES (KernelInitialSize));
95 if (KernelBuf == NULL) {
96 DEBUG ((EFI_D_ERROR, "Unable to allocate memory for kernel!\n"));
97 Status = EFI_OUT_OF_RESOURCES;
98 goto FreeAndReturn;
99 }
100
101 DEBUG ((EFI_D_INFO, "Kernel size: 0x%x\n", (UINT32) KernelSize));
102 DEBUG ((EFI_D_INFO, "Reading kernel image ..."));
103 QemuFwCfgSelectItem (QemuFwCfgItemKernelData);
104 QemuFwCfgReadBytes (KernelSize, KernelBuf);
105 DEBUG ((EFI_D_INFO, " [done]\n"));
106
107 QemuFwCfgSelectItem (QemuFwCfgItemCommandLineSize);
108 CommandLineSize = (UINTN) QemuFwCfgRead64 ();
109
110 if (CommandLineSize > 0) {
111 CommandLine = LoadLinuxAllocateCommandLinePages (
112 EFI_SIZE_TO_PAGES (CommandLineSize));
113 QemuFwCfgSelectItem (QemuFwCfgItemCommandLineData);
114 QemuFwCfgReadBytes (CommandLineSize, CommandLine);
115 } else {
116 CommandLine = NULL;
117 }
118
119 Status = LoadLinuxSetCommandLine (SetupBuf, CommandLine);
120 if (EFI_ERROR (Status)) {
121 goto FreeAndReturn;
122 }
123
124 QemuFwCfgSelectItem (QemuFwCfgItemInitrdSize);
125 InitrdSize = (UINTN) QemuFwCfgRead64 ();
126
127 if (InitrdSize > 0) {
128 InitrdData = LoadLinuxAllocateInitrdPages (
129 SetupBuf,
130 EFI_SIZE_TO_PAGES (InitrdSize)
131 );
132 DEBUG ((EFI_D_INFO, "Initrd size: 0x%x\n", (UINT32) InitrdSize));
133 DEBUG ((EFI_D_INFO, "Reading initrd image ..."));
134 QemuFwCfgSelectItem (QemuFwCfgItemInitrdData);
135 QemuFwCfgReadBytes (InitrdSize, InitrdData);
136 DEBUG ((EFI_D_INFO, " [done]\n"));
137 } else {
138 InitrdData = NULL;
139 }
140
141 Status = LoadLinuxSetInitrd (SetupBuf, InitrdData, InitrdSize);
142 if (EFI_ERROR (Status)) {
143 goto FreeAndReturn;
144 }
145
146 Status = LoadLinux (KernelBuf, SetupBuf);
147
148 FreeAndReturn:
149 if (SetupBuf != NULL) {
150 FreePages (SetupBuf, EFI_SIZE_TO_PAGES (SetupSize));
151 }
152 if (KernelBuf != NULL) {
153 FreePages (KernelBuf, EFI_SIZE_TO_PAGES (KernelInitialSize));
154 }
155 if (CommandLine != NULL) {
156 FreePages (CommandLine, EFI_SIZE_TO_PAGES (CommandLineSize));
157 }
158 if (InitrdData != NULL) {
159 FreePages (InitrdData, EFI_SIZE_TO_PAGES (InitrdSize));
160 }
161
162 return Status;
163 }
164