[U-Boot] [BeagleBone Black] Possible bug in U-Boot efi loader for BeagleBone Black

Heinrich Schuchardt xypron.glpk at gmx.de
Tue Dec 18 16:43:02 UTC 2018


On 12/18/18 2:04 PM, Dominik Adamski wrote:
> On 12/14/18 9:15 PM, Heinrich Schuchardt wrote:
>> On 12/14/18 3:58 PM, Dominik Adamski wrote:
>>> On 12/12/18 7:11 PM, Heinrich Schuchardt wrote:
>>>> On 12/12/18 3:02 PM, Dominik Adamski wrote:
>>>>> Hello,
>>>>> I think that I have found a bug in U-Boot UEFI implementation for
>>>>> BeagleBone Black board.
>>>>>
>>>>> I have tested U-Boot UEFI implementation for BeagleBone Black. I am
>>>>> able
>>>>> to load Linux successfully via GRUB bootloader with U-Boot
>>>>> v2018.09-rc2
>>>>> . U-Boot v2018.09-rc3 and above versions cause that the platform
>>>>> restarts over and over again. It starts booting, then it loads GRUB
>>>>> and
>>>>> when GRUB finishes its work an error occurs and the board restarts.
>>>>>
>>>>> I have looked through U-Boot repository and I have found the commit,
>>>>> which breaks booting. It's name is as follows: "efi_loader: update
>>>>> runtime services table crc32" (commit ID:
>>>>> a39f39cdd8be5cd3e7a8b696a463b621e3d827e0 ) . I have figured out, that
>>>>> when I comment out function call:
>>>>> efi_update_table_header_crc32(&efi_runtime_services.hdr); in function
>>>>> efi_runtime_detach then I am able to launch Linux successfully.
>>>>>
>>>>> My setup of U-Boot, GRUB and Linux was as follows:
>>>>> https://github.com/DominikAdamski/Beaglebone_GRUB_Manual . For U-Boot
>>>>> v2018.09 I get following log when booting:
>>>>>
>>>>> U-Boot 2018.09 (Dec 11 2018 - 11:11:16 +0100)
>>>>>
>>>>> CPU  : AM335X-GP rev 2.1
>>>>> Model: TI AM335x BeagleBone Black
>>>>> DRAM:  512 MiB
>>>>> NAND:  0 MiB
>>>>> MMC:   OMAP SD/MMC: 0, OMAP SD/MMC: 1
>>>>> Loading Environment from FAT... *** Warning - bad CRC, using default
>>>>> environment
>>>>>
>>>>> No USB device found
>>>>> <ethaddr> not set. Validating first E-fuse MAC
>>>>> Net:   eth0: ethernet at 4a100000
>>>>> Hit any key to stop autoboot:  2 ^H^H^H 1 ^H^H^H 0
>>>>> switch to partitions #0, OK
>>>>> mmc0 is current device
>>>>> SD/MMC found on device 0
>>>>> ** Unable to read file boot.scr **
>>>>> 85 bytes read in 1 ms (83 KiB/s)
>>>>> Loaded env from uEnv.txt
>>>>> Importing environment from mmc0 ...
>>>>> Running uenvcmd ...
>>>>> 403968 bytes read in 28 ms (13.8 MiB/s)
>>>>> ^[[18tScanning disks on usb...
>>>>> Disk usb0 not ready
>>>>> Disk usb1 not ready
>>>>> Disk usb2 not ready
>>>>> Disk usb3 not ready
>>>>> Scanning disks on mmc...
>>>>> MMC Device 2 not found
>>>>> MMC Device 3 not found
>>>>> Found 4 disks
>>>>> WARNING: booting without device tree
>>>>> ## Starting EFI application at 82000000 ...
>>>>> ^[[?25h^[[0;30;47mWelcome to GRUB!
>>>>> ^M
>>>>> ^M^[[0;37;40m^[[0;37;40m^[[0;37;40mEFI stub: Booting Linux Kernel...^M
>>>>> EFI stub: Using DTB from configuration table^M
>>>>> EFI stub: Exiting boot services and installing virtual address
>>>>> map...^M
>>>>> U-Boot EFI: Relocation at 9ff4a8a8 is out of range (2008214f)
>>>>> data abort
>>>>> pc : [<9ff4a7cc>]          lr : [<9ff4a8b9>]
>>>>> reloc pc : [<808007cc>]    lr : [<808008b9>]
>>>>> sp : 9df1ebac  ip : 00000020     fp : 00000000
>>>>> r10: 00001000  r9 : 9df29eb8     r8 : 00000028
>>>>> r7 : 9ff4aa10  r6 : 9ff4aec4     r5 : 00000003  r4 : 9ff4aa70
>>>>> r3 : 2002aac0  r2 : 00000050     r1 : 9ff4aa70  r0 : ffffffff
>>>>> Flags: NzCv  IRQs off  FIQs on  Mode SVC_32
>>>>> Code: 61204621 f876f000 bd106120 b5f04b36 (b31c681c)
>>>>> UEFI image [0x9ceb1000:0x9cf139ff] '/\grub.efi'
>>>>> UEFI image [0x94728000:0x9510bfff]
>>>>> Resetting CPU ...
>>>>>
>>>>> resetting ...
>>>>>
>>>>> Please let me know, if I should add more detailed logs.
>>>>>
>>>>> Dominik Adamski
>>>>>
>>>>>
>>>> Hello Dominik,
>>>>
>>>> you refer to an outdated release candidate v2018.09-rc2.
>>>>
>>>> The following patch is missing in the release candidate:
>>>>
>>>> commit 483dbab9f9318149e5ea97daacbfae320f53e35a
>>>> Author: Heinrich Schuchardt <xypron.glpk at gmx.de>
>>>> Date:   Sun Jul 29 09:49:03 2018 +0200
>>>>
>>>>       lib: crc32: mark function crc32() as __efi_runtime
>>>>
>>>> It is contained in the v2018.09 release. Please, update your page
>>>> https://github.com/DominikAdamski/Beaglebone_GRUB_Manual accordingly.
>>>>
>>>> The latest release is v2018.11. Release v2018.11 will require a recent
>>>> GRUB (later than patch d0c070179d4d). Or apply the following patch
>>>> http://git.denx.de/?p=u-boot.git;a=commit;h=f31239acff61f7def88a06eef1f091fce74ecd61
>>>>
>>>>
>>>> Revert "efi_loader: remove efi_exit_caches()"
>>>>
>>>> Best regards
>>>>
>>>> Heinrich
>>> Hello Heinrich,
>>>
>>> I am resending my mail, because I haven't noticed that I should answer
>>> below your response. I am also adding some more information just to be
>>> sure, that everything is clear.
>>>
>>> I have build the newest GRUB from master branch and I have checked out
>>> U-Boot with this patch:
>>>
>>> http://git.denx.de/?p=u-boot.git;a=commit;h=f31239acff61f7def88a06eef1f091fce74ecd61
>>>
>>>
>>> Revert "efi_loader: remove efi_exit_caches()"
>>>
>>> and I still get an error while Linux booting :
>>>
>>> EFI stub: Booting Linux Kernel...
>>> EFI stub: Using DTB from configuration table
>>> EFI stub: Exiting boot services and installing virtual address map...
>>> efi_runtime_relocate: Relocation at 9ff57a20 is out of range (20081092)
>>> data abort
>>> pc : [<9ff57944>]          lr : [<9ff57a31>]
>>> reloc pc : [<80800944>]    lr : [<80800a31>]
>>> sp : 9df2b594  ip : 1f757000     fp : 00000000
>>> r10: 00002000  r9 : 9df36eb8     r8 : 00000028
>>> r7 : 9ff57bc8  r6 : 9ff5807c     r5 : 00000003  r4 : 9ff57c28
>>> r3 : 20027c78  r2 : 00000050     r1 : 9ff57c28  r0 : ffffffff
>>> Flags: NzCv  IRQs off  FIQs on  Mode SVC_32
>>> Code: 46216120 f876f000 bd106120 4b36b5f0 (b31c681c)
>>> UEFI image [0x9cebf000:0x9cf21bff] '/\grub.efi'
>>> UEFI image [0x94732000:0x95115fff]
>>> Resetting CPU ...
>>>
>>> resetting ...
>>>
>>> I can boot Linux only when I remove line:
>>> efi_update_table_header_crc32(&efi_runtime_services.hdr); (file
>>> lib/efi_loader/efi_runtime.c line: 344 ) .
>>>
>>> In my manual I referred to version v2018.09-rc2 because it is the last
>>> tagged version which works fine on BeagleBone with GRUB. v2018.09
>>> version does not cooperate with GRUB for BB. It restarts BB over and
>>> over again. The problem is caused by this patch:
>>>
>>> commit a39f39cdd8be5cd3e7a8b696a463b621e3d827e0 (HEAD)
>>> Author: Heinrich Schuchardt <xypron.glpk at gmx.de>
>>> Date:   Sun Jul 29 09:49:04 2018 +0200
>>>
>>>      efi_loader: update runtime services table crc32
>>>
>>> This patch is a child of the patch, which you have mentioned:
>>>
>>> commit 483dbab9f9318149e5ea97daacbfae320f53e35a
>>> Author: Heinrich Schuchardt <xypron.glpk at gmx.de>
>>> Date:   Sun Jul 29 09:49:03 2018 +0200
>>>
>>>      lib: crc32: mark function crc32() as __efi_runtime
>>>
>>>
>>> The revert patch which you have mentioned:
>>> http://git.denx.de/?p=u-boot.git;a=commit;h=f31239acff61f7def88a06eef1f091fce74ecd61
>>>
>>> Revert "efi_loader: remove efi_exit_caches()" does not solve the
>>> problem. I can boot Linux only if I revert this patch:
>>>
>>> commit a39f39cdd8be5cd3e7a8b696a463b621e3d827e0 (HEAD)
>>> Author: Heinrich Schuchardt <xypron.glpk at gmx.de>
>>> Date:   Sun Jul 29 09:49:04 2018 +0200
>>>
>>>      efi_loader: update runtime services table crc32
>>>
>>> When I revert the wrong patch ( a39f39cdd8be5cd3e7a8b696a463b621e3d827e0
>>> ), then I can boot Linux with U-Boot sources younger than v2018.09-rc2 .
>>>
>>> Best regards,
>>> Dominik
>>>
>>>
>> Hello Dominik,
>>
>> the message
>> efi_runtime_relocate: Relocation at 9ff57a20 is out of range (20081092)
>> looks like a runtime function trying to call a non-runtime function.
>>
>> Actual addresses depend on compiler versions.
>>
>> Please, supply the following files to Alex and me for further analysis:
>>
>> .config
>> u-boot.map
>> u-boot
>> lib/crc32.o
>> lib/efi_loader/efi_runtime.o
>>
>> which match the U-Boot version you use together with the matching error
>> output. Please, also provide the output of the U-Boot command line tool
>> bdinfo.
>>
>> Do I understand you right in that the code you compiled is
>> commit f31239acff61f7def88a06eef1f091fce74ecd61 with no further patches
>> applied and the .config file is generated with am335x_evm_defconfig?
>>
>> Best regards
>>
>> Heinrich
> 
> Hello Heinrich,
> Yes, my code is commit f31239acff61f7def88a06eef1f091fce74ecd61 with no
> further patches applied and the .config file is generated with
> am335x_evm_defconfig .
> 
> Here is output of bdinfo command:
> 
> => bdinfo
> arch_number = 0x00000e05
> boot_params = 0x80000100
> DRAM bank   = 0x00000000
> -> start    = 0x80000000
> -> size     = 0x20000000
> baudrate    = 115200 bps
> TLB addr    = 0x9fff0000
> relocaddr   = 0x9ff57000
> reloc off   = 0x1f757000
> irq_sp      = 0x9df2bb00
> sp start    = 0x9df2baf0
> Early malloc usage: 1fc / 1000
> fdt_blob    = 0x9df2bb18
> =>
> 
> I attach logs from booting and other files which you have requested.
> 
> Please let me know if you don't receive binary files.
> 
> Best regards,
> Dominik
> 

Hello Dominik,

thanks for the files.

am335x_evm_defconfig is one of the boards with
CONFIG_DYNAMIC_CRC_TABLE=y.

Lets analyze the log:

efi_runtime_relocate: Relocation at 9ff57a20 is out of range (20081092)
data abort
pc : [<9ff57944>]          lr : [<9ff57a31>]
reloc pc : [<80800944>]    lr : [<80800a31>]

9ff57a20 - pc + reloc pc = 80800A20.

Looking at u-boot.map this is 0xE0 after the start of crc32_to_comp().

In `objdump -S arm-linux-gnueabihf-objdump -S crc32.o' we find these lines:

8080094a:       2601            movs    r6, #1
  for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
8080094c:       463d            mov     r5, r7
8080094e:       f8df c0d0       ldr.w   ip, [pc, #208]  ; 80800a20
<crc32_no_comp+0xe0>
    poly |= 1L << (31 - p[n]);
80800952:       f815 400c       ldrb.w  r4, [r5, ip]
80800956:       3501            adds    r5, #1

So the optimization in gcc has inlined function make_crc_table() as it
is only used once.

80800a20 holds the pointer to:
static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};

Please, observe that it is static but not marked as __efi_runtime_data.

By chance pointer p contains an odd address and we get a data abort.

I will send out a patch now. Could you, please, test it.

Thanks for your patience and support to analyze the problem.

Best regards

Heinrich


More information about the U-Boot mailing list