Is there a way to call U-Boot API functions from within an ARM program loaded with the go command ?
I see that the U-Boot API is available after startup at an address defined in the environment variable api_address but i can’t make sens of how to use it.
For example, if i want to call the getc function that ones see in U-Boot api/api.c, how do i actually call it from within an assembly program ?
I tried this (on ARM1176JZF-S board) but this crash :
.global _start
_start:
ldr r0, =0x1BB89148 ; api_address value
ldr r1, [r0, #32] ; offset to get getc location
bx r1 ; call getc
The rational was to call the second function (API_getc) from the syscall_table initialized in U-Boot api.c with r0 being the value of api_address.
1
Looks like i was misguided with api_address as it is not the address of the jump table but the api_signature struct defined in api/api.c, this hold a syscall member which is the address of the syscall function defined in that same file, this function can be used to call the API (the api example show that) but i was looking for a more direct access…
doc/README.standalone and looking / disassembling the standalone example was more useful especially the examples/standalone/stubs.c where it show the assembly code used to call an API function, this code use the U-Boot global data pointer stored in R9 on ARM (global_data struct in include/asm-generic/global_data.h) plus some computed offset to locate the jump table (struct jt member) which contains pointers to exported functions, it then call the API function stored in that table.
So in my case this works :
.global _start
_start:
// U-Boot API call
adr lr, halt // get back to "halt" after calling getc
ldr ip, [r9, #124] // load jump table address (global data pointer is in r9 + offset to the *jt* member)
ldr pc, [ip, #4] // call getc
//
halt:
wfe
b halt
Note that the offset to locate the jump table may change with different U-Boot config. options.