On Mon, Feb 6, 2012 at 21:58, Keshav P R <the.ridikulus....@gmail.com> wrote: > On Mon, Feb 6, 2012 at 21:23, Matthew Garrett <m...@redhat.com> wrote: >> We should attempt to load the kernel at its preferred address, and if we >> can't do that then we should at lesat align it correctly. When doing so >> we should also make sure to avoid putting the kernel on top of any regions >> being used by the firmware. >> --- >> >> I managed to screw up the rebase, so this is a fixed version. Also, the code >> now follows the old path if the kernel isn't relocatable - we can't move it, >> so better to try it and just hope that everything works out. >> >> ChangeLog | 8 +++++ >> grub-core/loader/i386/linux.c | 67 >> ++++++++++++++++++++++++++++++++++------ >> 2 files changed, 65 insertions(+), 10 deletions(-) >> >> diff --git a/ChangeLog b/ChangeLog >> index 33e5dda..aedf4bc 100644 >> --- a/ChangeLog >> +++ b/ChangeLog >> @@ -1,5 +1,13 @@ >> 2012-02-06 Matthew Garrett <m...@redhat.com> >> >> + * grub-core/loader/i386/linux.c (allocate_pages): Attempt to obtain >> + appropriately aligned memory if the desired target is unavailable >> + (grub_cmd_linux): Update to match newer Linux boot protocols, and >> + attempt to load the kernel at its preferred address rather than >> + hardcoding. >> + >> +2012-02-06 Matthew Garrett <m...@redhat.com> >> + >> * grub-core/lib/efi/relocator.c (grub_relocator_alloc_chunk_addr): >> Add argument to fail allocation when target address overlaps >> firmware regions. All users updated. >> diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c >> index 67a4533..3eb8fa0 100644 >> --- a/grub-core/loader/i386/linux.c >> +++ b/grub-core/loader/i386/linux.c >> @@ -183,13 +183,14 @@ free_pages (void) >> grub_relocator_unload (relocator); >> relocator = NULL; >> real_mode_mem = prot_mode_mem = initrd_mem = 0; >> - real_mode_target = prot_mode_target = initrd_mem_target = 0; >> + real_mode_target = initrd_mem_target = 0; >> } >> >> /* Allocate pages for the real mode code and the protected mode code >> for linux as well as a memory map buffer. */ >> static grub_err_t >> -allocate_pages (grub_size_t prot_size) >> +allocate_pages (grub_size_t prot_size, grub_size_t *align, >> + grub_size_t min_align, int relocatable) >> { >> grub_size_t real_size, mmap_size; >> grub_err_t err; >> @@ -269,18 +270,38 @@ allocate_pages (grub_size_t prot_size) >> + efi_mmap_size), 0); >> if (err) >> goto fail; >> + >> + grub_errno = GRUB_ERR_NONE; >> real_mode_mem = get_virtual_current_address (ch); >> } >> efi_mmap_buf = (grub_uint8_t *) real_mode_mem + real_size + mmap_size; >> >> - prot_mode_target = GRUB_LINUX_BZIMAGE_ADDR; >> - >> { >> grub_relocator_chunk_t ch; >> err = grub_relocator_alloc_chunk_addr (relocator, &ch, >> - prot_mode_target, prot_size, 0); >> + prot_mode_target, prot_size, >> + relocatable); >> + if (err) >> + { >> + unsigned int i; >> + for (i = *align; i >= min_align; i--) >> + { >> + err = grub_relocator_alloc_chunk_align (relocator, &ch, >> + 0x1000000, 0xffffffff, >> + prot_size, 1 << i, >> + >> GRUB_RELOCATOR_PREFERENCE_LOW); >> + if (!err) >> + { >> + *align = i; >> + prot_mode_target = get_physical_target_address (ch); >> + break; >> + } >> + } >> + } >> + >> if (err) >> goto fail; >> + >> prot_mode_mem = get_virtual_current_address (ch); >> } >> >> @@ -631,8 +652,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ >> ((unused)), >> struct linux_kernel_header lh; >> struct linux_kernel_params *params; >> grub_uint8_t setup_sects; >> - grub_size_t real_size, prot_size; >> + grub_size_t real_size, prot_size, prot_file_size, align = 0, min_align = >> 0; >> grub_ssize_t len; >> + int relocatable = 0; >> int i; >> >> grub_dl_ref (my_mod); >> @@ -705,9 +727,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ >> ((unused)), >> setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; >> >> real_size = setup_sects << GRUB_DISK_SECTOR_BITS; >> - prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE; >> >> - if (allocate_pages (prot_size)) >> + if (grub_le_to_cpu16 (lh.version) >= 0x205) >> + { >> + for (align = 0; align < 32; align++) >> + { >> + if (grub_le_to_cpu32 (lh.kernel_alignment) & (1 << align)) >> + break; >> + } >> + relocatable = grub_le_to_cpu32 (lh.relocatable); >> + } >> + >> + if (grub_le_to_cpu16 (lh.version) >= 0x020a) >> + { >> + min_align = lh.min_alignment; >> + prot_size = grub_le_to_cpu32 (lh.init_size); >> + prot_mode_target = grub_le_to_cpu64 (lh.pref_address); >> + } >> + else >> + { >> + min_align = 0; >> + prot_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE; >> + prot_mode_target = grub_le_to_cpu32 (lh.code32_start); >> + } >> + >> + prot_file_size = grub_file_size (file) - real_size - >> GRUB_DISK_SECTOR_SIZE; >> + if (allocate_pages (prot_size, &align, min_align, relocatable)) >> goto fail; >> >> params = (struct linux_kernel_params *) real_mode_mem; >> @@ -715,6 +760,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ >> ((unused)), >> grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); >> >> params->ps_mouse = params->padding10 = 0; >> + params->code32_start = prot_mode_target; >> + params->kernel_alignment = (1 << align); >> >> len = 0x400 - sizeof (lh); >> if (grub_file_read (file, (char *) real_mode_mem + sizeof (lh), len) != >> len) >> @@ -774,7 +821,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ >> ((unused)), >> grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); >> >> grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n", >> - (unsigned) real_size, (unsigned) prot_size); >> + (unsigned) real_size, (unsigned) prot_file_size); >> >> /* Look for memory size and video mode specified on the command line. */ >> linux_mem_size = 0; >> @@ -911,7 +958,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ >> ((unused)), >> maximal_cmdline_size >> - (sizeof (LINUX_IMAGE) - 1)); >> >> - len = prot_size; >> + len = prot_file_size; >> if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno) >> grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), >> argv[0]); >> -- >> 1.7.7.6 >> >> >> _______________________________________________ >> Grub-devel mailing list >> Grub-devel@gnu.org >> https://lists.gnu.org/mailman/listinfo/grub-devel > > Boot fine in VirtualBox X64 UEFI (UEFI 2.1 Tianocore OVMF). Patch V1 > 3/3 failed with premature end of file error. > > Regards. > > Keshav
Compile error for grub2-bios (i386-pc target) gcc -DHAVE_CONFIG_H -I. -I.. -Wall -W -I../include -I../include -DGRUB_MACHINE_PCBIOS=1 -DGRUB_MACHINE=I386_PC -DGRUB_TARGET_CPU_I386=1 -m32 -nostdinc -isystem /usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/include -DGRUB_FILE=\"loader/i386/pc/plan9.c\" -I. -I. -I.. -I.. -I../include -I../include -Os -Wall -W -Wshadow -Wpointer-arith -Wmissing-prototypes -Wundef -Wstrict-prototypes -g -falign-jumps=1 -falign-loops=1 -falign-functions=1 -mno-mmx -mno-sse -mno-sse2 -mno-3dnow -fno-dwarf2-cfi-asm -fno-asynchronous-unwind-tables -m32 -fno-stack-protector -mno-stack-arg-probe -Wno-trampolines -DUSE_ASCII_FAILBACK=1 -DHAVE_UNIFONT_WIDTHSPEC=1 -mrtd -mregparm=3 -ffreestanding -MT loader/i386/pc/plan9_module-plan9.o -MD -MP -MF loader/i386/pc/.deps-core/plan9_module-plan9.Tpo -c -o loader/i386/pc/plan9_module-plan9.o `test -f 'loader/i386/pc/plan9.c' || echo './'`loader/i386/pc/plan9.c loader/i386/pc/plan9.c: In function 'grub_cmd_plan9': loader/i386/pc/plan9.c:420:9: error: too few arguments to function 'grub_relocator_alloc_chunk_addr' ../include/grub/relocator.h:34:1: note: declared here loader/i386/pc/plan9.c:451:9: error: too few arguments to function 'grub_relocator_alloc_chunk_addr' ../include/grub/relocator.h:34:1: note: declared here make[3]: *** [loader/i386/pc/plan9_module-plan9.o] Error 1 with all the three V2 patches applied in order (didn't try V1). No error in x86_64-efi compile. - Keshav _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel