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 877846748Swdenk 'global_data' structure. The slot numbers 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 1577846748Swdenk gd->jt[XF_malloc] = my_malloc; 1677846748Swdenk gd->jt[XF_free] = my_free; 1727b207fdSwdenk 1877846748Swdenk Note that the pointers to the functions all have 'void *' type and 1977846748Swdenk thus the compiler cannot 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 24*6a10560cSMasahiro 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 6127b207fdSwdenk 6277846748Swdenk For example, the "hello world" application may be loaded and 6377846748Swdenk executed on a PowerPC board with the following commands: 6427b207fdSwdenk 6577846748Swdenk => tftp 0x40000 hello_world.bin 6627b207fdSwdenk => go 0x40004 6727b207fdSwdenk 6877846748Swdenk5. To export some additional function foobar(), the following steps 6977846748Swdenk should be undertaken: 7027b207fdSwdenk 7177846748Swdenk - Append the following line at the end of the include/_exports.h 7277846748Swdenk file: 7327b207fdSwdenk 7477846748Swdenk EXPORT_FUNC(foobar) 7527b207fdSwdenk 7677846748Swdenk - Add the prototype for this function to the include/exports.h 7777846748Swdenk file: 7827b207fdSwdenk 7977846748Swdenk void foobar(void); 8027b207fdSwdenk 8177846748Swdenk - Add the initialization of the jump table slot wherever 8277846748Swdenk appropriate (most likely, to the jumptable_init() function): 8327b207fdSwdenk 8477846748Swdenk gd->jt[XF_foobar] = foobar; 8527b207fdSwdenk 8677846748Swdenk - Increase the XF_VERSION value by one in the include/exports.h 8777846748Swdenk file 8827b207fdSwdenk 8977846748Swdenk6. The code for exporting the U-Boot functions to applications is 9077846748Swdenk mostly machine-independent. The only places written in assembly 9177846748Swdenk language are stub functions that perform the jump through the jump 9277846748Swdenk table. That said, to port this code to a new architecture, the 9377846748Swdenk only thing to be provided is the code in the examples/stubs.c 9477846748Swdenk file. If this architecture, however, uses some uncommon method of 9577846748Swdenk passing the 'global_data' pointer (like x86 does), one should add 9677846748Swdenk the respective code to the app_startup() function in that file. 9727b207fdSwdenk 9877846748Swdenk Note that these functions may only use call-clobbered registers; 9977846748Swdenk those registers that are used to pass the function's arguments, 10077846748Swdenk the stack contents and the return address should be left intact. 101