Skip to content
Snippets Groups Projects
README 110 KiB
Newer Older

	It is essential to remember this, since it has some impact on the C
	code for the initialization procedures:

	* Initialized global data (data segment) is read-only. Do not attempt
	  to write it.

	* Do not use any unitialized global data (or implicitely initialized
	  as zero data - BSS segment) at all - this is undefined, initiali-
	  zation is performed later (when relocating to RAM).

	* Stack space is very limited. Avoid big data buffers or things like
	  that.

	Having only the stack as writable memory limits means we cannot use
	normal global data to share information beween the code. But it
	turned out that the implementation of U-Boot can be greatly
	simplified by making a global data structure (gd_t) available to all
	functions. We could pass a pointer to this data as argument to _all_
	functions, but this would bloat the code. Instead we use a feature of
	the GCC compiler (Global Register Variables) to share the data: we
	place a pointer (gd) to the global data into a register which we
	reserve for this purpose.

	When choosing a register for such a purpose we are restricted by the
	relevant  (E)ABI  specifications for the current architecture, and by
	GCC's implementation.

	For PowerPC, the following registers have specific use:
		R1:	stack pointer
		R2:	TOC pointer
		R3-R4:	parameter passing and return values
		R5-R10: parameter passing
		R13:	small data area pointer
		R30:	GOT pointer
		R31:	frame pointer

		(U-Boot also uses R14 as internal GOT pointer.)

	    ==> U-Boot will use R29 to hold a pointer to the global data

	    Note: on PPC, we could use a static initializer (since the
	    address of the global data structure is known at compile time),
	    but it turned out that reserving a register results in somewhat
	    smaller code - although the code savings are not that big (on
	    average for all boards 752 bytes for the whole U-Boot image,
	    624 text + 127 data).

	On ARM, the following registers are used:

		R0:	function argument word/integer result
		R1-R3:	function argument word
		R9:	GOT pointer
		R10:	stack limit (used only if stack checking if enabled)
		R11:	argument (frame) pointer
		R12:	temporary workspace
		R13:	stack pointer
		R14:	link register
		R15:	program counter

	    ==> U-Boot will use R8 to hold a pointer to the global data


	Memory Management:
	------------------

	U-Boot runs in system state and uses physical addresses, i.e. the
	MMU is not used either for address mapping nor for memory protection.

	The available memory is mapped to fixed addresses using the memory
	controller. In this process, a contiguous block is formed for each
	memory type (Flash, SDRAM, SRAM), even when it consists of several
	physical memory banks.

	U-Boot is installed in the first 128 kB of the first Flash bank (on
	TQM8xxL modules this is the range 0x40000000 ... 0x4001FFFF). After
	booting and sizing and initializing DRAM, the code relocates itself
	to the upper end of DRAM. Immediately below the U-Boot code some
	memory is reserved for use by malloc() [see CFG_MALLOC_LEN
	configuration setting]. Below that, a structure with global Board
	Info data is placed, followed by the stack (growing downward).

	Additionally, some exception handler code is copied to the low 8 kB
	of DRAM (0x00000000 ... 0x00001FFF).

	So a typical memory configuration with 16 MB of DRAM could look like
	this:

		0x0000 0000	Exception Vector code
		      :
		0x0000 1FFF
		0x0000 2000	Free for Application Use
		      :
		      :

		      :
		      :
		0x00FB FF20	Monitor Stack (Growing downward)
		0x00FB FFAC	Board Info Data and permanent copy of global data
		0x00FC 0000	Malloc Arena
		      :
		0x00FD FFFF
		0x00FE 0000	RAM Copy of Monitor Code
		...		eventually: LCD or video framebuffer
		...		eventually: pRAM (Protected RAM - unchanged by reset)
		0x00FF FFFF	[End of RAM]


	System Initialization:
	----------------------

	In the reset configuration, U-Boot starts at the reset entry point
	(on most PowerPC systens at address 0x00000100). Because of the reset
	configuration for CS0# this is a mirror of the onboard Flash memory.
	To be able to re-map memory U-Boot then jumps to its link address.
	To be able to implement the initialization code in C, a (small!)
	initial stack is set up in the internal Dual Ported RAM (in case CPUs
	which provide such a feature like MPC8xx or MPC8260), or in a locked
	part of the data cache. After that, U-Boot initializes the CPU core,
	the caches and the SIU.

	Next, all (potentially) available memory banks are mapped using a
	preliminary mapping. For example, we put them on 512 MB boundaries
	(multiples of 0x20000000: SDRAM on 0x00000000 and 0x20000000, Flash
	on 0x40000000 and 0x60000000, SRAM on 0x80000000). Then UPM A is
	programmed for SDRAM access. Using the temporary configuration, a
	simple memory test is run that determines the size of the SDRAM
	banks.

	When there is more than one SDRAM bank, and the banks are of
	different size, the largest is mapped first. For equal size, the first
	bank (CS2#) is mapped first. The first mapping is always for address
	0x00000000, with any additional banks following immediately to create
	contiguous memory starting from 0.

	Then, the monitor installs itself at the upper end of the SDRAM area
	and allocates memory for use by malloc() and for the global Board
	Info data; also, the exception vector code is copied to the low RAM
	pages, and the final stack is set up.

	Only after this relocation will you have a "normal" C environment;
	until that you are restricted in several ways, mostly because you are
	running from ROM, and because the code will have to be relocated to a
	new address in RAM.


	U-Boot Porting Guide:
	----------------------

	[Based on messages by Jerry Van Baren in the U-Boot-Users mailing
	list, October 2002]


	int main (int argc, char *argv[])
	{
		sighandler_t no_more_time;

		signal (SIGALRM, no_more_time);
		alarm (PROJECT_DEADLINE - toSec (3 * WEEK));

		if (available_money > available_manpower) {
			pay consultant to port U-Boot;
			return 0;
		}

		Download latest U-Boot source;

		Subscribe to u-boot-users mailing list;

		if (clueless) {
			email ("Hi, I am new to U-Boot, how do I get started?");
		}

		while (learning) {
			Read the README file in the top level directory;
			Read http://www.denx.de/twiki/bin/view/DULG/Manual ;
			Read the source, Luke;
		}

		if (available_money > toLocalCurrency ($2500)) {
			Buy a BDI2000;
		} else {
			Add a lot of aggravation and time;
		}

		Create your own board support subdirectory;

		Create your own board config file;

		while (!running) {
			do {
				Add / modify source code;
			} until (compiles);
			Debug;
			if (clueless)
				email ("Hi, I am having problems...");
		}
		Send patch file to Wolfgang;
	void no_more_time (int sig)
	{
	      hire_a_guru();
	Coding Standards:
	-----------------
Wolfgang Denk's avatar
Wolfgang Denk committed

	All contributions to U-Boot should conform to the Linux kernel
	coding style; see the file "Documentation/CodingStyle" in your Linux
	kernel source directory.
Wolfgang Denk's avatar
Wolfgang Denk committed

	Please note that U-Boot is implemented in C (and to some small parts
	in Assembler); no C++ is used, so please do not use C++ style
	comments (//) in your code.
Wolfgang Denk's avatar
Wolfgang Denk committed

	Please also stick to the following formatting rules:
	- remove any trailing white space
	- use TAB characters for indentation, not spaces
	- make sure NOT to use DOS '\r\n' line feeds
	- do not add more than 2 empty lines to source files
	- do not add trailing empty lines to source files
	Submissions which do not conform to the standards may be returned
	with a request to reformat the changes.
	Submitting Patches:
	-------------------
Wolfgang Denk's avatar
Wolfgang Denk committed

	Since the number of patches for U-Boot is growing, we need to
	establish some rules. Submissions which do not conform to these rules
	may be rejected, even when they contain important and valuable stuff.
	When you send a patch, please include the following information with
	it:
Wolfgang Denk's avatar
Wolfgang Denk committed

	* For bug fixes: a description of the bug and how your patch fixes
	  this bug. Please try to include a way of demonstrating that the
	  patch actually fixes something.
Wolfgang Denk's avatar
Wolfgang Denk committed

	* For new features: a description of the feature and your
	  implementation.
Wolfgang Denk's avatar
Wolfgang Denk committed

	* A CHANGELOG entry as plaintext (separate from the patch)
Wolfgang Denk's avatar
Wolfgang Denk committed

	* For major contributions, your entry to the CREDITS file
Wolfgang Denk's avatar
Wolfgang Denk committed

	* When you add support for a new board, don't forget to add this
	  board to the MAKEALL script, too.
Wolfgang Denk's avatar
Wolfgang Denk committed

	* If your patch adds new configuration options, don't forget to
	  document these in the README file.
Wolfgang Denk's avatar
Wolfgang Denk committed

	* The patch itself. If you are accessing the CVS repository use "cvs
	  update; cvs diff -puRN"; else, use "diff -purN OLD NEW". If your
	  version of diff does not support these options, then get the latest
	  version of GNU diff.
Wolfgang Denk's avatar
Wolfgang Denk committed

	  The current directory when running this command shall be the top
	  level directory of the U-Boot source tree, or it's parent directory
	  (i. e. please make sure that your patch includes sufficient
	  directory information for the affected files).
	  We accept patches as plain text, MIME attachments or as uuencoded
	  gzipped text.
Wolfgang Denk's avatar
Wolfgang Denk committed

	* If one logical set of modifications affects or creates several
	  files, all these changes shall be submitted in a SINGLE patch file.
	* Changesets that contain different, unrelated modifications shall be
	  submitted as SEPARATE patches, one patch per changeset.
Wolfgang Denk's avatar
Wolfgang Denk committed

Wolfgang Denk's avatar
Wolfgang Denk committed

	* Before sending the patch, run the MAKEALL script on your patched
	  source tree and make sure that no errors or warnings are reported
	  for any of the boards.
Wolfgang Denk's avatar
Wolfgang Denk committed

	* Keep your modifications to the necessary minimum: A patch
	  containing several unrelated changes or arbitrary reformats will be
	  returned with a request to re-formatting / split it.
Wolfgang Denk's avatar
Wolfgang Denk committed

	* If you modify existing code, make sure that your new code does not
	  add to the memory footprint of the code ;-) Small is beautiful!
	  When adding new features, these should compile conditionally only
	  (using #ifdef), and the resulting code with the new feature
	  disabled must not need more memory than the old code without your
	  modification.