[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Fwd: [PATCH] Unable to boot very old Linux kernels
From: |
Piotras |
Subject: |
Fwd: [PATCH] Unable to boot very old Linux kernels |
Date: |
Sun, 23 Mar 2014 23:16:56 +0000 |
Scratch that.
With GRUB_RELOCATOR_PREFERENCE_HIGH, Global Descriptor Table is
located just before 0xa0000 like we want. I'll test it on live machine
before sending updated patch.
Sorry for confusion,
Piotr
---------- Forwarded message ----------
From: Piotras <address@hidden>
Date: Sun, Mar 23, 2014 at 10:50 PM
Subject: Re: [PATCH] Unable to boot very old Linux kernels
To: The development of GNU GRUB <address@hidden>
Hi,
Tested suggested parameters under Qemu, so calling
grub_relocator_alloc_chunk_align with following:
max_addr = (0xa0000 - RELOCATOR_SIZEOF (32)) + 1
preference = GRUB_RELOCATOR_PREFERENCE_LOW
This fails to allocate from low memory and falls back to top of
physical memory, ignoring preference. Relevant part of debug log for
relocator (full log included as attachment):
lib/relocator.c:434: trying to allocate in 0x1000-0x9ff31 aligned
0x10 size 0xd0
lib/relocator.c:1411: Adjusted limits from 1000-9ff31 to 0-100000
lib/relocator.c:434: trying to allocate in 0x0-0x100000 aligned 0x10 size 0xd0
lib/relocator.c:434: trying to allocate in 0x2a9000-0xffffffff
aligned 0x1 size 0xd0
lib/relocator.c:1186: allocated: 0x3fff7c20+0xd0
See malloc_in_range calls in grub_relocator_alloc_chunk_align to see
why preference is ignored after first failure. Looking at
malloc_in_range, I don't see any events to explain why allocation in
range 0x1000..0x9ff31 fails. I can try to debug this later this week.
Regards,
Piotr
My code for reference:
diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c
index d2a1b27..e9ab529 100644
--- a/grub-core/lib/i386/relocator.c
+++ b/grub-core/lib/i386/relocator.c
@@ -82,9 +82,9 @@ grub_relocator32_boot (struct grub_relocator *rel,
grub_relocator_chunk_t ch;
err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
- (0xffffffff - RELOCATOR_SIZEOF (32))
+ (0xa0000 - RELOCATOR_SIZEOF (32))
+ 1, RELOCATOR_SIZEOF (32), 16,
- GRUB_RELOCATOR_PREFERENCE_NONE,
+ GRUB_RELOCATOR_PREFERENCE_LOW,
avoid_efi_bootservices);
if (err)
return err;
On Sun, Mar 23, 2014 at 7:09 PM, Vladimir 'φ-coder/phcoder' Serbinenko
<address@hidden> wrote:
> On 17.03.2014 23:15, Piotr Krysiuk wrote:
>> Hi,
>>
>> I occasionally need to boot a very old Linux kernel.
>>
>> This works fine with old versions of GRUB, from before relocator was
>> introduced. However the kernel cannot be started by recent versions
>> of GRUB - machine simply restarts as soon as GRUB passes control to
>> Linux. As mentioned above this affects very old Linux only, so very
>> few users (if any) would care. But as I have a patch, here it is.
>>
>> I tracked the issues to code initializing BSS that is used by old
>> Linux kernels. See code following "Clear BSS" on
>> https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/arch/x86_64/boot/compressed/head.S?h=linux-2.6.17.y#n57
>>
>> AFAIK old Linux kernels do not provide information allowing boot
>> loader to determine end of BSS. As the consequence, current GRUB
>> may place GPT in the area overlapping with BSS sections of old
>> Linux kernels. The location of GPT was changed at the same time
>> when relocator was added, introducing regression.
>>
> Top of memory doesn't sound like a right place. Could you try with
>
>> err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
>> (0xa0000 - RELOCATOR_SIZEOF (32)),
>> ...
> This will put GDT in low memory
>
>> In order to improve compatibility with these old kernels, we could
>> switch back to old strategy and simply place GPT close to end of
>> physical memory.
>>
>> Best regards,
>>
>> Piotr Krysiuk
>> ---
>> ChangeLog | 5 +++++
>> grub-core/lib/i386/relocator.c | 2 +-
>> 2 files changed, 6 insertions(+), 1 deletion(-)
>>
>> diff --git a/ChangeLog b/ChangeLog
>> index 770269c..5a91e5e 100644
>> --- a/ChangeLog
>> +++ b/ChangeLog
>> @@ -1,3 +1,8 @@
>> +2014-03-17 Piotr Krysiuk <address@hidden>
>> +
>> + * grub-core/lib/i386/relocator.c: Moved GDT to end of physical memory
>> + to avoid collision with old Linux BSS.
>> +
>> 2014-02-28 Vladimir Serbinenko <address@hidden>
>>
>> * include/grub/i386/openbsd_bootarg.h: Add addr and frequency fields.
>> diff --git a/grub-core/lib/i386/relocator.c b/grub-core/lib/i386/relocator.c
>> index d2a1b27..523f669 100644
>> --- a/grub-core/lib/i386/relocator.c
>> +++ b/grub-core/lib/i386/relocator.c
>> @@ -84,7 +84,7 @@ grub_relocator32_boot (struct grub_relocator *rel,
>> err = grub_relocator_alloc_chunk_align (rel, &ch, 0,
>> (0xffffffff - RELOCATOR_SIZEOF (32))
>> + 1, RELOCATOR_SIZEOF (32), 16,
>> - GRUB_RELOCATOR_PREFERENCE_NONE,
>> + GRUB_RELOCATOR_PREFERENCE_HIGH,
>> avoid_efi_bootservices);
>> if (err)
>> return err;
>>
>
>
>
> _______________________________________________
> Grub-devel mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/grub-devel
>
relocator.log
Description: Text Data