127b207fdSwdenkDesign Notes on Exporting U-Boot Functions to Standalone Applications: 227b207fdSwdenk====================================================================== 327b207fdSwdenk 477846748Swdenk1. The functions are exported by U-Boot via a jump table. The jump 577846748Swdenk table is allocated and initialized in the jumptable_init() routine 677846748Swdenk (common/exports.c). Other routines may also modify the jump table, 777846748Swdenk however. The jump table can be accessed as the 'jt' field of the 849cad547SMartin Dorwig 'global_data' structure. The struct members for the jump table are 977846748Swdenk defined in the <include/exports.h> header. E.g., to substitute the 1077846748Swdenk malloc() and free() functions that will be available to standalone 1177846748Swdenk applications, one should do the following: 1227b207fdSwdenk 1377846748Swdenk DECLARE_GLOBAL_DATA_PTR; 1427b207fdSwdenk 1549cad547SMartin Dorwig gd->jt->malloc = my_malloc; 1649cad547SMartin Dorwig gd->jt->free = my_free; 1727b207fdSwdenk 1849cad547SMartin Dorwig Note that the pointers to the functions are real function pointers 1949cad547SMartin Dorwig so the compiler can perform type checks on these assignments. 2027b207fdSwdenk 2177846748Swdenk2. The pointer to the jump table is passed to the application in a 220df01fd3SThomas Chou machine-dependent way. PowerPC, ARM, MIPS, Blackfin and Nios II 230df01fd3SThomas Chou architectures use a dedicated register to hold the pointer to the 246a10560cSMasahiro Yamada 'global_data' structure: r2 on PowerPC, r9 on ARM, k0 on MIPS, 250df01fd3SThomas Chou P3 on Blackfin and gp on Nios II. The x86 architecture does not 260df01fd3SThomas Chou use such a register; instead, the pointer to the 'global_data' 270df01fd3SThomas Chou structure is passed as 'argv[-1]' pointer. 2827b207fdSwdenk 2977846748Swdenk The application can access the 'global_data' structure in the same 3077846748Swdenk way as U-Boot does: 3127b207fdSwdenk 3277846748Swdenk DECLARE_GLOBAL_DATA_PTR; 3327b207fdSwdenk 3477846748Swdenk printf("U-Boot relocation offset: %x\n", gd->reloc_off); 3527b207fdSwdenk 3677846748Swdenk3. The application should call the app_startup() function before any 3777846748Swdenk call to the exported functions. Also, implementor of the 3877846748Swdenk application may want to check the version of the ABI provided by 3977846748Swdenk U-Boot. To facilitate this, a get_version() function is exported 4077846748Swdenk that returns the ABI version of the running U-Boot. I.e., a 4177846748Swdenk typical application startup may look like this: 4227b207fdSwdenk 4354841ab5SWolfgang Denk int my_app (int argc, char * const argv[]) 4477846748Swdenk { 4577846748Swdenk app_startup (argv); 4677846748Swdenk if (get_version () != XF_VERSION) 4777846748Swdenk return 1; 4877846748Swdenk } 4927b207fdSwdenk 5077846748Swdenk4. The default load and start addresses of the applications are as 5177846748Swdenk follows: 5227b207fdSwdenk 5377846748Swdenk Load address Start address 5477846748Swdenk x86 0x00040000 0x00040000 5577846748Swdenk PowerPC 0x00040000 0x00040004 5677846748Swdenk ARM 0x0c100000 0x0c100000 5777846748Swdenk MIPS 0x80200000 0x80200000 584c58eb55SMike Frysinger Blackfin 0x00001000 0x00001000 59afc1ce82SMacpaul Lin NDS32 0x00300000 0x00300000 600df01fd3SThomas Chou Nios II 0x02000000 0x02000000 61*3fafced7SRick Chen RISC-V 0x00600000 0x00600000 6227b207fdSwdenk 6377846748Swdenk For example, the "hello world" application may be loaded and 6477846748Swdenk executed on a PowerPC board with the following commands: 6527b207fdSwdenk 6677846748Swdenk => tftp 0x40000 hello_world.bin 6727b207fdSwdenk => go 0x40004 6827b207fdSwdenk 6949cad547SMartin Dorwig5. To export some additional function long foobar(int i,char c), the following steps 7077846748Swdenk should be undertaken: 7127b207fdSwdenk 7277846748Swdenk - Append the following line at the end of the include/_exports.h 7377846748Swdenk file: 7427b207fdSwdenk 7549cad547SMartin Dorwig EXPORT_FUNC(foobar, long, foobar, int, char) 7649cad547SMartin Dorwig 7749cad547SMartin Dorwig Parameters to EXPORT_FUNC: 7849cad547SMartin Dorwig - the first parameter is the function that is exported (default implementation) 7949cad547SMartin Dorwig - the second parameter is the return value type 8049cad547SMartin Dorwig - the third parameter is the name of the member in struct jt_funcs 8149cad547SMartin Dorwig this is also the name that the standalone application will used. 8249cad547SMartin Dorwig the rest of the parameters are the function arguments 8327b207fdSwdenk 8477846748Swdenk - Add the prototype for this function to the include/exports.h 8577846748Swdenk file: 8627b207fdSwdenk 8749cad547SMartin Dorwig long foobar(int i, char c); 8827b207fdSwdenk 8949cad547SMartin Dorwig Initialization with the default implementation is done in jumptable_init() 9027b207fdSwdenk 9149cad547SMartin Dorwig You can override the default implementation using: 9249cad547SMartin Dorwig 9349cad547SMartin Dorwig gd->jt->foobar = another_foobar; 9449cad547SMartin Dorwig 9549cad547SMartin Dorwig The signature of another_foobar must then match the declaration of foobar. 9627b207fdSwdenk 9777846748Swdenk - Increase the XF_VERSION value by one in the include/exports.h 9877846748Swdenk file 9927b207fdSwdenk 10049cad547SMartin Dorwig - If you want to export a function which depends on a CONFIG_XXX 10149cad547SMartin Dorwig use 2 lines like this: 10249cad547SMartin Dorwig #ifdef CONFIG_FOOBAR 10349cad547SMartin Dorwig EXPORT_FUNC(foobar, long, foobar, int, char) 10449cad547SMartin Dorwig #else 10549cad547SMartin Dorwig EXPORT_FUNC(dummy, void, foobar, void) 10649cad547SMartin Dorwig #endif 10749cad547SMartin Dorwig 10849cad547SMartin Dorwig 10977846748Swdenk6. The code for exporting the U-Boot functions to applications is 11077846748Swdenk mostly machine-independent. The only places written in assembly 11177846748Swdenk language are stub functions that perform the jump through the jump 11277846748Swdenk table. That said, to port this code to a new architecture, the 11377846748Swdenk only thing to be provided is the code in the examples/stubs.c 11477846748Swdenk file. If this architecture, however, uses some uncommon method of 11577846748Swdenk passing the 'global_data' pointer (like x86 does), one should add 11677846748Swdenk the respective code to the app_startup() function in that file. 11727b207fdSwdenk 11877846748Swdenk Note that these functions may only use call-clobbered registers; 11977846748Swdenk those registers that are used to pass the function's arguments, 12077846748Swdenk the stack contents and the return address should be left intact. 121