Chinaunix首页 | 论坛 | 博客
  • 博客访问: 85452
  • 博文数量: 28
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-04 11:06
文章分类

全部博文(28)

文章存档

2014年(22)

2013年(5)

2012年(1)

我的朋友

分类: 嵌入式

2014-04-18 20:48:31

bootloader启动代码start.s调用
ldr    
pc ,_start_armboot
_start_armboot :  .word start_armboot
_start_armboot地址的内容start_armboot赋给pc从而进入第二阶段


第二阶段的功能:
<1>初始化IRQ FIQ模式的栈
  arch_cpu_init
<2>设置系统时钟 保存机器ID

gd->bd->bi_arch_number = MACH_TYPE_S3C2440;   //值为362
<3>初始化中断、定时器
 interrupt_init
 timer_init
<4>检查flash上的环境参数是否有效
   
env_init
<5>初始化串口控制台

 init_baudrate, /* initialze baudrate settings */
   serial_init, /* serial communications setup */
   console_init_f, /* stage 1 init of console */

<6> say that we are here 打印出uboot的版本信息
各模块的地址

   display_banner
<7>
检测系统内存映射(memory map)

int dram_init(void)

{config配置中有关于 PHYS_SDRAM_1 PHYS_SDRAM_1_SIZE变量的定义

     gd->bd->bi_dram[0] . start = PHYS_SDRAM_1;          //即0x3000 0000

     gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;  //即0x0400 0000

}
<8>将SDRAM的参数打印出来
  display_dram_config

<9>初始化NOR_flash并打印出其配置的参数数信息
  display_flash_config (flash_init ());

10>Nand_flash初始化
   nand_init()
<11>初始化环境变量并读入指定的内存
   env_relocate ();

<12>初始化各种设备驱动 i2c lcd key等
  stdio_init (); /* get the devices list going. */

<13>初始化网络设备 和控制台 使能中断
  gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

   console_init_r (); /* fully init console as a device */



代码分析:
start_armboot()

init_fnc_t **init_fnc_ptr;       //定义二级函数指针
 char *s;

 gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));

定义了全局数据指针,armboot_start的值位于0x3ff80000,且CONFIG_SYS_MALLOC_LEN在congfig中有定义

#define config_sys_malloc_len  (CONFIG_ENV_SIZE + 128 * 1024)

#define CONFIG_ENV_SIZE  0x20000   //128K为256M的Nandflash的块大小,block。

通过以上计算得出 config_sys_malloc_len 的大小为 256k = 0x4 0000。

再来看一下结构体gd_t,位于arch/arm/include/asm/global_data.h

sizeof(gd_t)=4 + 4 * 6 + 4+?+? = 32 +?= 0x20+?。

故gd所指向地址 0x3ff80000 - 0x40000 -  0x20-?为 0x3FF3 FFE0-?


点击(此处)折叠或打开

  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. #if 0
  16.     unsigned long    cpu_clk;    /* CPU clock in         */
  17.     unsigned long    bus_clk;
  18.     phys_size_t    ram_size;    /* RAM size */
  19.     unsigned long    reset_status;    /* reset status register at boot */
  20. #endif
  21.     void        **jt;        /* jump table */
  22. } gd_t;
  23. /*
  24.  * Global Data Flags
  25.  */
  26. #define    GD_FLG_RELOC    0x00001        /* Code was relocated to RAM        */
  27. #define    GD_FLG_DEVINIT    0x00002        /* Devices have been initialized    */
  28. #define    GD_FLG_SILENT    0x00004        /* Silent mode                */
  29. #define    GD_FLG_POSTFAIL    0x00008        /* Critical POST test failed        */
  30. #define    GD_FLG_POSTSTOP    0x00010        /* POST seqeunce aborted        */
  31. #define    GD_FLG_LOGINIT    0x00020        /* Log Buffer has been initialized    */
  32. #define GD_FLG_DISABLE_CONSOLE    0x00040        /* Disable console (in & out)     */

  33. #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm
  34. typedef struct bd_info {
  35.     int            bi_baudrate;    /* serial console baudrate */
  36.     unsigned long    bi_ip_addr;    /* IP Address */
  37.     struct environment_s     *bi_env;
  38.     ulong     bi_arch_number;    /* unique id for this board */
  39.     ulong     bi_boot_params;    /* where this board expects params */
  40.     struct                /* RAM configuration */
  41.     {
  42.     ulong start;
  43.     ulong size;
  44.     }            bi_dram[CONFIG_NR_DRAM_BANKS];
  45. } bd_t;

