xref: /openbmc/u-boot/doc/README.standalone (revision 54841ab50c20d6fa6c9cc3eb826989da3a22d934)
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