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 240df01fd3SThomas Chou 'global_data' structure: r2 on PowerPC, r8 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 43*54841ab5SWolfgang 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 590df01fd3SThomas Chou Nios II 0x02000000 0x02000000 6027b207fdSwdenk 6177846748Swdenk For example, the "hello world" application may be loaded and 6277846748Swdenk executed on a PowerPC board with the following commands: 6327b207fdSwdenk 6477846748Swdenk => tftp 0x40000 hello_world.bin 6527b207fdSwdenk => go 0x40004 6627b207fdSwdenk 6777846748Swdenk5. To export some additional function foobar(), the following steps 6877846748Swdenk should be undertaken: 6927b207fdSwdenk 7077846748Swdenk - Append the following line at the end of the include/_exports.h 7177846748Swdenk file: 7227b207fdSwdenk 7377846748Swdenk EXPORT_FUNC(foobar) 7427b207fdSwdenk 7577846748Swdenk - Add the prototype for this function to the include/exports.h 7677846748Swdenk file: 7727b207fdSwdenk 7877846748Swdenk void foobar(void); 7927b207fdSwdenk 8077846748Swdenk - Add the initialization of the jump table slot wherever 8177846748Swdenk appropriate (most likely, to the jumptable_init() function): 8227b207fdSwdenk 8377846748Swdenk gd->jt[XF_foobar] = foobar; 8427b207fdSwdenk 8577846748Swdenk - Increase the XF_VERSION value by one in the include/exports.h 8677846748Swdenk file 8727b207fdSwdenk 8877846748Swdenk6. The code for exporting the U-Boot functions to applications is 8977846748Swdenk mostly machine-independent. The only places written in assembly 9077846748Swdenk language are stub functions that perform the jump through the jump 9177846748Swdenk table. That said, to port this code to a new architecture, the 9277846748Swdenk only thing to be provided is the code in the examples/stubs.c 9377846748Swdenk file. If this architecture, however, uses some uncommon method of 9477846748Swdenk passing the 'global_data' pointer (like x86 does), one should add 9577846748Swdenk the respective code to the app_startup() function in that file. 9627b207fdSwdenk 9777846748Swdenk Note that these functions may only use call-clobbered registers; 9877846748Swdenk those registers that are used to pass the function's arguments, 9977846748Swdenk the stack contents and the return address should be left intact. 100