__asm__ __volatile__("": : :"memory"); //分配一个存储全局数据的区域,地址给指针 gd/

memset ((void*)gd, 0, sizeof (gd_t));//给全局变量gd初始化
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
memset (gd->bd, 0, sizeof (bd_t));//变量bd初始化
gd->flags |= GD_FLG_RELOC; /* Code was relocated to RAM  在初始化波特率时会用到 根据此标志来找到波特率等环境变量存放的位置*/

//uboot镜像文件大小

monitor_flash_len = _bss_start - _armboot_start;

//初始化函数循环
 见上述<3>--<8>

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
       if ((*init_fnc_ptr)() != 0)

      {
           hang ();
      }
 }


点击(此处)折叠或打开

  1. typedef int (init_fnc_t) (void);

  2. int print_cpuinfo (void);

  3. init_fnc_t *init_sequence[] = {
  4. #if defined(CONFIG_ARCH_CPU_INIT)
  5.     arch_cpu_init,        /* basic arch cpu dependent setup */
  6. #endif
  7.     board_init,        /* basic board dependent setup */
  8. #if defined(CONFIG_USE_IRQ)
  9.     interrupt_init,        /* set up exceptions */
  10. #endif
  11.     timer_init,        /* initialize timer */
  12. #ifdef CONFIG_FSL_ESDHC
  13.     get_clocks,
  14. #endif
  15.     env_init,        /* initialize environment */
  16.     init_baudrate,        /* initialze baudrate settings */
  17.     serial_init,        /* serial communications setup */
  18.     console_init_f,        /* stage 1 init of console */
  19.     display_banner,        /* say that we are here */
  20. #if defined(CONFIG_DISPLAY_CPUINFO)
  21.     print_cpuinfo,        /* display cpu info (and speed) */
  22. #endif
  23. #if defined(CONFIG_DISPLAY_BOARDINFO)
  24.     checkboard,        /* display board info */
  25. #endif
  26. #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
  27.     init_func_i2c,
  28. #endif
  29.     dram_init,        /* configure available RAM banks */
  30. #if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
  31.     arm_pci_init,
  32. #endif
  33.     display_dram_config,
  34.     NULL,
  35. };

mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,CONFIG_SYS_MALLOC_LEN);
//堆清0以便下次再用

//下面再是各种初始化

点击(此处)折叠或打开

  1. display_flash_config (flash_init ());
  2. nand_init();        /* go init the NAND */

  3. /* initialize environment */
  4.     env_relocate ();
  5. /* IP Address */
  6.     gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

  7.     stdio_init ();    /* get the devices list going. */

  8.     jumptable_init ();
  9. console_init_r ();    /* fully init console as a device
  10. /* enable exceptions */
  11.     enable_interrupts ();

  12.   /*fengpan add begin*/
  13. #ifdef CONFIG_USB_DEVICE
  14.     usb_init_slave();
  15. #endif    
  16. eth_initialize(gd->bd);
for (;;) {
      main_loop ();
}


初始化循环函数:分析

for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
       if ((*init_fnc_ptr)() != 0)

{   hang ();}}




board_init

