Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix "Try to pick better locations for kernel and initrd" causing boot to fail on some UEFI x86_64 systems #30

Closed

Conversation

jwrdegoede
Copy link
Contributor

The "Try to pick better locations for kernel and initrd" commit causes boot
to fail on some UEFI x86_64 systems (Sandy Bridge) with these errors:

grub-core/loader/i386/efi/linux.c:217:cannot allocate kernel parameters.
grub-core/loader/i386/efi/linux.c:94:you need to load the kernel first.

This commit fixes this by retrying the memory allocations changed by
the "Try to pick better locations for kernel and initrd" commit with
the old memory limit of 0x3fffffff.

BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1624525
Signed-off-by: Hans de Goede hdegoede@redhat.com

stbenjam and others added 8 commits August 27, 2018 13:16
This sets a couple of variables.  With the url http://www.example.com/foo/bar :
http_path: /foo/bar
http_url: http://www.example.com/foo/bar

Signed-off-by: Peter Jones <pjones@redhat.com>
The kernel in front of me (slightly edited to make objdump work) looks like:

00000000  4d 5a 10 13 4d 5a 10 13  4d 5a 10 13 4d 5a 10 13  |MZ..MZ..MZ..MZ..|
00000010  4d 5a 10 13 4d 5a 10 13  4d 5a 10 13 00 00 a0 e1  |MZ..MZ..MZ......|
00000020  f6 03 00 ea 18 28 6f 01  00 00 00 00 00 32 74 00  |.....(o......2t.|
00000030  01 02 03 04 45 45 45 45  74 a2 00 00 40 00 00 00  |....EEEEt...@...|
00000040  50 45 00 00 4c 01 04 00  00 00 00 00 00 00 00 00  |PE..L...........|
00000050  00 00 00 00 90 00 06 03  0b 01 02 14 00 20 74 00  |............. t.|
00000060  00 14 00 00 00 00 00 00  b4 19 00 00 00 10 00 00  |................|
00000070  00 30 74 00 00 00 00 00  00 10 00 00 00 02 00 00  |.0t.............|
00000080  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000090  00 44 74 00 00 10 00 00  00 00 00 00 0a 00 00 00  |.Dt.............|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000000b0  00 00 00 00 06 00 00 00  00 00 00 00 00 00 00 00  |................|
000000c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*

(I don't know why the MZ header is there 7 times, but the offsets work out, so
it's merely a surprising distraction.)

If linux_arm_kernel_header.reserved2 is 16 bytes, that means hdr_offset is
here:

00000030  01 02 03 04 45 45 45 45  74 a2 00 00 40 00 00 00  |....EEEEt...@...|
00000040  50 45 00 00 4c 01 04 00  00 00 00 00 00 00 00 00  |PE..L...........|
          ^^^^^^^^^^^

But it's supposed to be 4 bytes before that.

This patch makes the reserved field be 3*32 instead of 4*32, and that means we
can find the PE header correcrtly at 0x40 by reading the value at 0x3c.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Peter Jones <pjones@redhat.com>
On mustang, our memory map looks like:

Type      Physical start  - end             #Pages        Size Attributes
reserved  0000004000000000-00000040001fffff 00000200      2MiB UC WC WT WB
conv-mem  0000004000200000-0000004393ffffff 00393e00  14654MiB UC WC WT WB
ldr-code  0000004394000000-00000043f7ffffff 00064000   1600MiB UC WC WT WB
BS-data   00000043f8000000-00000043f801ffff 00000020    128KiB UC WC WT WB
conv-mem  00000043f8020000-00000043fa15bfff 0000213c  34032KiB UC WC WT WB
ldr-code  00000043fa15c000-00000043fa2a1fff 00000146   1304KiB UC WC WT WB
ldr-data  00000043fa2a2000-00000043fa3e8fff 00000147   1308KiB UC WC WT WB
conv-mem  00000043fa3e9000-00000043fa3e9fff 00000001      4KiB UC WC WT WB
ldr-data  00000043fa3ea000-00000043fa3eafff 00000001      4KiB UC WC WT WB
ldr-code  00000043fa3eb000-00000043fa4affff 000000c5    788KiB UC WC WT WB
BS-code   00000043fa4b0000-00000043fa59ffff 000000f0    960KiB UC WC WT WB
RT-code   00000043fa5a0000-00000043fa5affff 00000010     64KiB RT UC WC WT WB
RT-data   00000043fa5b0000-00000043fa5bffff 00000010     64KiB RT UC WC WT WB
RT-code   00000043fa5c0000-00000043fa5cffff 00000010     64KiB RT UC WC WT WB
ldr-data  00000043fa5d0000-00000043fa5d0fff 00000001      4KiB UC WC WT WB
BS-code   00000043fa5d1000-00000043fa5ddfff 0000000d     52KiB UC WC WT WB
reserved  00000043fa5de000-00000043fa60ffff 00000032    200KiB UC WC WT WB
ACPI-rec  00000043fa610000-00000043fa6affff 000000a0    640KiB UC WC WT WB
ACPI-nvs  00000043fa6b0000-00000043fa6bffff 00000010     64KiB UC WC WT WB
ACPI-rec  00000043fa6c0000-00000043fa70ffff 00000050    320KiB UC WC WT WB
RT-code   00000043fa710000-00000043fa72ffff 00000020    128KiB RT UC WC WT WB
RT-data   00000043fa730000-00000043fa78ffff 00000060    384KiB RT UC WC WT WB
RT-code   00000043fa790000-00000043fa79ffff 00000010     64KiB RT UC WC WT WB
RT-data   00000043fa7a0000-00000043fa99ffff 00000200      2MiB RT UC WC WT WB
RT-code   00000043fa9a0000-00000043fa9affff 00000010     64KiB RT UC WC WT WB
RT-data   00000043fa9b0000-00000043fa9cffff 00000020    128KiB RT UC WC WT WB
BS-code   00000043fa9d0000-00000043fa9d9fff 0000000a     40KiB UC WC WT WB
reserved  00000043fa9da000-00000043fa9dbfff 00000002      8KiB UC WC WT WB
conv-mem  00000043fa9dc000-00000043fc29dfff 000018c2  25352KiB UC WC WT WB
BS-data   00000043fc29e000-00000043fc78afff 000004ed   5044KiB UC WC WT WB
conv-mem  00000043fc78b000-00000043fca01fff 00000277   2524KiB UC WC WT WB
BS-data   00000043fca02000-00000043fcea3fff 000004a2   4744KiB UC WC WT WB
conv-mem  00000043fcea4000-00000043fcea4fff 00000001      4KiB UC WC WT WB
BS-data   00000043fcea5000-00000043fd192fff 000002ee   3000KiB UC WC WT WB
conv-mem  00000043fd193000-00000043fd2b0fff 0000011e   1144KiB UC WC WT WB
BS-data   00000043fd2b1000-00000043ff80ffff 0000255f  38268KiB UC WC WT WB
BS-code   00000043ff810000-00000043ff99ffff 00000190   1600KiB UC WC WT WB
RT-code   00000043ff9a0000-00000043ff9affff 00000010     64KiB RT UC WC WT WB
conv-mem  00000043ff9b0000-00000043ff9bffff 00000010     64KiB UC WC WT WB
RT-data   00000043ff9c0000-00000043ff9effff 00000030    192KiB RT UC WC WT WB
conv-mem  00000043ff9f0000-00000043ffa05fff 00000016     88KiB UC WC WT WB
BS-data   00000043ffa06000-00000043ffffffff 000005fa   6120KiB UC WC WT WB
MMIO      0000000010510000-0000000010510fff 00000001      4KiB RT
MMIO      0000000010548000-0000000010549fff 00000002      8KiB RT
MMIO      0000000017000000-0000000017001fff 00000002      8KiB RT
MMIO      000000001c025000-000000001c025fff 00000001      4KiB RT

When we're trying to find the base of ram, if we start with GRUB_UINT_MAX
(0xffffffff on all platforms) and always use min(), that means we eventually
decide that the base of ram is GRUB_UINT_MAX, which is lower than our first
memory address, and thus our allocation of the initramfs, which specifies this
value as the maximum possible address it can be at, fails.

This patch changes it to start at GRUB_EFI_MAX_USABLE_ADDRESS, which is always
at least 0xffffffff on 32-bit platforms and at least 0x7ffffffffffffff on
64-bit platforms.  Additionally, this adds a requirement that the memory we
choose is actually /allocatable/ conventional memory, not merely
write-combining.  On this machine that means we wind up with an allocation
around 0x4392XXXXXX, which is a reasonable address.

This also changes grub_efi_allocate_pages_real() so that if 0 is allocated, it
tries to allocate again starting with the same max address it did the first
time, rather than interposing GRUB_EFI_MAX_USABLE_ADDRESS there, so that any
per-platform constraints on its given address are maintained.

Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Peter Jones <pjones@redhat.com>
Don't limit allocations on 64-bit platforms to < 0x3fffffff; use
__UINTPTR_MAX__ or __INTPTR_MAX__.

Signed-off-by: Peter Jones <pjones@redhat.com>
… to fail on some UEFI x86_64 systems

The "Try to pick better locations for kernel and initrd" commit causes boot
to fail on some UEFI x86_64 systems (Sandy Bridge) with these errors:

grub-core/loader/i386/efi/linux.c:217:cannot allocate kernel parameters.
grub-core/loader/i386/efi/linux.c:94:you need to load the kernel first.

This commit fixes this by retrying the memory allocations changed by
the "Try to pick better locations for kernel and initrd" commit with
the old memory limit of 0x3fffffff.

BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1624525
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Copy link
Contributor

@martinezjavier martinezjavier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@amartinz
Copy link

amartinz commented Sep 8, 2018

Also causes failures on x399, but instead of falling back to the old way, my solution was to fix a comparison.

See the comment at the following commit:
6c2388e

@vathpela vathpela force-pushed the fedora-29 branch 4 times, most recently from b0ef23a to 1fd2c9c Compare September 11, 2018 21:58
@vathpela
Copy link
Contributor

vathpela commented Sep 12, 2018

So, there wound up being a couple more problems there, not least a significant number of machines in the field apparently can't read from disk/flash into addresses >4G. (I have not experimentally determined the actual address range.)

So while @amartinz and @jwrdegoede are both absolutely correct, currently we've got 1fd2c9c instead.

FWIW, the fedora package build is here: https://bodhi.fedoraproject.org/updates/FEDORA-2018-2756e3a374 .

If there are no objections, I'm going to close this PR soon. Thanks!

@vathpela vathpela closed this Sep 24, 2018
egservice pushed a commit to vulturm/macbook-grub2 that referenced this pull request Feb 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants