3 Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "LoadLinuxLib.h"
12 A simple check of the kernel setup image
14 An assumption is made that the size of the data is at least the
15 size of struct boot_params.
17 @param[in] KernelSetup - The kernel setup image
19 @retval EFI_SUCCESS - The kernel setup looks valid and supported
20 @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
21 @retval EFI_UNSUPPORTED - The kernel setup is not valid or supported
27 BasicKernelSetupCheck (
31 return LoadLinuxCheckKernelSetup (KernelSetup
, sizeof (struct boot_params
));
36 LoadLinuxCheckKernelSetup (
38 IN UINTN KernelSetupSize
41 struct boot_params
*Bp
;
43 if (KernelSetup
== NULL
) {
44 return EFI_INVALID_PARAMETER
;
47 if (KernelSetupSize
< sizeof (*Bp
)) {
48 return EFI_UNSUPPORTED
;
51 Bp
= (struct boot_params
*)KernelSetup
;
53 if ((Bp
->hdr
.signature
!= 0xAA55) || // Check boot sector signature
54 (Bp
->hdr
.header
!= SETUP_HDR
) ||
55 (Bp
->hdr
.version
< 0x205) || // We only support relocatable kernels
56 (!Bp
->hdr
.relocatable_kernel
)
59 return EFI_UNSUPPORTED
;
67 LoadLinuxGetKernelSize (
72 struct boot_params
*Bp
;
74 if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup
))) {
78 Bp
= (struct boot_params
*)KernelSetup
;
80 if (Bp
->hdr
.version
> 0x20a) {
81 return Bp
->hdr
.init_size
;
84 // Add extra size for kernel decompression
86 return 3 * KernelSize
;
92 LoadLinuxAllocateKernelSetupPages (
97 EFI_PHYSICAL_ADDRESS Address
;
100 Status
= gBS
->AllocatePages (
106 if (!EFI_ERROR (Status
)) {
107 return (VOID
*)(UINTN
)Address
;
115 LoadLinuxInitializeKernelSetup (
121 struct boot_params
*Bp
;
123 Status
= BasicKernelSetupCheck (KernelSetup
);
124 if (EFI_ERROR (Status
)) {
128 Bp
= (struct boot_params
*)KernelSetup
;
130 SetupEnd
= 0x202 + (Bp
->hdr
.jump
& 0xff);
133 // Clear all but the setup_header
135 ZeroMem (KernelSetup
, 0x1f1);
136 ZeroMem (((UINT8
*)KernelSetup
) + SetupEnd
, 4096 - SetupEnd
);
139 "Cleared kernel setup 0-0x1f1, 0x%Lx-0x1000\n",
148 LoadLinuxAllocateKernelPages (
149 IN VOID
*KernelSetup
,
154 EFI_PHYSICAL_ADDRESS KernelAddress
;
156 struct boot_params
*Bp
;
158 if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup
))) {
162 Bp
= (struct boot_params
*)KernelSetup
;
164 for (Loop
= 1; Loop
< 512; Loop
++) {
165 KernelAddress
= MultU64x32 (
166 2 * Bp
->hdr
.kernel_alignment
,
169 Status
= gBS
->AllocatePages (
175 if (!EFI_ERROR (Status
)) {
176 return (VOID
*)(UINTN
)KernelAddress
;
185 LoadLinuxAllocateCommandLinePages (
190 EFI_PHYSICAL_ADDRESS Address
;
193 Status
= gBS
->AllocatePages (
199 if (!EFI_ERROR (Status
)) {
200 return (VOID
*)(UINTN
)Address
;
208 LoadLinuxAllocateInitrdPages (
209 IN VOID
*KernelSetup
,
214 EFI_PHYSICAL_ADDRESS Address
;
216 struct boot_params
*Bp
;
218 if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup
))) {
222 Bp
= (struct boot_params
*)KernelSetup
;
224 Address
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Bp
->hdr
.ramdisk_max
;
225 Status
= gBS
->AllocatePages (
231 if (!EFI_ERROR (Status
)) {
232 return (VOID
*)(UINTN
)Address
;
241 IN OUT
struct boot_params
*Bp
245 UINT8 TmpMemoryMap
[1];
247 UINTN DescriptorSize
;
248 UINT32 DescriptorVersion
;
250 EFI_MEMORY_DESCRIPTOR
*MemoryMap
;
251 EFI_MEMORY_DESCRIPTOR
*MemoryMapPtr
;
253 struct efi_info
*Efi
;
254 struct e820_entry
*LastE820
;
255 struct e820_entry
*E820
;
256 UINTN E820EntryCount
;
257 EFI_PHYSICAL_ADDRESS LastEndAddr
;
260 // Get System MemoryMapSize
262 MemoryMapSize
= sizeof (TmpMemoryMap
);
263 Status
= gBS
->GetMemoryMap (
265 (EFI_MEMORY_DESCRIPTOR
*)TmpMemoryMap
,
270 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
272 // Enlarge space here, because we will allocate pool now.
274 MemoryMapSize
+= EFI_PAGE_SIZE
;
275 Status
= gBS
->AllocatePool (
280 ASSERT_EFI_ERROR (Status
);
283 // Get System MemoryMap
285 Status
= gBS
->GetMemoryMap (
292 ASSERT_EFI_ERROR (Status
);
295 E820
= &Bp
->e820_map
[0];
298 MemoryMapPtr
= MemoryMap
;
299 for (Index
= 0; Index
< (MemoryMapSize
/ DescriptorSize
); Index
++) {
302 if (MemoryMap
->NumberOfPages
== 0) {
306 switch (MemoryMap
->Type
) {
307 case EfiReservedMemoryType
:
308 case EfiRuntimeServicesCode
:
309 case EfiRuntimeServicesData
:
310 case EfiMemoryMappedIO
:
311 case EfiMemoryMappedIOPortSpace
:
313 E820Type
= E820_RESERVED
;
316 case EfiUnusableMemory
:
317 E820Type
= E820_UNUSABLE
;
320 case EfiACPIReclaimMemory
:
321 E820Type
= E820_ACPI
;
326 case EfiBootServicesCode
:
327 case EfiBootServicesData
:
328 case EfiConventionalMemory
:
332 case EfiACPIMemoryNVS
:
339 "Invalid EFI memory descriptor type (0x%x)!\n",
345 if ((LastE820
!= NULL
) &&
346 (LastE820
->type
== (UINT32
)E820Type
) &&
347 (MemoryMap
->PhysicalStart
== LastEndAddr
))
349 LastE820
->size
+= EFI_PAGES_TO_SIZE ((UINTN
)MemoryMap
->NumberOfPages
);
350 LastEndAddr
+= EFI_PAGES_TO_SIZE ((UINTN
)MemoryMap
->NumberOfPages
);
352 if (E820EntryCount
>= ARRAY_SIZE (Bp
->e820_map
)) {
356 E820
->type
= (UINT32
)E820Type
;
357 E820
->addr
= MemoryMap
->PhysicalStart
;
358 E820
->size
= EFI_PAGES_TO_SIZE ((UINTN
)MemoryMap
->NumberOfPages
);
360 LastEndAddr
= E820
->addr
+ E820
->size
;
368 MemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)((UINTN
)MemoryMap
+ DescriptorSize
);
371 Bp
->e820_entries
= (UINT8
)E820EntryCount
;
374 Efi
->efi_systab
= (UINT32
)(UINTN
)gST
;
375 Efi
->efi_memdesc_size
= (UINT32
)DescriptorSize
;
376 Efi
->efi_memdesc_version
= DescriptorVersion
;
377 Efi
->efi_memmap
= (UINT32
)(UINTN
)MemoryMapPtr
;
378 Efi
->efi_memmap_size
= (UINT32
)MemoryMapSize
;
380 Efi
->efi_loader_signature
= SIGNATURE_32 ('E', 'L', '3', '2');
382 Efi
->efi_systab_hi
= (UINT32
)(((UINT64
)(UINTN
)gST
) >> 32);
383 Efi
->efi_memmap_hi
= (UINT32
)(((UINT64
)(UINTN
)MemoryMapPtr
) >> 32);
384 Efi
->efi_loader_signature
= SIGNATURE_32 ('E', 'L', '6', '4');
387 gBS
->ExitBootServices (gImageHandle
, MapKey
);
392 LoadLinuxSetCommandLine (
393 IN OUT VOID
*KernelSetup
,
394 IN CHAR8
*CommandLine
398 struct boot_params
*Bp
;
400 Status
= BasicKernelSetupCheck (KernelSetup
);
401 if (EFI_ERROR (Status
)) {
405 Bp
= (struct boot_params
*)KernelSetup
;
407 Bp
->hdr
.cmd_line_ptr
= (UINT32
)(UINTN
)CommandLine
;
415 IN OUT VOID
*KernelSetup
,
421 struct boot_params
*Bp
;
423 Status
= BasicKernelSetupCheck (KernelSetup
);
424 if (EFI_ERROR (Status
)) {
428 Bp
= (struct boot_params
*)KernelSetup
;
430 Bp
->hdr
.ramdisk_start
= (UINT32
)(UINTN
)Initrd
;
431 Bp
->hdr
.ramdisk_len
= (UINT32
)InitrdSize
;
449 while (!(Mask
& 0x1)) {
466 SetupGraphicsFromGop (
467 struct screen_info
*Si
,
468 EFI_GRAPHICS_OUTPUT_PROTOCOL
*Gop
471 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
475 Status
= Gop
->QueryMode (Gop
, Gop
->Mode
->Mode
, &Size
, &Info
);
476 if (EFI_ERROR (Status
)) {
482 /* EFI framebuffer */
483 Si
->orig_video_isVGA
= 0x70;
487 Si
->orig_video_page
= 0;
488 Si
->orig_video_mode
= 0;
489 Si
->orig_video_cols
= 0;
490 Si
->orig_video_lines
= 0;
491 Si
->orig_video_ega_bx
= 0;
492 Si
->orig_video_points
= 0;
494 Si
->lfb_base
= (UINT32
)Gop
->Mode
->FrameBufferBase
;
495 Si
->lfb_size
= (UINT32
)Gop
->Mode
->FrameBufferSize
;
496 Si
->lfb_width
= (UINT16
)Info
->HorizontalResolution
;
497 Si
->lfb_height
= (UINT16
)Info
->VerticalResolution
;
502 if (Info
->PixelFormat
== PixelRedGreenBlueReserved8BitPerColor
) {
512 Si
->lfb_linelength
= (UINT16
)(Info
->PixelsPerScanLine
* 4);
513 } else if (Info
->PixelFormat
== PixelBlueGreenRedReserved8BitPerColor
) {
523 Si
->lfb_linelength
= (UINT16
)(Info
->PixelsPerScanLine
* 4);
524 } else if (Info
->PixelFormat
== PixelBitMask
) {
526 Info
->PixelInformation
.RedMask
,
531 Info
->PixelInformation
.GreenMask
,
536 Info
->PixelInformation
.BlueMask
,
541 Info
->PixelInformation
.ReservedMask
,
545 Si
->lfb_depth
= Si
->red_size
+ Si
->green_size
+
546 Si
->blue_size
+ Si
->rsvd_size
;
547 Si
->lfb_linelength
= (UINT16
)((Info
->PixelsPerScanLine
* Si
->lfb_depth
) / 8);
558 Si
->lfb_linelength
= Si
->lfb_width
/ 2;
567 IN OUT
struct boot_params
*Bp
571 EFI_HANDLE
*HandleBuffer
;
574 EFI_GRAPHICS_OUTPUT_PROTOCOL
*Gop
;
576 ZeroMem ((VOID
*)&Bp
->screen_info
, sizeof (Bp
->screen_info
));
578 Status
= gBS
->LocateHandleBuffer (
580 &gEfiGraphicsOutputProtocolGuid
,
585 if (!EFI_ERROR (Status
)) {
586 for (Index
= 0; Index
< HandleCount
; Index
++) {
587 Status
= gBS
->HandleProtocol (
589 &gEfiGraphicsOutputProtocolGuid
,
592 if (EFI_ERROR (Status
)) {
596 Status
= SetupGraphicsFromGop (&Bp
->screen_info
, Gop
);
597 if (!EFI_ERROR (Status
)) {
598 FreePool (HandleBuffer
);
603 FreePool (HandleBuffer
);
606 return EFI_NOT_FOUND
;
611 SetupLinuxBootParams (
612 IN OUT
struct boot_params
*Bp
617 SetupLinuxMemmap (Bp
);
626 IN OUT VOID
*KernelSetup
630 struct boot_params
*Bp
;
632 Status
= BasicKernelSetupCheck (KernelSetup
);
633 if (EFI_ERROR (Status
)) {
637 Bp
= (struct boot_params
*)KernelSetup
;
639 if ((Bp
->hdr
.version
< 0x205) || !Bp
->hdr
.relocatable_kernel
) {
641 // We only support relocatable kernels
643 return EFI_UNSUPPORTED
;
646 InitLinuxDescriptorTables ();
648 Bp
->hdr
.code32_start
= (UINT32
)(UINTN
)Kernel
;
649 if ((Bp
->hdr
.version
>= 0x20c) && Bp
->hdr
.handover_offset
&&
650 (Bp
->hdr
.xloadflags
& ((sizeof (UINTN
) == 4) ? BIT2
: BIT3
)))
652 DEBUG ((DEBUG_INFO
, "Jumping to kernel EFI handover point at ofs %x\n", Bp
->hdr
.handover_offset
));
654 DisableInterrupts ();
655 JumpToUefiKernel ((VOID
*)gImageHandle
, (VOID
*)gST
, KernelSetup
, Kernel
);
659 // Old kernels without EFI handover protocol
661 SetupLinuxBootParams (KernelSetup
);
663 DEBUG ((DEBUG_INFO
, "Jumping to kernel\n"));
664 DisableInterrupts ();
665 SetLinuxDescriptorTables ();
666 JumpToKernel (Kernel
, (VOID
*)KernelSetup
);