grub-devel
[Top][All Lists]
Advanced

[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
>

Attachment: relocator.log
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]