On Mon, 2012-10-22 at 10:45 +0100, Matt Fleming wrote: > On Sun, 2012-10-21 at 15:44 -0700, Jordan Justen wrote: > > This code is based on efilinux's bzimage support. > > git://git.kernel.org/pub/scm/boot/efilinux/efilinux.git > > > > Signed-off-by: Jordan Justen <jordan.l.jus...@intel.com> > > Cc: Matt Fleming <matt.flem...@intel.com> > > --- > > OvmfPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.S | 29 ++ > > OvmfPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.asm | 35 ++ > > OvmfPkg/Library/LoadLinuxLib/Linux.c | 487 > > ++++++++++++++++++++ > > OvmfPkg/Library/LoadLinuxLib/LinuxGdt.c | 200 ++++++++ > > OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.h | 56 +++ > > OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf | 50 ++ > > OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.S | 30 ++ > > OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.asm | 34 ++ > > OvmfPkg/OvmfPkgIa32.dsc | 1 + > > OvmfPkg/OvmfPkgIa32X64.dsc | 1 + > > OvmfPkg/OvmfPkgX64.dsc | 1 + > > 11 files changed, 924 insertions(+) > > create mode 100644 OvmfPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.S > > create mode 100644 OvmfPkg/Library/LoadLinuxLib/Ia32/JumpToKernel.asm > > create mode 100644 OvmfPkg/Library/LoadLinuxLib/Linux.c > > create mode 100644 OvmfPkg/Library/LoadLinuxLib/LinuxGdt.c > > create mode 100644 OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.h > > create mode 100644 OvmfPkg/Library/LoadLinuxLib/LoadLinuxLib.inf > > create mode 100644 OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.S > > create mode 100644 OvmfPkg/Library/LoadLinuxLib/X64/JumpToKernel.asm > > [...] > > > +VOID* > > +EFIAPI > > +LoadLinuxAllocateKernelSetupPages ( > > + IN UINTN Pages > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_PHYSICAL_ADDRESS Address; > > + > > + Address = 0xa0000; > > + Status = gBS->AllocatePages ( > > + AllocateMaxAddress, > > + EfiLoaderData, > > + Pages, > > + &Address > > + ); > > + if (EFI_ERROR (Status)) { > > + return NULL; > > + } > > + > > + return (VOID*)(UINTN) Address; > > +} > > It looks like you're using this function to allocate memory for the > "struct boot_params" that you pass to the kernel image. This memory > doesn't need to be allocated under 0xa0000, and in fact, it would > probably be better if it wasn't since there's very little memory there > anyway. > > But the memory you allocate for "struct boot_params" does need to be > below the 1GB mark, which is what efilinux commit 8947b2 that you > highlighted in the covering letter does - that commit doesn't affect the > memory allocation for the initrd (see comments below for initrd > allocation restrictions).
Whoops. Thanks for pointing this out. > > +VOID* > > +EFIAPI > > +LoadLinuxAllocateInitrdPages ( > > + IN UINTN Pages > > + ) > > +{ > > + EFI_STATUS Status; > > + EFI_PHYSICAL_ADDRESS Address; > > + > > + Address = BASE_1GB; > > + Status = gBS->AllocatePages ( > > + AllocateMaxAddress, > > + EfiLoaderData, > > + Pages, > > + &Address > > + ); > > + if (!EFI_ERROR (Status)) { > > + return (VOID*)(UINTN) Address; > > + } else { > > + return NULL; > > + } > > +} > > What you should actually be using to restrict the allocation of the > initrd is Bp->hdr.ramdisk_max, which may be much higher than 1GB. The > initrd is accessed pretty late in the boot procedure, way after "proper" > pagetables have been installed that lift the 1GB restriction. > > > + > > +STATIC > > +VOID > > +SetupLinuxMemmap ( > > + IN OUT struct boot_params *Bp > > + ) > > +{ > > + EFI_STATUS Status; > > + UINT8 TmpMemoryMap[1]; > > + UINTN MapKey; > > + UINTN DescriptorSize; > > + UINT32 DescriptorVersion; > > + UINTN MemoryMapSize; > > + EFI_MEMORY_DESCRIPTOR *MemoryMap; > > + EFI_MEMORY_DESCRIPTOR *MemoryMapPtr; > > + UINTN Index; > > + struct efi_info *Efi; > > + struct e820_entry *LastE820; > > [...] > > > + LastE820 = &Bp->e820_map[0]; > > [...] > > > + > > + if ((LastE820 != NULL) && > > + (LastE820->type == (UINT32) E820Type) && > > + (MemoryMap->PhysicalStart == LastEndAddr)) { > > + LastE820->size += EFI_PAGES_TO_SIZE (MemoryMap->NumberOfPages); > > Is the (LastE820 != NULL) expression ever false? I think it is set just below whenever a new E820 entry is modified. > > + } else { > > + if (E820EntryCount >= (sizeof (Bp->e820_map) / sizeof > > (Bp->e820_map[0]))) { > > + break; > > + } > > + E820->type = (UINT32) E820Type; > > + E820->addr = MemoryMap->PhysicalStart; > > + E820->size = EFI_PAGES_TO_SIZE (MemoryMap->NumberOfPages); > > + LastE820 = E820; > > + LastEndAddr = E820->addr + E820->size; > > + E820++; > > + E820EntryCount++; > > + } > > + > > + // > > + // Get next item > > + // > > + MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + > > DescriptorSize); > > + } > > + Bp->e820_entries = (UINT8) E820EntryCount; > > I think Laszlo has already mentioned that this code doesn't handle the > case where, even after merging adjacent entries of the same time, we > have more than 128 entries. I took Laszlo's comment to mean I wasn't checking if I overflowed the e820 entries. At least that should be handled in the 'if (...) break' code just above. > The efilinux code doesn't either but such > machines do exist. It's something that's been on my TODO list for a > while. You need to stuff the extra entries in a setup_data entry with > type SETUP_E280_EXT. I think I'll wait for you to add this, and then port it over. :) > > +EFI_STATUS > > +EFIAPI > > +LoadLinuxSetInitrd ( > > + IN OUT VOID *KernelSetup, > > + IN VOID *Initrd, > > + IN UINTN InitrdSize > > + ) > > +{ > > + struct boot_params *Bp; > > + > > + RETURN_STATUS_ON_ERROR (BasicKernelSetupCheck (KernelSetup)); > > + > > + Bp = (struct boot_params*) KernelSetup; > > + > > + Bp->hdr.ramdisk_start = (UINT32)(UINTN) Initrd; > > + Bp->hdr.ramdisk_len = (UINT32) InitrdSize; > > + Bp->hdr.ramdisk_max = Bp->hdr.ramdisk_start + Bp->hdr.ramdisk_len; > > 'ramdisk_max' is a read-only field. It tells you the maximum address at > which you can allocate memory to hold the initrd. The kernel doesn't > read it. Got it. > > +STATIC > > +EFI_STATUS > > +SetupLinuxBootParams ( > > + IN VOID *Kernel, > > + IN OUT struct boot_params *Bp > > + ) > > +{ > > + Bp->alt_mem_k = SIZE_32KB; > > This is a bit of legacy code and shouldn't be needed (it shouldn't be in > efilinux either). Will it possibly allow some older kernels to boot? Or, should I just toss it out? Thanks for the review Matt! -Jordan ------------------------------------------------------------------------------ Everyone hates slow websites. So do we. Make your web apps faster with AppDynamics Download AppDynamics Lite for free today: http://p.sf.net/sfu/appdyn_sfd2d_oct _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel