[U-Boot] [BUG] Crash when starting grub-arm.efi on BeagleBone Black

On 3/7/19 12:05 PM, Adam Podogrocki wrote:
Hello Heinrich,
I've checked U-Boot behaviour in following setups:
1. U-Boot v2018.09/v2018.11 and GRUB commit 72e80c025 (used by us in other setups) 2. U-Boot v2019.01 and GRUB commit 72e80c025 (used by us in other setups) 3. U-Boot v2019.01 and GRUB latest commit 9223eff8f
These are not commit numbers from git://git.savannah.gnu.org/grub.git So to which repository do they relate?
On Google drive you supplied to me GRUB 35b909062. This is also not a valid commit number.
First I tried to find the location of the crash that you reported:
$ hexedit grub-arm.efi # GRUB 35b909062
000060D4 33 7B 31 68 03 F0 0F 02 4F EA 13 1B 02 9B 5F 18 000060E4 2F 44 04 2A 78 D8 DF E8 02 F0 03 03 43 6A 75 00 000060F4 F0 89 11 B3 08 BB 79 1E 11 F8 01 2F 6A B9 40 F2 00006104 FD 11 00 EB 50 10 FB F7 F8 FC 60 4B 03 EB 81 01 ^^^^^^^^^^^
I analyzed the file with the tool available at https://github.com/xypron/efi_analyzer
$ efianalyze grub-arm.efi # GRUB 35b909062
Offset to PE = 80 Machine type: 0x01c2, ARM or Thumb ("interworking") Characteristics 0x30e Image type: PE32 EFI application ImageBase=0x0 SectionAlignment=0x1000 SizeOfImage=0x55000 .reloc.address=0x54000 .reloc.size=0x1000 BaseOfCode=0x1000 AddressOfEntryPoint=0x1000 Number of Sections 4 Section[0] .text Virtual size 0x8000 Virtual address 0x1000 Size of raw data 0x8000 Pointer to raw data 0x1000 End of raw data 0x9000 Section[1] .data Virtual size 0xb000 Virtual address 0x9000 Size of raw data 0xb000 Pointer to raw data 0x9000 End of raw data 0x14000 Section[2] mods Virtual size 0x40000 Virtual address 0x14000 Size of raw data 0x40000 Pointer to raw data 0x14000 End of raw data 0x54000 Section[3] .reloc Virtual size 0x1000 Virtual address 0x54000 Size of raw data 0x1000 Pointer to raw data 0x54000 End of raw data 0x55000
So the entry-point is 0x1000 and the virtual address 0x1000 matches the position in the file. That makes things easy.
$ /usr/bin/arm-linux-gnueabihf-objdump -D -b binary -marm grub-arm.efi
1000: e59fc010 ldr ip, [pc, #16] ; 0x1018 1004: e58c0000 str r0, [ip] 1008: e59fc00c ldr ip, [pc, #12] ; 0x101c 100c: e58c1000 str r1, [ip] 1010: e59fc008 ldr ip, [pc, #8] ; 0x1020 1014: e12fff1c bx ip 1018: 0000c914 andeq ip, r0, r4, lsl r9 101c: 0000c910 andeq ip, r0, r0, lsl r9 1020: 0000610d andeq r6, r0, sp, lsl #2
This matches function _start() in grub-core/kern/arm/efi/startup.S:
ldr ip, =EXT_C(grub_efi_image_handle) str r0, [ip] ldr ip, =EXT_C(grub_efi_system_table) str r1, [ip] ldr ip, =EXT_C(grub_main) bx ip END
So here we first store the image handle and the system table. Then we branch to 610C in thumb mode (bit 0 is set in the address).
The entry point is called in U-Boot via
0x47f8765c <efi_start_image+100> ldr r0, [sp, #4]
0x47f87660 <efi_start_image+104> blx r3
So we have first a blx jump to ARM and then a bx jump to THUMB.
TODO for me:
According to http://infocenter.arm.com/help/topic/com.arm.doc.uan0002a/UAN002A_1176-pan_u... depending on the alignment of the blx command this sequence of commands may fail on some ARM11 processors.
But the BeagleBone Black has an ARMv7-A and not an ARM11 processor. So nothing to worry us.
The further disassembly depends on the start address:
/usr/bin/arm-linux-gnueabihf-objdump -D -b binary -marm \ --disassembler-options=force-thumb grub-arm.efi --start-addr=0x6100
00006100 <.data+0x6100>: 6100: b96a cbnz r2, 0x611e 6102: f240 11fd movw r1, #509 ; 0x1fd 6106: eb00 1050 add.w r0, r0, r0, lsr #5 610a: f7fb fcf8 bl 0x1afe 610e: 4b60 ldr r3, [pc, #384] ; (0x6290) 6110: eb03 0181 add.w r1, r3, r1, lsl #2 6114: 684a ldr r2, [r1, #4] 6116: b942 cbnz r2, 0x612a
/usr/bin/arm-linux-gnueabihf-objdump -D -b binary -marm \ --disassembler-options=force-thumb grub-arm.efi --start-addr=0x610c
0000610c <.data+0x610c>: 610c: fcf8 4b60 ldc2l 11, cr4, [r8], #384 ; 0x180 ; <UNPREDICTABLE> 6110: eb03 0181 add.w r1, r3, r1, lsl #2 6114: 684a ldr r2, [r1, #4] 6116: b942 cbnz r2, 0x612a 6118: 463a mov r2, r7 611a: 495e ldr r1, [pc, #376] ; (0x6294)
So the next instruction after branching is `ldc2l 11, cr4, [r8], #384`.
Next I put your grub_arm.efi into directory tftp/ and started U-Boot qemu_arm_defconfig with:
qemu-system-arm -machine virt -cpu cortex-a15 \ -bios u-boot.bin -nographic -gdb tcp::1234 -netdev \ user,id=eth0,tftp=tftp,net=192.168.76.0/24,dhcpstart=192.168.76.9 \ -device e1000,netdev=eth0
I displayed the relocation offset with command bdinfo:
=> bdinfo arch_number = 0x00000000 boot_params = 0x00000000 DRAM bank = 0x00000000 -> start = 0x40000000 -> size = 0x08000000 baudrate = 115200 bps TLB addr = 0x47ff0000 relocaddr = 0x47f4f000 <<<<<< You need this address reloc off = 0x47f4f000 irq_sp = 0x46e0dec0 sp start = 0x46e0deb0 Early malloc usage: 11c / 400 fdt_blob = 0x46e0ded8
In a separate mode I opened GDB:
gdb-multiarch u-boot -ex 'target remote localhost:1234'
(gdb) add-symbol-file u-boot 0x47f4f000 add symbol table from file "u-boot" at .text_addr = 0x47f4f000 (y or n) y Reading symbols from u-boot...done. (gdb) b efi_start_image Breakpoint 1 at 0x385f8: efi_start_image. (2 locations) (gdb) c Continuing
When debugging the ldc2l instruction at 610c caused the same error that you already observed:
=> bootefi $kernel_addr_r $fdtcontroladdr Found 0 disks ## Starting EFI application at 40400000 ... undefined instruction pc : [<45cb610a>] lr : [<47f87664>] reloc pc : [<fdd6710a>] lr : [<00038664>] sp : 46e0dc28 ip : 45cb610d fp : 47f6a324 r10: 00000003 r9 : 00000000 r8 : 46f11080 r7 : 40400000 r6 : 45e0c040 r5 : 00000000 r4 : 47f4f7c8 r3 : 45cb1000 r2 : 00000000 r1 : 47f4f7c8 r0 : 46f18010 Flags: nZCv IRQs off FIQs off Mode SVC_32 Code: 1e79bb08 2f01f811 f240b96a eb0011fd (f7fb1050) UEFI image [0x45cb0000:0x45d04fff] pc=0x610a '/grub_arm.efi' Resetting CPU ...
I have no clue why GRUB would try to transfer data to a co-processor (ldc2l 11, cr4, [r8], #384).
As I cannot find a match in git://git.savannah.gnu.org/grub.git I wonder how you ended up with this in your GRUB.
I will stop my analysis here. I hope with the information provided you are able to take over.
Best regards
Heinrich

On 3/7/19 11:29 PM, Heinrich Schuchardt wrote:
On 3/7/19 12:05 PM, Adam Podogrocki wrote:
Hello Heinrich,
I've checked U-Boot behaviour in following setups:
1. U-Boot v2018.09/v2018.11 and GRUB commit 72e80c025 (used by us in other setups) 2. U-Boot v2019.01 and GRUB commit 72e80c025 (used by us in other setups) 3. U-Boot v2019.01 and GRUB latest commit 9223eff8f
These are not commit numbers from git://git.savannah.gnu.org/grub.git So to which repository do they relate?
On Google drive you supplied to me GRUB 35b909062. This is also not a valid commit number.
First I tried to find the location of the crash that you reported:
$ hexedit grub-arm.efi # GRUB 35b909062
000060D4 33 7B 31 68 03 F0 0F 02 4F EA 13 1B 02 9B 5F 18 000060E4 2F 44 04 2A 78 D8 DF E8 02 F0 03 03 43 6A 75 00 000060F4 F0 89 11 B3 08 BB 79 1E 11 F8 01 2F 6A B9 40 F2 00006104 FD 11 00 EB 50 10 FB F7 F8 FC 60 4B 03 EB 81 01 ^^^^^^^^^^^
I analyzed the file with the tool available at https://github.com/xypron/efi_analyzer
$ efianalyze grub-arm.efi # GRUB 35b909062
Offset to PE = 80 Machine type: 0x01c2, ARM or Thumb ("interworking") Characteristics 0x30e Image type: PE32 EFI application ImageBase=0x0 SectionAlignment=0x1000 SizeOfImage=0x55000 .reloc.address=0x54000 .reloc.size=0x1000 BaseOfCode=0x1000 AddressOfEntryPoint=0x1000 Number of Sections 4 Section[0] .text Virtual size 0x8000 Virtual address 0x1000 Size of raw data 0x8000 Pointer to raw data 0x1000 End of raw data 0x9000 Section[1] .data Virtual size 0xb000 Virtual address 0x9000 Size of raw data 0xb000 Pointer to raw data 0x9000 End of raw data 0x14000 Section[2] mods Virtual size 0x40000 Virtual address 0x14000 Size of raw data 0x40000 Pointer to raw data 0x14000 End of raw data 0x54000 Section[3] .reloc Virtual size 0x1000 Virtual address 0x54000 Size of raw data 0x1000 Pointer to raw data 0x54000 End of raw data 0x55000
So the entry-point is 0x1000 and the virtual address 0x1000 matches the position in the file. That makes things easy.
$ /usr/bin/arm-linux-gnueabihf-objdump -D -b binary -marm grub-arm.efi
1000: e59fc010 ldr ip, [pc, #16] ; 0x1018 1004: e58c0000 str r0, [ip] 1008: e59fc00c ldr ip, [pc, #12] ; 0x101c 100c: e58c1000 str r1, [ip] 1010: e59fc008 ldr ip, [pc, #8] ; 0x1020 1014: e12fff1c bx ip 1018: 0000c914 andeq ip, r0, r4, lsl r9 101c: 0000c910 andeq ip, r0, r0, lsl r9 1020: 0000610d andeq r6, r0, sp, lsl #2
This matches function _start() in grub-core/kern/arm/efi/startup.S:
ldr ip, =EXT_C(grub_efi_image_handle) str r0, [ip] ldr ip, =EXT_C(grub_efi_system_table) str r1, [ip] ldr ip, =EXT_C(grub_main) bx ip END
So here we first store the image handle and the system table. Then we branch to 610C in thumb mode (bit 0 is set in the address).
The entry point is called in U-Boot via
0x47f8765c <efi_start_image+100> ldr r0, [sp, #4]
0x47f87660 <efi_start_image+104> blx r3
So we have first a blx jump to ARM and then a bx jump to THUMB.
TODO for me:
According to http://infocenter.arm.com/help/topic/com.arm.doc.uan0002a/UAN002A_1176-pan_u... depending on the alignment of the blx command this sequence of commands may fail on some ARM11 processors.
But the BeagleBone Black has an ARMv7-A and not an ARM11 processor. So nothing to worry us.
The further disassembly depends on the start address:
/usr/bin/arm-linux-gnueabihf-objdump -D -b binary -marm \ --disassembler-options=force-thumb grub-arm.efi --start-addr=0x6100
00006100 <.data+0x6100>: 6100: b96a cbnz r2, 0x611e 6102: f240 11fd movw r1, #509 ; 0x1fd 6106: eb00 1050 add.w r0, r0, r0, lsr #5 610a: f7fb fcf8 bl 0x1afe 610e: 4b60 ldr r3, [pc, #384] ; (0x6290) 6110: eb03 0181 add.w r1, r3, r1, lsl #2 6114: 684a ldr r2, [r1, #4] 6116: b942 cbnz r2, 0x612a
/usr/bin/arm-linux-gnueabihf-objdump -D -b binary -marm \ --disassembler-options=force-thumb grub-arm.efi --start-addr=0x610c
0000610c <.data+0x610c>: 610c: fcf8 4b60 ldc2l 11, cr4, [r8], #384 ; 0x180 ; <UNPREDICTABLE> 6110: eb03 0181 add.w r1, r3, r1, lsl #2 6114: 684a ldr r2, [r1, #4] 6116: b942 cbnz r2, 0x612a 6118: 463a mov r2, r7 611a: 495e ldr r1, [pc, #376] ; (0x6294)
So the next instruction after branching is `ldc2l 11, cr4, [r8], #384`.
Next I put your grub_arm.efi into directory tftp/ and started U-Boot qemu_arm_defconfig with:
qemu-system-arm -machine virt -cpu cortex-a15 \ -bios u-boot.bin -nographic -gdb tcp::1234 -netdev \ user,id=eth0,tftp=tftp,net=192.168.76.0/24,dhcpstart=192.168.76.9 \ -device e1000,netdev=eth0
I displayed the relocation offset with command bdinfo:
=> bdinfo arch_number = 0x00000000 boot_params = 0x00000000 DRAM bank = 0x00000000 -> start = 0x40000000 -> size = 0x08000000 baudrate = 115200 bps TLB addr = 0x47ff0000 relocaddr = 0x47f4f000 <<<<<< You need this address reloc off = 0x47f4f000 irq_sp = 0x46e0dec0 sp start = 0x46e0deb0 Early malloc usage: 11c / 400 fdt_blob = 0x46e0ded8
In a separate mode I opened GDB:
gdb-multiarch u-boot -ex 'target remote localhost:1234'
(gdb) add-symbol-file u-boot 0x47f4f000 add symbol table from file "u-boot" at .text_addr = 0x47f4f000 (y or n) y Reading symbols from u-boot...done. (gdb) b efi_start_image Breakpoint 1 at 0x385f8: efi_start_image. (2 locations) (gdb) c Continuing
When debugging the ldc2l instruction at 610c caused the same error that you already observed:
=> bootefi $kernel_addr_r $fdtcontroladdr Found 0 disks ## Starting EFI application at 40400000 ... undefined instruction pc : [<45cb610a>] lr : [<47f87664>] reloc pc : [<fdd6710a>] lr : [<00038664>] sp : 46e0dc28 ip : 45cb610d fp : 47f6a324 r10: 00000003 r9 : 00000000 r8 : 46f11080 r7 : 40400000 r6 : 45e0c040 r5 : 00000000 r4 : 47f4f7c8 r3 : 45cb1000 r2 : 00000000 r1 : 47f4f7c8 r0 : 46f18010 Flags: nZCv IRQs off FIQs off Mode SVC_32 Code: 1e79bb08 2f01f811 f240b96a eb0011fd (f7fb1050) UEFI image [0x45cb0000:0x45d04fff] pc=0x610a '/grub_arm.efi' Resetting CPU ...
I have no clue why GRUB would try to transfer data to a co-processor (ldc2l 11, cr4, [r8], #384).
As I cannot find a match in git://git.savannah.gnu.org/grub.git I wonder how you ended up with this in your GRUB.
I will stop my analysis here. I hope with the information provided you are able to take over.
Best regards
Heinrich
On 3/8/19 2:12 PM, Adam Podogrocki wrote:> Hello Heinrich,
Just for clarification
http://git.savannah.gnu.org/cgit/grub.git/commit/?id=35b909062e7b334eb4af372...
- it is a commit I am referring to as GRUB #35b909062
I truly appreciate your help.
Regards, Adam Podogrocki
Thanks for pointing me to that commit.
I now have built that GRUB version with
./configure --target=arm-linux-gnueabihf --with-platform=efi \ --disable-grub-emu-usb TARGET_CC=arm-linux-gnueabihf-gcc
Now I tried to find out what grub_main() looks like:
$ objdump -D -marm grub-core/foo/usr/local/lib/grub/arm-efi/kernel.img
00005ce4 <grub_main>: 5ce4: b583 push {r0, r1, r7, lr} 5ce6: f7ff fffe bl 48 <grub_machine_init> 5cea: 2002 movs r0, #2 5cec: 4e74 ldr r6, [pc, #464] 5cee: f7ff ffc3 bl 5c78 <grub_list_remove+0x16> 5cf2: 4874 ldr r0, [pc, #464] 5cf4: f7ff fffe bl 69b0 <grub_err_printf> 5cf8: 2000 movs r0, #0 5cfa: f7ff ffbd bl 5c78 <grub_list_remove+0x16>
I found that code in your grub_arm.efi:
$ hexedit grub-arm.efi
v 00006D00 C0 18 70 47 18 C9 00 00 6D 69 6D 67 >83 B5 FA F7 00006D10 9B F9 02 20 74 4E FF F7 C3 FF 74 48 00 F0 6C FE 00006D20 00 20 FF F7 BD FF 33 68 E3 B1 19 68 70 4A 91 42
So what remains to find out, is why function _start() in grub-core/kern/arm/efi/startup.S is not jumping to 0x6D0d but to 0x610D.
This is the start of the relocation table:
00054000 00 10 00 00 88 00 00 00 18 30 1C 30 20 30 2C 30 00054010 44 30 80 30 84 30 88 30 94 30 C4 30 C8 30 34 31 00054020 38 31 3C 31 40 31 44 31 B8 31 BC 31 C0 31 E8 33 00054030 EC 33 FC 33 00 34 04 34 08 34 0C 34 10 34 14 34
So we start with Page RVA = 0x1000 Block Size = 0x88
and these relocations Type 3 - E_REL_BASED_HIGHLOW @ 0x018 Type 3 - E_REL_BASED_HIGHLOW @ 0x01c Type 3 - E_REL_BASED_HIGHLOW @ 0x020
This matches the three addresses used in _start().
According to the PE-COFF spec: "To apply a base relocation, the difference is calculated between the preferred base address and the base where the image is actually loaded. If the image is loaded at its preferred base, the difference is zero and thus the base relocations do not have to be applied."
The preferred load address of the image is ImageBase = 0 and the section starting at 0x1000 has a VirtualAddress of 0x1000. So in our analysis above no relocation has to be considered.
Thus I would consider this a bug in GRUB.
Best regards
Heinrich

On 3/8/19 9:39 PM, Heinrich Schuchardt wrote:
On 3/7/19 11:29 PM, Heinrich Schuchardt wrote:
On 3/7/19 12:05 PM, Adam Podogrocki wrote:
Hello Heinrich,
I've checked U-Boot behaviour in following setups:
1. U-Boot v2018.09/v2018.11 and GRUB commit 72e80c025 (used by us in other setups) 2. U-Boot v2019.01 and GRUB commit 72e80c025 (used by us in other setups) 3. U-Boot v2019.01 and GRUB latest commit 9223eff8f
These are not commit numbers from git://git.savannah.gnu.org/grub.git So to which repository do they relate?
On Google drive you supplied to me GRUB 35b909062. This is also not a valid commit number.
First I tried to find the location of the crash that you reported:
$ hexedit grub-arm.efi # GRUB 35b909062
000060D4 33 7B 31 68 03 F0 0F 02 4F EA 13 1B 02 9B 5F 18 000060E4 2F 44 04 2A 78 D8 DF E8 02 F0 03 03 43 6A 75 00 000060F4 F0 89 11 B3 08 BB 79 1E 11 F8 01 2F 6A B9 40 F2 00006104 FD 11 00 EB 50 10 FB F7 F8 FC 60 4B 03 EB 81 01 ^^^^^^^^^^^
I analyzed the file with the tool available at https://github.com/xypron/efi_analyzer
$ efianalyze grub-arm.efi # GRUB 35b909062
Offset to PE = 80 Machine type: 0x01c2, ARM or Thumb ("interworking") Characteristics 0x30e Image type: PE32 EFI application ImageBase=0x0 SectionAlignment=0x1000 SizeOfImage=0x55000 .reloc.address=0x54000 .reloc.size=0x1000 BaseOfCode=0x1000 AddressOfEntryPoint=0x1000 Number of Sections 4 Section[0] .text Virtual size 0x8000 Virtual address 0x1000 Size of raw data 0x8000 Pointer to raw data 0x1000 End of raw data 0x9000 Section[1] .data Virtual size 0xb000 Virtual address 0x9000 Size of raw data 0xb000 Pointer to raw data 0x9000 End of raw data 0x14000 Section[2] mods Virtual size 0x40000 Virtual address 0x14000 Size of raw data 0x40000 Pointer to raw data 0x14000 End of raw data 0x54000 Section[3] .reloc Virtual size 0x1000 Virtual address 0x54000 Size of raw data 0x1000 Pointer to raw data 0x54000 End of raw data 0x55000
So the entry-point is 0x1000 and the virtual address 0x1000 matches the position in the file. That makes things easy.
$ /usr/bin/arm-linux-gnueabihf-objdump -D -b binary -marm grub-arm.efi
1000: e59fc010 ldr ip, [pc, #16] ; 0x1018 1004: e58c0000 str r0, [ip] 1008: e59fc00c ldr ip, [pc, #12] ; 0x101c 100c: e58c1000 str r1, [ip] 1010: e59fc008 ldr ip, [pc, #8] ; 0x1020 1014: e12fff1c bx ip 1018: 0000c914 andeq ip, r0, r4, lsl r9 101c: 0000c910 andeq ip, r0, r0, lsl r9 1020: 0000610d andeq r6, r0, sp, lsl #2
This matches function _start() in grub-core/kern/arm/efi/startup.S:
ldr ip, =EXT_C(grub_efi_image_handle) str r0, [ip] ldr ip, =EXT_C(grub_efi_system_table) str r1, [ip] ldr ip, =EXT_C(grub_main) bx ip END
So here we first store the image handle and the system table. Then we branch to 610C in thumb mode (bit 0 is set in the address).
The entry point is called in U-Boot via
0x47f8765c <efi_start_image+100> ldr r0, [sp, #4]
0x47f87660 <efi_start_image+104> blx r3
So we have first a blx jump to ARM and then a bx jump to THUMB.
TODO for me:
According to http://infocenter.arm.com/help/topic/com.arm.doc.uan0002a/UAN002A_1176-pan_u... depending on the alignment of the blx command this sequence of commands may fail on some ARM11 processors.
But the BeagleBone Black has an ARMv7-A and not an ARM11 processor. So nothing to worry us.
The further disassembly depends on the start address:
/usr/bin/arm-linux-gnueabihf-objdump -D -b binary -marm \ --disassembler-options=force-thumb grub-arm.efi --start-addr=0x6100
00006100 <.data+0x6100>: 6100: b96a cbnz r2, 0x611e 6102: f240 11fd movw r1, #509 ; 0x1fd 6106: eb00 1050 add.w r0, r0, r0, lsr #5 610a: f7fb fcf8 bl 0x1afe 610e: 4b60 ldr r3, [pc, #384] ; (0x6290) 6110: eb03 0181 add.w r1, r3, r1, lsl #2 6114: 684a ldr r2, [r1, #4] 6116: b942 cbnz r2, 0x612a
/usr/bin/arm-linux-gnueabihf-objdump -D -b binary -marm \ --disassembler-options=force-thumb grub-arm.efi --start-addr=0x610c
0000610c <.data+0x610c>: 610c: fcf8 4b60 ldc2l 11, cr4, [r8], #384 ; 0x180 ; <UNPREDICTABLE> 6110: eb03 0181 add.w r1, r3, r1, lsl #2 6114: 684a ldr r2, [r1, #4] 6116: b942 cbnz r2, 0x612a 6118: 463a mov r2, r7 611a: 495e ldr r1, [pc, #376] ; (0x6294)
So the next instruction after branching is `ldc2l 11, cr4, [r8], #384`.
Next I put your grub_arm.efi into directory tftp/ and started U-Boot qemu_arm_defconfig with:
qemu-system-arm -machine virt -cpu cortex-a15 \ -bios u-boot.bin -nographic -gdb tcp::1234 -netdev \ user,id=eth0,tftp=tftp,net=192.168.76.0/24,dhcpstart=192.168.76.9 \ -device e1000,netdev=eth0
I displayed the relocation offset with command bdinfo:
=> bdinfo arch_number = 0x00000000 boot_params = 0x00000000 DRAM bank = 0x00000000 -> start = 0x40000000 -> size = 0x08000000 baudrate = 115200 bps TLB addr = 0x47ff0000 relocaddr = 0x47f4f000 <<<<<< You need this address reloc off = 0x47f4f000 irq_sp = 0x46e0dec0 sp start = 0x46e0deb0 Early malloc usage: 11c / 400 fdt_blob = 0x46e0ded8
In a separate mode I opened GDB:
gdb-multiarch u-boot -ex 'target remote localhost:1234'
(gdb) add-symbol-file u-boot 0x47f4f000 add symbol table from file "u-boot" at .text_addr = 0x47f4f000 (y or n) y Reading symbols from u-boot...done. (gdb) b efi_start_image Breakpoint 1 at 0x385f8: efi_start_image. (2 locations) (gdb) c Continuing
When debugging the ldc2l instruction at 610c caused the same error that you already observed:
=> bootefi $kernel_addr_r $fdtcontroladdr Found 0 disks ## Starting EFI application at 40400000 ... undefined instruction pc : [<45cb610a>] lr : [<47f87664>] reloc pc : [<fdd6710a>] lr : [<00038664>] sp : 46e0dc28 ip : 45cb610d fp : 47f6a324 r10: 00000003 r9 : 00000000 r8 : 46f11080 r7 : 40400000 r6 : 45e0c040 r5 : 00000000 r4 : 47f4f7c8 r3 : 45cb1000 r2 : 00000000 r1 : 47f4f7c8 r0 : 46f18010 Flags: nZCv IRQs off FIQs off Mode SVC_32 Code: 1e79bb08 2f01f811 f240b96a eb0011fd (f7fb1050) UEFI image [0x45cb0000:0x45d04fff] pc=0x610a '/grub_arm.efi' Resetting CPU ...
I have no clue why GRUB would try to transfer data to a co-processor (ldc2l 11, cr4, [r8], #384).
As I cannot find a match in git://git.savannah.gnu.org/grub.git I wonder how you ended up with this in your GRUB.
I will stop my analysis here. I hope with the information provided you are able to take over.
Best regards
Heinrich
On 3/8/19 2:12 PM, Adam Podogrocki wrote:> Hello Heinrich,
Just for clarification
http://git.savannah.gnu.org/cgit/grub.git/commit/?id=35b909062e7b334eb4af372...
- it is a commit I am referring to as GRUB #35b909062
I truly appreciate your help.
Regards, Adam Podogrocki
Thanks for pointing me to that commit.
I now have built that GRUB version with
./configure --target=arm-linux-gnueabihf --with-platform=efi \ --disable-grub-emu-usb TARGET_CC=arm-linux-gnueabihf-gcc
Now I tried to find out what grub_main() looks like:
$ objdump -D -marm grub-core/foo/usr/local/lib/grub/arm-efi/kernel.img
00005ce4 <grub_main>: 5ce4: b583 push {r0, r1, r7, lr} 5ce6: f7ff fffe bl 48 <grub_machine_init> 5cea: 2002 movs r0, #2 5cec: 4e74 ldr r6, [pc, #464] 5cee: f7ff ffc3 bl 5c78 <grub_list_remove+0x16> 5cf2: 4874 ldr r0, [pc, #464] 5cf4: f7ff fffe bl 69b0 <grub_err_printf> 5cf8: 2000 movs r0, #0 5cfa: f7ff ffbd bl 5c78 <grub_list_remove+0x16>
I found that code in your grub_arm.efi:
$ hexedit grub-arm.efi
v
00006D00 C0 18 70 47 18 C9 00 00 6D 69 6D 67 >83 B5 FA F7 00006D10 9B F9 02 20 74 4E FF F7 C3 FF 74 48 00 F0 6C FE 00006D20 00 20 FF F7 BD FF 33 68 E3 B1 19 68 70 4A 91 42
So what remains to find out, is why function _start() in grub-core/kern/arm/efi/startup.S is not jumping to 0x6D0d but to 0x610D.
This is the start of the relocation table:
00054000 00 10 00 00 88 00 00 00 18 30 1C 30 20 30 2C 30 00054010 44 30 80 30 84 30 88 30 94 30 C4 30 C8 30 34 31 00054020 38 31 3C 31 40 31 44 31 B8 31 BC 31 C0 31 E8 33 00054030 EC 33 FC 33 00 34 04 34 08 34 0C 34 10 34 14 34
So we start with Page RVA = 0x1000 Block Size = 0x88
and these relocations Type 3 - E_REL_BASED_HIGHLOW @ 0x018 Type 3 - E_REL_BASED_HIGHLOW @ 0x01c Type 3 - E_REL_BASED_HIGHLOW @ 0x020
This matches the three addresses used in _start().
According to the PE-COFF spec: "To apply a base relocation, the difference is calculated between the preferred base address and the base where the image is actually loaded. If the image is loaded at its preferred base, the difference is zero and thus the base relocations do not have to be applied."
The preferred load address of the image is ImageBase = 0 and the section starting at 0x1000 has a VirtualAddress of 0x1000. So in our analysis above no relocation has to be considered.
Thus I would consider this a bug in GRUB.
Best regards
Heinrich
Leif pointed me to this patch series: https://lists.gnu.org/archive/html/grub-devel/2019-01/msg00113.html
He assumes than one of [PATCH v4 1/2] mkimage: Use EFI32_HEADER_SIZE define in arm-efi case [PATCH v4 2/2] mkimage: Align efi sections on 4k boundary broke GRUB on armhf.
Best regards
Heinrich
participants (1)
-
Heinrich Schuchardt