Android源码编译(三)----------->beagleboard-xm u-boot

来源:互联网 发布:matlab char数组 编辑:程序博客网 时间:2024/06/10 07:31

1, Build

From http://code.google.com/p/beagleboard/wiki/BeagleSourceCode, download u-boot 1.3.3 for beagleboard

If you uses latest ARM gcc from codesourcery, you maybe get following error

arm-none-linux-gnueabi-gcc -g  -Os   -fno-strict-aliasing  -fno-common -ffixed-r8 -msoft-float  -D__KERNEL__ -DTEXT_BASE=0x80e80000 -I/home/ken/bb/u-boot/u-boot-beagle/include -fno-builtin -ffreestanding -nostdinc -isystem /opt/sourcery_g++/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/include -pipe  -DCONFIG_ARM -D__ARM__ -march=armv7a  -Wall -Wstrict-prototypes -c -o hello_world.o hello_world.chello_world.c:1: error: bad value (armv7a) for -march= switch

This issue is caused by latest GCC changing for ARMV7-A architecture, that should uses -march=armv7-a but not -march=armv7a.

To fix it, in u-boot\cpu\omap3\config.mk, change following line:

PLATFORM_CPPFLAGS += -march=armv7a

To:

PLATFORM_CPPFLAGS += -march=armv7-a

Although success to build uboot.bin image, but beagleboard-xm fail to boot it:

a) the serial baudrate is changed from 115200 to 57600

b) system hang after find no NAND memory.

But the u-boot image built from git mainline git://git.denx.de/u-boot.git with omap3 patch can work correctly, please referencehttp://www.elinux.org/BeagleBoard

   1: git clone git://git.denx.de/u-boot.git u-boot-main   2: cd u-boot-main   3: git checkout --track -b omap3 origin/master

Build

   1: make CROSS_COMPILE=arm-none-linux-gnueabi- mrproper   2: make CROSS_COMPILE=arm-none-linux-gnueabi- omap3_beagle_config   3: make CROSS_COMPILE=arm-none-linux-gnueabi- 

As mentioned by previous discussion, u-boot.bin is loaded into the first of internal SDRAM at address 0×80008000. So in uboot\board\ti\beagle\config.mk:

   1: #   2: # Physical Address:   3: # 8000'0000 (bank0)   4: # A000/0000 (bank1)   5: # Linux-Kernel is expected to be at 8000'8000, entry 8000'8000   6: # (mem base + reserved)   7:     8: # For use with external or internal boots.   9: CONFIG_SYS_TEXT_BASE = 0x80008000

CONFIG_SYS_TEXT_BASE as macro passed into build options as:

arm-none-linux-gnueabi-gcc   -D__ASSEMBLY__ -g  -Os   -fno-common -ffixed-r8 -msoft-float   -D__KERNEL__-DCONFIG_SYS_TEXT_BASE=0×80008000 -I/home/ken/bb/u-boot/u-boot-mailine/include -fno-builtin -ffreestanding -nostdinc -isystem /opt/sourcery_g++/bin/../lib/gcc/arm-none-linux-gnueabi/4.3.3/include -pipe  -DCONFIG_ARM -D__ARM__ -marm  -mabi=aapcs-linux -mno-thumb-interwork -march=armv5   -o start.o start.S –c

(BTW: there is some interesting compiler options used: –ffreestanding, –isystem, –mabi=aapcs-linux)

