Skip to content
Snippets Groups Projects
README 115 KiB
Newer Older
  • Learn to ignore specific revisions
  • =================
    
    One of the features of U-Boot is that you can dynamically load and
    run "standalone" applications, which can use some resources of
    U-Boot like console I/O functions or interrupt services.
    
    Two simple examples are included with the sources:
    
    "Hello World" Demo:
    -------------------
    
    'examples/hello_world.c' contains a small "Hello World" Demo
    application; it is automatically compiled when you build U-Boot.
    It's configured to run at address 0x00040004, so you can play with it
    like that:
    
    	=> loads
    	## Ready for S-Record download ...
    	~>examples/hello_world.srec
    	1 2 3 4 5 6 7 8 9 10 11 ...
    	[file transfer complete]
    	[connected]
    	## Start Addr = 0x00040004
    
    	=> go 40004 Hello World! This is a test.
    	## Starting application at 0x00040004 ...
    	Hello World
    	argc = 7
    	argv[0] = "40004"
    	argv[1] = "Hello"
    	argv[2] = "World!"
    	argv[3] = "This"
    	argv[4] = "is"
    	argv[5] = "a"
    	argv[6] = "test."
    	argv[7] = "<NULL>"
    	Hit any key to exit ...
    
    	## Application terminated, rc = 0x0
    
    Another example, which demonstrates how to register a CPM interrupt
    handler with the U-Boot code, can be found in 'examples/timer.c'.
    Here, a CPM timer is set up to generate an interrupt every second.
    The interrupt service routine is trivial, just printing a '.'
    character, but this is just a demo program. The application can be
    controlled by the following keys:
    
    	? - print current values og the CPM Timer registers
    	b - enable interrupts and start timer
    	e - stop timer and disable interrupts
    	q - quit application
    
    	=> loads
    	## Ready for S-Record download ...
    	~>examples/timer.srec
    	1 2 3 4 5 6 7 8 9 10 11 ...
    	[file transfer complete]
    	[connected]
    	## Start Addr = 0x00040004
    
    	=> go 40004
    	## Starting application at 0x00040004 ...
    	TIMERS=0xfff00980
    	Using timer 1
    	  tgcr @ 0xfff00980, tmr @ 0xfff00990, trr @ 0xfff00994, tcr @ 0xfff00998, tcn @ 0xfff0099c, ter @ 0xfff009b0
    
    Hit 'b':
    	[q, b, e, ?] Set interval 1000000 us
    	Enabling timer
    Hit '?':
    	[q, b, e, ?] ........
    	tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0xef6, ter=0x0
    Hit '?':
    	[q, b, e, ?] .
    	tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x2ad4, ter=0x0
    Hit '?':
    	[q, b, e, ?] .
    	tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x1efc, ter=0x0
    Hit '?':
    	[q, b, e, ?] .
    	tgcr=0x1, tmr=0xff1c, trr=0x3d09, tcr=0x0, tcn=0x169d, ter=0x0
    Hit 'e':
    	[q, b, e, ?] ...Stopping timer
    Hit 'q':
    	[q, b, e, ?] ## Application terminated, rc = 0x0
    
    
    Minicom warning:
    ================
    
    Over time, many people have reported problems when trying to use the
    "minicom" terminal emulation program for serial download. I (wd)
    consider minicom to be broken, and recommend not to use it. Under
    Unix, I recommend to use C-Kermit for general purpose use (and
    especially for kermit binary protocol download ("loadb" command), and
    use "cu" for S-Record download ("loads" command).
    
    Nevertheless, if you absolutely want to use it try adding this
    configuration to your "File transfer protocols" section:
    
    	   Name	   Program			Name U/D FullScr IO-Red. Multi
    	X  kermit  /usr/bin/kermit -i -l %l -s	 Y    U	   Y	   N	  N
    	Y  kermit  /usr/bin/kermit -i -l %l -r	 N    D	   Y	   N	  N
    
    
    NetBSD Notes:
    =============
    
    Starting at version 0.9.2, U-Boot supports NetBSD both as host
    (build U-Boot) and target system (boots NetBSD/mpc8xx).
    
    Building requires a cross environment; it is known to work on
    NetBSD/i386 with the cross-powerpc-netbsd-1.3 package (you will also
    need gmake since the Makefiles are not compatible with BSD make).
    Note that the cross-powerpc package does not install include files;
    attempting to build U-Boot will fail because <machine/ansi.h> is
    missing.  This file has to be installed and patched manually:
    
    	# cd /usr/pkg/cross/powerpc-netbsd/include
    	# mkdir powerpc
    	# ln -s powerpc machine
    	# cp /usr/src/sys/arch/powerpc/include/ansi.h powerpc/ansi.h
    	# ${EDIT} powerpc/ansi.h	## must remove __va_list, _BSD_VA_LIST
    
    Native builds *don't* work due to incompatibilities between native
    and U-Boot include files.
    
    Booting assumes that (the first part of) the image booted is a
    stage-2 loader which in turn loads and then invokes the kernel
    proper. Loader sources will eventually appear in the NetBSD source
    tree (probably in sys/arc/mpc8xx/stand/u-boot_stage2/); in the
    
    meantime, see ftp://ftp.denx.de/pub/u-boot/ppcboot_stage2.tar.gz
    
    
    
    Implementation Internals:
    =========================
    
    The following is not intended to be a complete description of every
    implementation detail. However, it should help to understand the
    inner workings of U-Boot and make it easier to port it to custom
    hardware.
    
    
    Initial Stack, Global Data:
    ---------------------------
    
    The implementation of U-Boot is complicated by the fact that U-Boot
    starts running out of ROM (flash memory), usually without access to
    system RAM (because the memory controller is not initialized yet).
    This means that we don't have writable Data or BSS segments, and BSS
    is not initialized as zero. To be able to get a C environment working
    at all, we have to allocate at least a minimal stack. Implementation
    options for this are defined and restricted by the CPU used: Some CPU
    models provide on-chip memory (like the IMMR area on MPC8xx and
    MPC826x processors), on others (parts of) the data cache can be
    locked as (mis-) used as memory, etc.
    
    	Chris Hallinan posted a good summary of	 these	issues	to  the
    	u-boot-users mailing list:
    
    	Subject: RE: [U-Boot-Users] RE: More On Memory Bank x (nothingness)?
    	From: "Chris Hallinan" <clh@net1plus.com>
    	Date: Mon, 10 Feb 2003 16:43:46 -0500 (22:43 MET)
    	...
    
    	Correct me if I'm wrong, folks, but the way I understand it
    	is this: Using DCACHE as initial RAM for Stack, etc, does not
    	require any physical RAM backing up the cache. The cleverness
    	is that the cache is being used as a temporary supply of
    	necessary storage before the SDRAM controller is setup. It's
    	beyond the scope of this list to expain the details, but you
    	can see how this works by studying the cache architecture and
    	operation in the architecture and processor-specific manuals.
    
    	OCM is On Chip Memory, which I believe the 405GP has 4K. It
    	is another option for the system designer to use as an
    	initial stack/ram area prior to SDRAM being available. Either
    	option should work for you. Using CS 4 should be fine if your
    	board designers haven't used it for something that would
    	cause you grief during the initial boot! It is frequently not
    	used.
    
    	CFG_INIT_RAM_ADDR should be somewhere that won't interfere
    	with your processor/board/system design. The default value
    	you will find in any recent u-boot distribution in
    
    	walnut.h should work for you. I'd set it to a value larger
    
    	than your SDRAM module. If you have a 64MB SDRAM module, set
    	it above 400_0000. Just make sure your board has no resources
    	that are supposed to respond to that address! That code in
    	start.S has been around a while and should work as is when
    	you get the config right.
    
    	-Chris Hallinan
    	DS4.COM, Inc.
    
    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:
    ----------------------
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    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:
    ----------------------
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    [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;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	signal (SIGALRM, no_more_time);
    	alarm (PROJECT_DEADLINE - toSec (3 * WEEK));
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	if (available_money > available_manpower) {
    		pay consultant to port U-Boot;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		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;
    
    	return 0;
    }
    
    void no_more_time (int sig)
    {
          hire_a_guru();
    }
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    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.
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    Patches shall be sent to the u-boot-users mailing list.
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    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.
    
    
    * Remember that there is a size limit of 40 kB per message on the
      u-boot-users mailing list. Compression may help.