1Design Notes on Exporting U-Boot Functions to Standalone Applications: 2====================================================================== 3 41. The functions are exported by U-Boot via a jump table. The jump 5 table is allocated and initialized in the jumptable_init() routine 6 (common/exports.c). Other routines may also modify the jump table, 7 however. The jump table can be accessed as the 'jt' field of the 8 'global_data' structure. The struct members for the jump table are 9 defined in the <include/exports.h> header. E.g., to substitute the 10 malloc() and free() functions that will be available to standalone 11 applications, one should do the following: 12 13 DECLARE_GLOBAL_DATA_PTR; 14 15 gd->jt->malloc = my_malloc; 16 gd->jt->free = my_free; 17 18 Note that the pointers to the functions are real function pointers 19 so the compiler can perform type checks on these assignments. 20 212. The pointer to the jump table is passed to the application in a 22 machine-dependent way. PowerPC, ARM, MIPS, Blackfin and Nios II 23 architectures use a dedicated register to hold the pointer to the 24 'global_data' structure: r2 on PowerPC, r9 on ARM, k0 on MIPS, 25 P3 on Blackfin and gp on Nios II. The x86 architecture does not 26 use such a register; instead, the pointer to the 'global_data' 27 structure is passed as 'argv[-1]' pointer. 28 29 The application can access the 'global_data' structure in the same 30 way as U-Boot does: 31 32 DECLARE_GLOBAL_DATA_PTR; 33 34 printf("U-Boot relocation offset: %x\n", gd->reloc_off); 35 363. The application should call the app_startup() function before any 37 call to the exported functions. Also, implementor of the 38 application may want to check the version of the ABI provided by 39 U-Boot. To facilitate this, a get_version() function is exported 40 that returns the ABI version of the running U-Boot. I.e., a 41 typical application startup may look like this: 42 43 int my_app (int argc, char * const argv[]) 44 { 45 app_startup (argv); 46 if (get_version () != XF_VERSION) 47 return 1; 48 } 49 504. The default load and start addresses of the applications are as 51 follows: 52 53 Load address Start address 54 x86 0x00040000 0x00040000 55 PowerPC 0x00040000 0x00040004 56 ARM 0x0c100000 0x0c100000 57 MIPS 0x80200000 0x80200000 58 Blackfin 0x00001000 0x00001000 59 NDS32 0x00300000 0x00300000 60 Nios II 0x02000000 0x02000000 61 RISC-V 0x00600000 0x00600000 62 63 For example, the "hello world" application may be loaded and 64 executed on a PowerPC board with the following commands: 65 66 => tftp 0x40000 hello_world.bin 67 => go 0x40004 68 695. To export some additional function long foobar(int i,char c), the following steps 70 should be undertaken: 71 72 - Append the following line at the end of the include/_exports.h 73 file: 74 75 EXPORT_FUNC(foobar, long, foobar, int, char) 76 77 Parameters to EXPORT_FUNC: 78 - the first parameter is the function that is exported (default implementation) 79 - the second parameter is the return value type 80 - the third parameter is the name of the member in struct jt_funcs 81 this is also the name that the standalone application will used. 82 the rest of the parameters are the function arguments 83 84 - Add the prototype for this function to the include/exports.h 85 file: 86 87 long foobar(int i, char c); 88 89 Initialization with the default implementation is done in jumptable_init() 90 91 You can override the default implementation using: 92 93 gd->jt->foobar = another_foobar; 94 95 The signature of another_foobar must then match the declaration of foobar. 96 97 - Increase the XF_VERSION value by one in the include/exports.h 98 file 99 100 - If you want to export a function which depends on a CONFIG_XXX 101 use 2 lines like this: 102 #ifdef CONFIG_FOOBAR 103 EXPORT_FUNC(foobar, long, foobar, int, char) 104 #else 105 EXPORT_FUNC(dummy, void, foobar, void) 106 #endif 107 108 1096. The code for exporting the U-Boot functions to applications is 110 mostly machine-independent. The only places written in assembly 111 language are stub functions that perform the jump through the jump 112 table. That said, to port this code to a new architecture, the 113 only thing to be provided is the code in the examples/stubs.c 114 file. If this architecture, however, uses some uncommon method of 115 passing the 'global_data' pointer (like x86 does), one should add 116 the respective code to the app_startup() function in that file. 117 118 Note that these functions may only use call-clobbered registers; 119 those registers that are used to pass the function's arguments, 120 the stack contents and the return address should be left intact. 121