It is worth to mention that uboot will keep some information into a global_data in top of stack, the structure is defined in uboot\arch\arm\include\asm\global_data.h:

   1: typedef    struct    global_data {   2:     bd_t        *bd;   3:     unsigned long    flags;   4:     unsigned long    baudrate;   5:     unsigned long    have_console;    /* serial_init() was called */   6:     unsigned long    env_addr;    /* Address  of Environment struct */   7:     unsigned long    env_valid;    /* Checksum of Environment valid? */   8:     unsigned long    fb_base;    /* base address of frame buffer */   9: #ifdef CONFIG_VFD  10:     unsigned char    vfd_type;    /* display type */  11: #endif  12: #ifdef CONFIG_FSL_ESDHC  13:     unsigned long    sdhc_clk;  14: #endif  15: #ifdef CONFIG_AT91FAMILY  16:     /* "static data" needed by at91's clock.c */  17:     unsigned long    cpu_clk_rate_hz;  18:     unsigned long    main_clk_rate_hz;  19:     unsigned long    mck_rate_hz;  20:     unsigned long    plla_rate_hz;  21:     unsigned long    pllb_rate_hz;  22:     unsigned long    at91_pllb_usb_init;  23: #endif  24: #ifdef CONFIG_ARM  25:     /* "static data" needed by most of timer.c on ARM platforms */  26:     unsigned long    timer_rate_hz;  27:     unsigned long    tbl;  28:     unsigned long    tbu;  29:     unsigned long long    timer_reset_value;  30:     unsigned long    lastinc;  31: #endif  32:     unsigned long    relocaddr;    /* Start address of U-Boot in RAM */  33:     phys_size_t    ram_size;    /* RAM size */  34:     unsigned long    mon_len;    /* monitor len */  35:     unsigned long    irq_sp;        /* irq stack pointer */  36:     unsigned long    start_addr_sp;    /* start_addr_stackpointer */  37:     unsigned long    reloc_off;  38: #if !(defined(CONFIG_SYS_NO_ICACHE) && defined(CONFIG_SYS_NO_DCACHE))  39:     unsigned long    tlb_addr;  40: #endif  41:     void        **jt;        /* jump table */  42:     char        env_buf[32];    /* buffer for getenv() before reloc. */  43: } gd_t;

The structure size maybe different according to configure macros, so at beginning of build, a script is used to calculate current size of global data:

   1: #   2: # Physical Address:   3: # 8000'0000 (bank0)   4: # A000/0000 (bank1)   5: # Linux-Kernel is expected to be at 8000'8000, entry 8000'8000   6: # (mem base + reserved)   7:     8: # For use with external or internal boots.   9: CONFIG_SYS_TEXT_BASE = 0x80008000

In EFI, there is similar design that put PeiCore’s private data at top of stack as global data.

2, Memory Map

0x9fff0000  ~  TLB table

0x9ff7f000 ~ 0x9fff0000 : Reserved for U-boot (449K)

0x9ff1f000 ~ 0x9ff7f000: for malloc(384k)

0x9ff1efe0 ~ 0x9ff1f000: board info (32 bytes)

0x9ff1ef68 ~ 0x9ff1efe0: global data (120 bytes)

0x9ff1ef68: New stack point

0×80008000                              reset vector

0×8007020 ~0×80008028      interrupt vectors

0×8000100 : Linux boot parameters

SDRAM #1

0x4020FF80 ~ 0×40210000  global_data

0x4020F800 ~0x4020FF80   stack

 

2, Workflow

  1. uboot\arch\cpu\armv7\start.S
    • Like x-load, start.S provide the first assemble loader for u-boot
    • The first instruction is reset vector and the interrupt/exception handle are closed to it. As system.map file:
80008000 T _start80008020 t _undefined_instruction80008024 t _software_interrupt80008028 t _prefetch_abort8000802c t _data_abort80008030 t _not_used80008034 t _irq80008038 t _fiq

    • Switch CPU to SVC32 mode.
   1: mrs    r0, cpsr   2: bic    r0, r0, #0x1f   3: orr    r0, r0, #0xd3   4: msr    cpsr,r0

    • Copy interrupt vectors to ROM indirect address: 0x4020F800
    • Because beagleboard-xm does not have NAND/OneNand device, so need copy DPLL initialize code into ROM indirect address after interrupt vectors
    • Init CPU in assemble like x-load:
      • Setup important registers: mmu, cache
      • Setup memory timing.
    • Setup stack for C code at 0x4020FF80 (uboot\include\configs\omap3_beagle.h):
  
   1: #define CONFIG_SYS_INIT_RAM_ADDR    0x4020f800   2: #define CONFIG_SYS_INIT_RAM_SIZE    0x800   3: #define CONFIG_SYS_INIT_SP_ADDR        (CONFIG_SYS_INIT_RAM_ADDR + \   4:                      CONFIG_SYS_INIT_RAM_SIZE - \   5:                      GENERATED_GBL_DATA_SIZE) 

As above mentioned, before top of stack, global_data will be stored, the size of global_data is determined/generated at build time (include\generated\generic-asm-offices.h)

   1: #define GENERATED_GBL_DATA_SIZE (128) /* (sizeof(struct global_data) + 15) & ~15 */

    • Call C function board_init_f (uboot\arch\arm\lib\board.c):
      • Assign/Init global data structure at 0x4020F800
      • Disable memory I/O cache for compiler optization, just like MemoryFence() used in edk2 MdePkg:
   1: __asm__ __volatile__("": : :"memory");

Because many hardware intialization or I/O accessing will use write/read same MMIO address, the compiler maybe optimizate these code out or re-arrange read/write sequence, so it will break. Above instruction like asm volatitle used.

      • call all function defined in init_sequence array:
        • timer_init (arch/arm/cpu/armv7/omap-common/timer.c)
          • here used GPTIMER2 (there are 12 GP time in OMAP3), which base adress is 0×49032000
        • Initialize environment, because no NAND, so the environment is relocated to RAM as in arch\arm\include\asm\global_data.h
   1: #define    GD_FLG_RELOC        0x00001    /* Code was relocated to RAM        */

            By default, some configuration value comes from global variable default_environment in common\env_common.c such as baudrate.

        • serial initliazation

beagleboard-xm use NS16650 serial at COM3 0×49020000, datasheet at http://www.national.com/ds/PC/PC16550D.pdf

        • Init stage1 console for print
        • Print CPU/board information
        • Init I2C device.
        • Init SDRAM device, caculate the bank’s size.
      • Reserve RAM memory for u-boot at top of RAM1 started from 0×80000000
      • Relocate code for new location at 0x9ff7f000/stack at 0x9ff1ef60 (arch\arm\cpu\armv7\start.S, relocate_code())
      • Jump to board_init_r() in new location in RAM, (The sequence is very like PeiCore relocation in EFI)
      • In beaglboard’s board_init_r() (board\ti\beagle\beagle.c):
        • Init GPMC
        • set board id for linux as 1546
        • set boot parameter address at 0×80000100
        • Init MMC driver
        • Init stdio drivers such as serial, nulldev
        • Init jumptable?
        • Evalute board version, for beagleboard-xm board, set VAUX2 to 1.8v for EHCI PHY. And print DIE ID at 0x4830A200
        • Init IRQ/FIQ stack which size are all 4K
        • Change CPSR to enable interrupt
        • Enter main_loop() function to read boot/user script …