点击(此处)折叠或打开

  1. int board_init (void)
  2. {
  3.     struct s3c24x0_clock_power * const clk_power =
  4.                     s3c24x0_get_base_clock_power();
  5.     struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
  6.     
  7.     /* set up the I/O ports
  8.     gpio->GPACON = 0x007FFFFF;
  9.     gpio->GPBCON = 0x00044555;
  10.     gpio->GPBUP = 0x000007FF;
  11.     gpio->GPCCON = 0xAAAAAAAA;
  12.     gpio->GPCUP = 0x0000FFFF;
  13.     gpio->GPDCON = 0xAAAAAAAA;
  14.     gpio->GPDUP = 0x0000FFFF;
  15.     gpio->GPECON = 0xAAAAAAAA;
  16.     gpio->GPEUP = 0x0000FFFF;
  17.     gpio->GPFCON = 0x000055AA;
  18.     gpio->GPFUP = 0x000000FF;
  19.     gpio->GPGCON = 0xFF95FFBA;
  20.     gpio->GPGUP = 0x0000FFFF;
  21.     gpio->GPHCON = 0x002AFAAA;
  22.     gpio->GPHUP = 0x000007FF;*/
  23.     /* set up the I/O ports */
  24.     /* support both of S3C2410 and S3C2440, by www.arm9.net */
  25.     if ((gpio->GSTATUS1 == 0x32410000) || (gpio->GSTATUS1 == 0x32410002))
  26.     {
  27.         /* arch number of SMDK2410-Board */
  28.         gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
  29.     }
  30.     else
  31.     {
  32.         /* arch number of SMDK2440-Board */
  33.         gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
  34.     }

  35.     /* adress of boot parameters */
  36.     gd->bd->bi_boot_params = 0x30000100;

  37.     icache_enable();
  38.     dcache_enable();

  39.     return 0;
  40. }
timer_init, /* initialize timer */

点击(此处)折叠或打开

  1. int timer_init(void)
  2. {
  3.     struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
  4.     ulong tmr;

  5.     /* use PWM Timer 4 because it has no output */
  6.     /* prescaler for Timer 4 is 16 */
  7.     writel(0x0f00, &timers->TCFG0);//预分频15+1=16 to timer4
  8.     if (timer_load_val == 0) {
  9.         /*
  10.          * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
  11.          * (default) and prescaler = 16. Should be 10390
  12.          * @33.25MHz and 15625 @ 50 MHz
  13.          */
  14.         timer_load_val = get_PCLK() / (2 * 16 * 100);
  15.         timer_clk = get_PCLK() / (2 * 16);
  16.     }
  17.     /* load value for 10 ms timeout */
  18.     lastdec = timer_load_val;
  19.     writel(timer_load_val, &timers->TCNTB4);
  20.     /* auto load, manual update of Timer 4 */
  21.     tmr = (readl(&timers->TCON) & ~0x0700000) | 0x0600000;
  22.     writel(tmr, &timers->TCON);
  23.     /* auto load, start Timer 4 */
  24.     tmr = (tmr & ~0x0700000) | 0x0500000;
  25.     writel(tmr, &timers->TCON);
  26.     timestamp = 0;

  27.     return (0);
  28. }


点击(此处)折叠或打开

  1. int timer_init(void)
  2. {
  3.     struct s3c24x0_timers *timers = s3c24x0_get_base_timers();
  4.     ulong tmr;

  5.     /* use PWM Timer 4 because it has no output */
  6.     /* prescaler for Timer 4 is 16 */
  7.     writel(0x0f00, &timers->TCFG0);
  8.     if (timer_load_val == 0) {
  9.         /*
  10.          * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
  11.          * (default) and prescaler = 16. Should be 10390
  12.          * @33.25MHz and 15625 @ 50 MHz
  13.          */
  14.         timer_load_val = get_PCLK() / (2 * 16 * 100);
  15.         timer_clk = get_PCLK() / (2 * 16);
  16.     }
  17.     /* load value for 10 ms timeout */
  18.     lastdec = timer_load_val;
  19.     writel(timer_load_val, &timers->TCNTB4);
  20.     /* auto load, manual update of Timer 4 */
  21.     tmr = (readl(&timers->TCON) & ~0x0700000) | 0x0600000;
  22.     writel(tmr, &timers->TCON);
  23.     /* auto load, start Timer 4 */
  24.     tmr = (tmr & ~0x0700000) | 0x0500000;
  25.     writel(tmr, &timers->TCON);
  26.     timestamp = 0;

  27.     return (0);
  28. }
env_init, /* initialize environment */

