README.standalone (27b207fd0a0941b03f27e2a82c0468b1a090c745) | README.standalone (7784674852c66b0924bdc79062bd208aa51fd0a9) |
---|---|
1Design Notes on Exporting U-Boot Functions to Standalone Applications: 2====================================================================== 3 | 1Design Notes on Exporting U-Boot Functions to Standalone Applications: 2====================================================================== 3 |
41. Add a field to the global_data structure, the pointer to a jump 5 table. | 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 slot numbers 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: |
6 | 12 |
72. Jump table itself is allocated and filled in the same way as the 8 syscall table is (allocated with malloc() after the code has been 9 relocated to RAM); a special function, fixed to the table element 10 number 0, will be added which returns the ABI version so 11 applications can check for compatibility issues. | 13 DECLARE_GLOBAL_DATA_PTR; |
12 | 14 |
133. It is application's responsibility to check the ABI version and 14 act accordingly. | 15 gd->jt[XF_malloc] = my_malloc; 16 gd->jt[XF_free] = my_free; |
15 | 17 |
164. Pointer to the global_data is passed to the application in the 17 dedicated register that is used in the U-Boot to hold this 18 pointer. This assumes that the application is built with the same 19 register- allocation flags as the U-Boot itself. (Actually, this 20 is a requirement even now, as the 'go' command does not perform 21 any actions to protect this register against being clobbered by 22 the application). | 18 Note that the pointers to the functions all have 'void *' type and 19 thus the compiler cannot perform type checks on these assignments. |
23 | 20 |
24 This approach won't work on the x86 architecture. See below. | 212. The pointer to the jump table is passed to the application in a 22 machine-dependent way. PowerPC, ARM and MIPS architectures use a 23 dedicated register to hold the pointer to the 'global_data' 24 structure: r29 on PowerPC, r8 on ARM and k0 on MIPS. The x86 25 architecture does not use such a register; instead, the pointer to 26 the 'global_data' structure is passed as 'argv[-1]' pointer. |
25 | 27 |
265. Application now calls standard library functions like printf() 27 instead of specially prefixed names like mon_printf() as it did 28 before. Present implementation of these functions (using the 29 system calls mechanism) will be replaced with jump stubs. | 28 The application can access the 'global_data' structure in the same 29 way as U-Boot does: |
30 | 30 |
316. To export additional functions, the following steps will have to be 32 taken: | 31 DECLARE_GLOBAL_DATA_PTR; |
33 | 32 |
34 - Add the xxx() U-Boot function to the EXPORT_FUNC list 35 - Add initialization of the appropriate slot in the jump table | 33 printf("U-Boot relocation offset: %x\n", gd->reloc_off); |
36 | 34 |
377. To port to a new architecture, the appropriate stub code should be 38 provided. No other machine-dependent code is used. Once the stub 39 template is available, no additional coding is needed when 40 exporting new U-Boot functions. A pre-processor macro will be used 41 to automatically instantiate the stub definition for each exported 42 function. | 353. The application should call the app_startup() function before any 36 call to the exported functions. Also, implementor of the 37 application may want to check the version of the ABI provided by 38 U-Boot. To facilitate this, a get_version() function is exported 39 that returns the ABI version of the running U-Boot. I.e., a 40 typical application startup may look like this: |
43 | 41 |
44Note the following: | 42 int my_app (int argc, char *argv[]) 43 { 44 app_startup (argv); 45 if (get_version () != XF_VERSION) 46 return 1; 47 } |
45 | 48 |
46- This approach uses a jump table with fixed slot allocation. That 47 said, to retain the ABI compatibility, no table reordering, 48 inserting new functions in the middle of the list or deleting 49 functions from the list is allowed. Any such action will break the 50 ABI compatibility. | 494. The default load and start addresses of the applications are as 50 follows: |
51 | 51 |
52- The x86 architecture does not use a dedicated register to store the 53 pointer to the global_data structure. There are the following 54 approaches available: | 52 Load address Start address 53 x86 0x00040000 0x00040000 54 PowerPC 0x00040000 0x00040004 55 ARM 0x0c100000 0x0c100000 56 MIPS 0x80200000 0x80200000 |
55 | 57 |
56 * Pass the global_data pointer to the application in a register or 57 as an additional argument. This requires special machine- 58 dependent startup code to be compiled into the application. | 58 For example, the "hello world" application may be loaded and 59 executed on a PowerPC board with the following commands: |
59 | 60 |
60 * Make the x86 consistent with the rest of architectures and use a 61 dedicated register. This renders one register unusable in the 62 rest of the U-Boot code and thus increases the size of the U-Boot 63 binary and decreases it performance. 64 65The following changes will be made: 66 67- The syscall handling code will be removed. 68 69- The include/_exports.h file will be introduced, containing the list 70 of the exported functions in the following form: 71 72 EXPORT_FUNC(getc) 73 EXPORT_FUNC(tstc) 74 ... 75 76 This list will be used to assign the slot numbers in the jump 77 table, to determine the size of the jump table and to generate the 78 code for the stub functions. 79 80- The include/exports.h file will be introduced, containing the 81 prototypes of the exported functions and the assigned slot numbers. 82 83- The examples/stubs.c file will be introduced, containing the code 84 for the jump stubs for each of the exported functions. 85 86Implementation Notes on Exporting U-Boot Functions: 87=================================================== 88 891. The patch was applied against TOT as of 7/24 12:50 MEST; the 90 resulting images were tested on the following boards: 91 92 * lwmon (PowerPC) 93 * trab (ARM) 94 * inca (MIPS) 95 96 The hello_world application was loaded and executed then: 97 98 [lwmon] 99 => tftp 0x40000 /tftpboot/LWMON/hello_world.bin-avn | 61 => tftp 0x40000 hello_world.bin |
100 => go 0x40004 101 | 62 => go 0x40004 63 |
102 [trab] 103 TRAB # tftp 0xc100000 /tftpboot/TRAB/hello_world.bin-avn 104 TRAB # go 0xc100000 | 645. To export some additional function foobar(), the following steps 65 should be undertaken: |
105 | 66 |
106 [inca] 107 INCA-IP # tftp 0x80200000 /tftpboot/INCA/hello_world.bin-avn 108 INCA-IP # go 0x80200000 | 67 - Append the following line at the end of the include/_exports.h 68 file: |
109 | 69 |
1102. As neither of supported x86 boards can be built from the TOT 111 sources currently, the patch build was verified by manually 112 running the following command in the U-Boot top directory: | 70 EXPORT_FUNC(foobar) |
113 | 71 |
114 > make -C examples TOPDIR=`pwd` ARCH=i386 CROSS_COMPILE= | 72 - Add the prototype for this function to the include/exports.h 73 file: |
115 | 74 |
116 The rest of the code is mostly machine-independent and was not 117 verified. | 75 void foobar(void); |
118 | 76 |
1193. To test the x86 assembly code, a small standalone application was 120 written. It was built and run on the RedHat Linux 8.0 (x86). The 121 application performs a jump using a pointer to jump table and a 122 function's index in it. | 77 - Add the initialization of the jump table slot wherever 78 appropriate (most likely, to the jumptable_init() function): |
123 | 79 |
1244. For the MIPS architecture, the linker script is also provided for 125 linking applications. The default linker script places the .text 126 and .data sections too far from each other so that the resulting 127 .bin files span about 256Mb in size. | 80 gd->jt[XF_foobar] = foobar; |
128 | 81 |
1295. Several example applications required updating for the new API. 130 These applications relied upon the bd_t pointer being passed as 131 the 1st argument to the main function; this had changed when the 132 system calls were introduced, but apparently, these applications 133 weren't fixed at that moment. This is fixed now. | 82 - Increase the XF_VERSION value by one in the include/exports.h 83 file |
134 | 84 |
1356. GCC issues warnings for the 'sched' application. Since now the 136 mon_printf() function is renamed to printf(), GCC applies its 137 knowledge of the format specifiers to check the arguments, 138 complaining about ints passed as longs and vice versa. This is not 139 fixed yet. | 856. The code for exporting the U-Boot functions to applications is 86 mostly machine-independent. The only places written in assembly 87 language are stub functions that perform the jump through the jump 88 table. That said, to port this code to a new architecture, the 89 only thing to be provided is the code in the examples/stubs.c 90 file. If this architecture, however, uses some uncommon method of 91 passing the 'global_data' pointer (like x86 does), one should add 92 the respective code to the app_startup() function in that file. |
140 | 93 |
1417. Only the hello_world example application was modified to make use 142 of the newly supplied get_version() function. The application now 143 prints two ABI versions, the one that the application was compiled 144 for and the other, actual ABI version. 145 1468. The following new files were added: 147 common/exports.c 148 examples/mips.lds 149 examples/stubs.c 150 include/_exports.h 151 include/exports.h 152 doc/README.standalone 153 154 The following files are no longer used and will be removed: 155 examples/syscall.S 156 include/syscall.h | 94 Note that these functions may only use call-clobbered registers; 95 those registers that are used to pass the function's arguments, 96 the stack contents and the return address should be left intact. |