3 Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
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 "LoadLinuxLib.h"
19 A simple check of the kernel setup image
21 An assumption is made that the size of the data is at least the
22 size of struct boot_params.
24 @param[in] KernelSetup - The kernel setup image
26 @retval EFI_SUCCESS - The kernel setup looks valid and supported
27 @retval EFI_INVALID_PARAMETER - KernelSetup was NULL
28 @retval EFI_UNSUPPORTED - The kernel setup is not valid or supported
34 BasicKernelSetupCheck (
38 return LoadLinuxCheckKernelSetup(KernelSetup
, sizeof (struct boot_params
));
44 LoadLinuxCheckKernelSetup (
46 IN UINTN KernelSetupSize
49 struct boot_params
*Bp
;
51 if (KernelSetup
== NULL
) {
52 return EFI_INVALID_PARAMETER
;
55 if (KernelSetupSize
< sizeof (*Bp
)) {
56 return EFI_UNSUPPORTED
;
59 Bp
= (struct boot_params
*) KernelSetup
;
61 if ((Bp
->hdr
.signature
!= 0xAA55) || // Check boot sector signature
62 (Bp
->hdr
.header
!= SETUP_HDR
) ||
63 (Bp
->hdr
.version
< 0x205) // We only support relocatable kernels
65 return EFI_UNSUPPORTED
;
74 LoadLinuxGetKernelSize (
79 struct boot_params
*Bp
;
81 if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup
))) {
85 Bp
= (struct boot_params
*) KernelSetup
;
87 if (Bp
->hdr
.version
> 0x20a) {
88 return Bp
->hdr
.init_size
;
91 // Add extra size for kernel decompression
93 return 3 * KernelSize
;
100 LoadLinuxAllocateKernelSetupPages (
105 EFI_PHYSICAL_ADDRESS Address
;
108 Status
= gBS
->AllocatePages (
114 if (!EFI_ERROR (Status
)) {
115 return (VOID
*)(UINTN
) Address
;
124 LoadLinuxAllocateKernelPages (
125 IN VOID
*KernelSetup
,
130 EFI_PHYSICAL_ADDRESS KernelAddress
;
132 struct boot_params
*Bp
;
134 if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup
))) {
138 Bp
= (struct boot_params
*) KernelSetup
;
140 for (Loop
= 1; Loop
< 512; Loop
++) {
141 KernelAddress
= MultU64x32 (
142 2 * Bp
->hdr
.kernel_alignment
,
145 Status
= gBS
->AllocatePages (
151 if (!EFI_ERROR (Status
)) {
152 return (VOID
*)(UINTN
) KernelAddress
;
162 LoadLinuxAllocateCommandLinePages (
167 EFI_PHYSICAL_ADDRESS Address
;
170 Status
= gBS
->AllocatePages (
176 if (!EFI_ERROR (Status
)) {
177 return (VOID
*)(UINTN
) Address
;
186 LoadLinuxAllocateInitrdPages (
187 IN VOID
*KernelSetup
,
192 EFI_PHYSICAL_ADDRESS Address
;
194 struct boot_params
*Bp
;
196 if (EFI_ERROR (BasicKernelSetupCheck (KernelSetup
))) {
200 Bp
= (struct boot_params
*) KernelSetup
;
202 Address
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Bp
->hdr
.ramdisk_max
;
203 Status
= gBS
->AllocatePages (
209 if (!EFI_ERROR (Status
)) {
210 return (VOID
*)(UINTN
) Address
;
220 IN OUT
struct boot_params
*Bp
224 UINT8 TmpMemoryMap
[1];
226 UINTN DescriptorSize
;
227 UINT32 DescriptorVersion
;
229 EFI_MEMORY_DESCRIPTOR
*MemoryMap
;
230 EFI_MEMORY_DESCRIPTOR
*MemoryMapPtr
;
232 struct efi_info
*Efi
;
233 struct e820_entry
*LastE820
;
234 struct e820_entry
*E820
;
235 UINTN E820EntryCount
;
236 EFI_PHYSICAL_ADDRESS LastEndAddr
;
239 // Get System MemoryMapSize
241 MemoryMapSize
= sizeof (TmpMemoryMap
);
242 Status
= gBS
->GetMemoryMap (
244 (EFI_MEMORY_DESCRIPTOR
*)TmpMemoryMap
,
249 ASSERT (Status
== EFI_BUFFER_TOO_SMALL
);
251 // Enlarge space here, because we will allocate pool now.
253 MemoryMapSize
+= EFI_PAGE_SIZE
;
254 MemoryMap
= AllocatePool (MemoryMapSize
);
255 ASSERT (MemoryMap
!= NULL
);
258 // Get System MemoryMap
260 Status
= gBS
->GetMemoryMap (
267 ASSERT_EFI_ERROR (Status
);
270 E820
= &Bp
->e820_map
[0];
273 MemoryMapPtr
= MemoryMap
;
274 for (Index
= 0; Index
< (MemoryMapSize
/ DescriptorSize
); Index
++) {
277 if (MemoryMap
->NumberOfPages
== 0) {
281 switch(MemoryMap
->Type
) {
282 case EfiReservedMemoryType
:
283 case EfiRuntimeServicesCode
:
284 case EfiRuntimeServicesData
:
285 case EfiMemoryMappedIO
:
286 case EfiMemoryMappedIOPortSpace
:
288 E820Type
= E820_RESERVED
;
291 case EfiUnusableMemory
:
292 E820Type
= E820_UNUSABLE
;
295 case EfiACPIReclaimMemory
:
296 E820Type
= E820_ACPI
;
301 case EfiBootServicesCode
:
302 case EfiBootServicesData
:
303 case EfiConventionalMemory
:
307 case EfiACPIMemoryNVS
:
314 "Invalid EFI memory descriptor type (0x%x)!\n",
320 if ((LastE820
!= NULL
) &&
321 (LastE820
->type
== (UINT32
) E820Type
) &&
322 (MemoryMap
->PhysicalStart
== LastEndAddr
)) {
323 LastE820
->size
+= EFI_PAGES_TO_SIZE (MemoryMap
->NumberOfPages
);
324 LastEndAddr
+= EFI_PAGES_TO_SIZE (MemoryMap
->NumberOfPages
);
326 if (E820EntryCount
>= (sizeof (Bp
->e820_map
) / sizeof (Bp
->e820_map
[0]))) {
329 E820
->type
= (UINT32
) E820Type
;
330 E820
->addr
= MemoryMap
->PhysicalStart
;
331 E820
->size
= EFI_PAGES_TO_SIZE (MemoryMap
->NumberOfPages
);
333 LastEndAddr
= E820
->addr
+ E820
->size
;
341 MemoryMap
= (EFI_MEMORY_DESCRIPTOR
*)((UINTN
)MemoryMap
+ DescriptorSize
);
343 Bp
->e820_entries
= (UINT8
) E820EntryCount
;
346 Efi
->efi_systab
= (UINT32
)(UINTN
) gST
;
347 Efi
->efi_memdesc_size
= (UINT32
) DescriptorSize
;
348 Efi
->efi_memdesc_version
= DescriptorVersion
;
349 Efi
->efi_memmap
= (UINT32
)(UINTN
) MemoryMapPtr
;
350 Efi
->efi_memmap_size
= (UINT32
) MemoryMapSize
;
352 Efi
->efi_loader_signature
= SIGNATURE_32 ('E', 'L', '3', '2');
354 Efi
->efi_systab_hi
= ((UINT64
)(UINTN
) gST
) >> 32;
355 Efi
->efi_memmap_hi
= ((UINT64
)(UINTN
) MemoryMapPtr
) >> 32;
356 Efi
->efi_loader_signature
= SIGNATURE_32 ('E', 'L', '6', '4');
359 gBS
->ExitBootServices (gImageHandle
, MapKey
);
365 LoadLinuxSetCommandLine (
366 IN OUT VOID
*KernelSetup
,
367 IN CHAR8
*CommandLine
371 struct boot_params
*Bp
;
373 Status
= BasicKernelSetupCheck (KernelSetup
);
374 if (EFI_ERROR (Status
)) {
378 Bp
= (struct boot_params
*) KernelSetup
;
380 Bp
->hdr
.cmd_line_ptr
= (UINT32
)(UINTN
) CommandLine
;
389 IN OUT VOID
*KernelSetup
,
395 struct boot_params
*Bp
;
397 Status
= BasicKernelSetupCheck (KernelSetup
);
398 if (EFI_ERROR (Status
)) {
402 Bp
= (struct boot_params
*) KernelSetup
;
404 Bp
->hdr
.ramdisk_start
= (UINT32
)(UINTN
) Initrd
;
405 Bp
->hdr
.ramdisk_len
= (UINT32
) InitrdSize
;
424 while (!(Mask
& 0x1)) {
441 SetupGraphicsFromGop (
442 struct screen_info
*Si
,
443 EFI_GRAPHICS_OUTPUT_PROTOCOL
*Gop
446 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION
*Info
;
450 Status
= Gop
->QueryMode(Gop
, Gop
->Mode
->Mode
, &Size
, &Info
);
451 if (EFI_ERROR (Status
)) {
457 /* EFI framebuffer */
458 Si
->orig_video_isVGA
= 0x70;
462 Si
->orig_video_page
= 0;
463 Si
->orig_video_mode
= 0;
464 Si
->orig_video_cols
= 0;
465 Si
->orig_video_lines
= 0;
466 Si
->orig_video_ega_bx
= 0;
467 Si
->orig_video_points
= 0;
469 Si
->lfb_base
= (UINT32
) Gop
->Mode
->FrameBufferBase
;
470 Si
->lfb_size
= (UINT32
) Gop
->Mode
->FrameBufferSize
;
471 Si
->lfb_width
= (UINT16
) Info
->HorizontalResolution
;
472 Si
->lfb_height
= (UINT16
) Info
->VerticalResolution
;
477 if (Info
->PixelFormat
== PixelRedGreenBlueReserved8BitPerColor
) {
487 Si
->lfb_linelength
= (UINT16
) (Info
->PixelsPerScanLine
* 4);
489 } else if (Info
->PixelFormat
== PixelBlueGreenRedReserved8BitPerColor
) {
499 Si
->lfb_linelength
= (UINT16
) (Info
->PixelsPerScanLine
* 4);
500 } else if (Info
->PixelFormat
== PixelBitMask
) {
501 FindBits(Info
->PixelInformation
.RedMask
,
502 &Si
->red_pos
, &Si
->red_size
);
503 FindBits(Info
->PixelInformation
.GreenMask
,
504 &Si
->green_pos
, &Si
->green_size
);
505 FindBits(Info
->PixelInformation
.BlueMask
,
506 &Si
->blue_pos
, &Si
->blue_size
);
507 FindBits(Info
->PixelInformation
.ReservedMask
,
508 &Si
->rsvd_pos
, &Si
->rsvd_size
);
509 Si
->lfb_depth
= Si
->red_size
+ Si
->green_size
+
510 Si
->blue_size
+ Si
->rsvd_size
;
511 Si
->lfb_linelength
= (UINT16
) ((Info
->PixelsPerScanLine
* Si
->lfb_depth
) / 8);
522 Si
->lfb_linelength
= Si
->lfb_width
/ 2;
532 IN OUT
struct boot_params
*Bp
536 EFI_HANDLE
*HandleBuffer
;
539 EFI_GRAPHICS_OUTPUT_PROTOCOL
*Gop
;
541 ZeroMem ((VOID
*)&Bp
->screen_info
, sizeof(Bp
->screen_info
));
543 Status
= gBS
->LocateHandleBuffer (
545 &gEfiGraphicsOutputProtocolGuid
,
550 if (!EFI_ERROR (Status
)) {
551 for (Index
= 0; Index
< HandleCount
; Index
++) {
552 Status
= gBS
->HandleProtocol (
554 &gEfiGraphicsOutputProtocolGuid
,
557 if (EFI_ERROR (Status
)) {
561 Status
= SetupGraphicsFromGop (&Bp
->screen_info
, Gop
);
562 if (!EFI_ERROR (Status
)) {
563 FreePool (HandleBuffer
);
568 FreePool (HandleBuffer
);
571 return EFI_NOT_FOUND
;
577 SetupLinuxBootParams (
579 IN OUT
struct boot_params
*Bp
584 Bp
->hdr
.code32_start
= (UINT32
)(UINTN
) Kernel
;
586 SetupLinuxMemmap (Bp
);
596 IN OUT VOID
*KernelSetup
600 struct boot_params
*Bp
;
602 Status
= BasicKernelSetupCheck (KernelSetup
);
603 if (EFI_ERROR (Status
)) {
607 Bp
= (struct boot_params
*) KernelSetup
;
609 if (Bp
->hdr
.version
< 0x205) {
611 // We only support relocatable kernels
613 return EFI_UNSUPPORTED
;
616 InitLinuxDescriptorTables ();
618 SetupLinuxBootParams (Kernel
, (struct boot_params
*) KernelSetup
);
620 DEBUG ((EFI_D_INFO
, "Jumping to kernel\n"));
621 DisableInterrupts ();
622 SetLinuxDescriptorTables ();
623 JumpToKernel (Kernel
, (VOID
*) KernelSetup
);