点击(此处)折叠或打开

  1. /* this is called before nand_init()
  2.  * so we can't read Nand to validate env data.
  3.  * Mark it OK for now. env_relocate() in env_common.c
  4.  * will call our relocate function which does the real
  5.  * validation.
  6.  *
  7.  * When using a NAND boot image (like sequoia_nand), the environment
  8.  * can be embedded or attached to the U-Boot image in NAND flash. This way
  9.  * the SPL loads not only the U-Boot image from NAND but also the
  10.  * environment.
  11.  */
  12. int env_init(void)
  13. {//在有一部分宏没定义 经过分析 发现此函数实质就执行下面语句
  14.     gd->env_addr = (ulong)&default_environment[0];
  15.     gd->env_valid = 1;//在下面initialze baudrate settings会用到

  16.     return (0);
  17. }
init_baudrate, /* initialze baudrate settings */

点击(此处)折叠或打开

  1. static int init_baudrate (void)
  2. {
  3.     char tmp[64];    /* long enough for environment variables */
  4.     int i = getenv_r ("baudrate", tmp, sizeof (tmp));
  5.     gd->bd->bi_baudrate = gd->baudrate = (i > 0)
  6.             ? (int) simple_strtoul (tmp, NULL, 10)
  7.             : CONFIG_BAUDRATE;

  8.     return (0);
  9. }
serial_init, /* serial communications setup */

点击(此处)折叠或打开

  1. int serial_init(void)
  2. {
  3.     return serial_init_dev(UART_NR);
  4. }

  5. #ifdef CONFIG_SERIAL1
    #define UART_NR S3C24X0_UART0


  6. static int serial_init_dev(const int dev_index)
  7. {
  8.     struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);

  9.     /* FIFO enable, Tx/Rx FIFO clear */
  10.     writel(0x07, &uart->UFCON);
  11.     writel(0x0, &uart->UMCON);

  12.     /* Normal,No parity,1 stop,8 bit */
  13.     writel(0x3, &uart->ULCON);
  14.     /*
  15.      * tx=level,rx=edge,disable timeout int.,enable rx error int.,
  16.      * normal,interrupt or polling
  17.      */
  18.     writel(0x245, &uart->UCON);

  19.     /* FIXME: This is sooooooooooooooooooo ugly */
  20.     _serial_setbrg(dev_index);

  21.     return (0);
  22. }
console_init_f, /* stage 1 init of console */

点击(此处)折叠或打开

  1. int console_init_f(void)
  2. {
  3.     gd->have_console = 1;

  4. #ifdef CONFIG_SILENT_CONSOLE
  5.     if (getenv("silent") != NULL)
  6.         gd->flags |= GD_FLG_SILENT;
  7. #endif

  8.     return 0;
  9. }
display_banner, /* say that we are here */
//测试串口 以及输出一些初始化后的信息

点击(此处)折叠或打开

  1. static int display_banner (void)
  2. {
  3.     printf ("\n\n%s\n\n", version_string);
  4.     debug ("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",
  5.      _armboot_start, _bss_start, _bss_end);
  6. #ifdef CONFIG_MODEM_SUPPORT
  7.     debug ("Modem Support enabled\n");
  8. #endif
  9. #ifdef CONFIG_USE_IRQ
  10.     debug ("IRQ Stack: %08lx\n", IRQ_STACK_START);
  11.     debug ("FIQ Stack: %08lx\n", FIQ_STACK_START);
  12. #endif

  13.     return (0);
  14. }
dram_init, /* configure available RAM banks */

点击(此处)折叠或打开

  1. int dram_init (void)
  2. {//sdram的初始化
  3.     gd->bd->bi_dram[0].start = PHYS_SDRAM_1;//config文件中 定义 SDRAM的起始地址
  4.     gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;//config文件中定义SDRAM的大小

  5.     return 0;
  6. }
display_dram_config
//显示SDRAM信息

点击(此处)折叠或打开

  1. static int display_dram_config (void)
  2. {
  3.     int i;

  4. #ifdef DEBUG
  5.     puts ("RAM Configuration:\n");

  6.     for(i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
  7.         printf ("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
  8.         print_size (gd->bd->bi_dram[i].size, "\n");
  9.     }
  10. #else
  11.     ulong size = 0;

  12.     for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
  13.         size += gd->bd->bi_dram[i].size;
  14.     }
  15.     puts("DRAM: ");
  16.     print_size(size, "\n");
  17. #endif

  18.     return (0);
  19. }














阅读(1935) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~