[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH V2 3/3] Update Linux loader to follow the kernel's preference
From: |
Keshav P R |
Subject: |
Re: [PATCH V2 3/3] Update Linux loader to follow the kernel's preferences |
Date: |
Mon, 6 Feb 2012 22:00:30 +0530 |
On Mon, Feb 6, 2012 at 21:58, Keshav P R <address@hidden> wrote:
> On Mon, Feb 6, 2012 at 21:23, Matthew Garrett <address@hidden> 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 <address@hidden>
>>
>> + * 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 <address@hidden>
>> +
>> * 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
>> address@hidden
>> 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
- [PATCH V2 1/3] Update the Linux boot protocol, Matthew Garrett, 2012/02/06
- [PATCH V2 2/3] Add support for avoiding firmware in relocations, Matthew Garrett, 2012/02/06
- [PATCH V2 3/3] Update Linux loader to follow the kernel's preferences, Matthew Garrett, 2012/02/06
- Re: [PATCH V2 3/3] Update Linux loader to follow the kernel's preferences, Keshav P R, 2012/02/06
- Re: [PATCH V2 3/3] Update Linux loader to follow the kernel's preferences,
Keshav P R <=
- Re: [PATCH V2 3/3] Update Linux loader to follow the kernel's preferences, Matthew Garrett, 2012/02/06
- Re: [PATCH V2 3/3] Update Linux loader to follow the kernel's preferences, Keshav P R, 2012/02/06
- Re: [PATCH V2 3/3] Update Linux loader to follow the kernel's preferences, Keshav P R, 2012/02/06
- Re: [PATCH V2 3/3] Update Linux loader to follow the kernel's preferences, Keshav P R, 2012/02/08
- Re: [PATCH V2 3/3] Update Linux loader to follow the kernel's preferences, Keshav P R, 2012/02/08