
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