uboot的init_sequence 分析

来源:互联网 发布:android 淘宝筛选界面 编辑:程序博客网 时间:2024/06/07 01:21

第一个C函数startarm_boot中首先执行了一个初始化函数指针数组。

初始化函数指针数组:
init_fnc_t *init_sequence[] = {
#if defined(CONFIG_ARCH_CPU_INIT)   //如果定义了CONFIG_ARCH_CPU_INIT这个宏,则调用cpu架构相关的函数。这个函数一般定义在arch/arm/cpu/arm926ejs/lpc3250/cpu.c中。
 arch_cpu_init,  /* basic arch cpu dependent setup */
#endif
 board_init,  /* basic board dependent setup */板级初始化函数。在board/zhiyuan/smartarm3250/smart3250.c中。 
#if defined(CONFIG_USE_IRQ)
 interrupt_init,  /* set up exceptions */初始化中断,目前3250的uboot不支持中断,因为3250去除了CONFIG_USE_IRQ的宏定义。
#endif
 timer_init,  /* initialize timer */初始化时钟,该函数在board/zhiyuan/smartarm3250/smart3250.c中
#ifdef CONFIG_FSL_ESDHC
 get_clocks,  //一般定义在arch/arm/cpu/XX/speed.c中。目前大部分arm不支持此特性。
#endif
 env_init,  /* initialize environment */位于common/目录下的env_nand.c文件中(因为smartarm3250.h中定义了CONFIG_ENV_IS_IN_NAND,makefile会编译它而不是其他的含有同样函数的源文件) 
 init_baudrate,  /* initialze baudrate settings */   初始化波特率设置。定义在arch/arm/lib/board.c
 serial_init,  /* serial communications setup */    定义在arch/arm/cpu/arm926ejs/lpc3250/serial.c中。
 console_init_f,  /* stage 1 init of console */   common/console.c
 display_banner,  /* say that we are here */arch/arm/lib/board.c中定义。
#if defined(CONFIG_DISPLAY_CPUINFO)
 print_cpuinfo,  /* display cpu info (and speed) */arch/arm/lib/board.c中定义。3250目前不支持
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
 checkboard,  /* display board info */ 3250目前不支持
#endif
#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
 init_func_i2c,      //i2c初始化,arch/arm/lib/board.c中定义。3250目前不支持
#endif
 dram_init,  /* configure available RAM banks *///board/zhiyuan/smartarm3250/smart3250.c中
#if defined(CONFIG_CMD_PCI) || defined (CONFIG_PCI)
 arm_pci_init,  //arch/arm/lib/board.c
#endif
 display_dram_config, //arch/arm/lib/board.c
 NULL,
};

函数使用分析:
1。arch_cpu_init 
如果定义了CONFIG_ARCH_CPU_INIT这个宏,则调用cpu架构相关的函数。这个函数一般定义在uboot/cpu/arm926ejs/lpc3250/cpu.c中。3250目前不支持。这个函数所做的工作是和cpu架构相关,比如使能cache,定义端口电压等。
2。board_init
板级初始化函数。在board/xxx/xxxxx/xxx.c中(相关的移植文件夹),初始化端口,设置中断触发方式等。首先调用dcache_kill(lowlevel_init.S)禁用数据cache,然后调用phy3250_get_board_info(lowlevel_init.c),填充PHY_HW_T。
typedef struct
{
  unsigned long dramcfg;    /* DRAM 配置字,配置DRAM的类型和容量,祥见smartarm3250_pre.h宏定义*/
  unsigned long syscfg;     /* 配置字, 目前只有bit0用来指示是否有SD卡接口*/
  /* MAC address, use lower 6 bytes only, index 0 is first byte */
  u_char  mac[8];     /* 使用最低6比特存储MAC地址*/
  unsigned long rsvd [5];   /* 保留,目前置零*/
  unsigned long fieldvval;  /* 必须填充为PHY_HW_VER_VAL */
} PHY_HW_T;
然后填充gd->bd结构体的两个成员,分别只是开发板代号和uboot传给内核的参数在内存中的地址。
/* arch/arm/include/asm */
typedef struct global_data {
 bd_t  *bd;
 unsigned long flags;
 unsigned long baudrate;
 unsigned long have_console; /* serial_init() was called */
 unsigned long env_addr; /* Address  of Environment struct */
 unsigned long env_valid; /* Checksum of Environment valid? */
 unsigned long fb_base; /* base address of frame buffer */
#ifdef CONFIG_VFD
 unsigned char vfd_type; /* display type */
#endif
#ifdef CONFIG_FSL_ESDHC
 unsigned long sdhc_clk;
#endif
#if 0
 unsigned long cpu_clk; /* CPU clock in Hz!  */
 unsigned long bus_clk;
 phys_size_t ram_size; /* RAM size */
 unsigned long reset_status; /* reset status register at boot */
#endif
 void  **jt;  /* stdio的跳转表*/
} gd_t;

(arch/arm/include/asm/u-boot.h)
typedef struct bd_info {
    int   bi_baudrate; /* serial console baudrate */
    unsigned long bi_ip_addr; /* IP Address */
    struct environment_s        *bi_env;
    ulong         bi_arch_number; /* 板子的编号,定义在arch/arm/include/asm/mach-types.h,每一个支持的开发板对应一个编号。smartarm3250*/
    ulong         bi_boot_params; /*板子参数的地址*/
    struct    /* RAM configuration */
    {
 ulong start;
 ulong size;
    }bi_dram[CONFIG_NR_DRAM_BANKS];
} bd_t;
最后,初始化SLC NAND控制器。
3。interrupt_init
中断初始化。3250不支持
4。timer_init
该函数在board/zhiyuan/smartarm3250/smart3250.c中。
根据smartarm3250.h中的CFG_HZ初始化并使能timer0。
5。env_init
位于common/目录下的env_flash.c文件中(因为smartarm3250.h中定义了CONFIG_ENV_IS_IN_NAND,makefile会编译它而不是其他的含有同样函数的源文件)初始化环境变量字符数组,3250使用的数组定义在common/enc_common.c中。gd->env_addr指向default_environment,gd->env_valid=1.
下面的代码可以看出,smartarm3250.h的许多宏被转化为字符串保存在default_environment。
uchar default_environment[] = {
#ifdef CONFIG_BOOTARGS
 "bootargs=" CONFIG_BOOTARGS   "\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
 "bootcmd=" CONFIG_BOOTCOMMAND  "\0"
#endif
#ifdef CONFIG_RAMBOOTCOMMAND
 "ramboot=" CONFIG_RAMBOOTCOMMAND  "\0"
#endif
#ifdef CONFIG_NFSBOOTCOMMAND
 "nfsboot=" CONFIG_NFSBOOTCOMMAND  "\0"
#endif
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
 "bootdelay=" MK_STR(CONFIG_BOOTDELAY) "\0"
#endif
#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
 "baudrate=" MK_STR(CONFIG_BAUDRATE)  "\0"
#endif
#ifdef CONFIG_LOADS_ECHO
 "loads_echo=" MK_STR(CONFIG_LOADS_ECHO) "\0"
#endif
#ifdef CONFIG_ETHADDR
 "ethaddr=" MK_STR(CONFIG_ETHADDR)  "\0"
#endif
#ifdef CONFIG_ETH1ADDR
 "eth1addr=" MK_STR(CONFIG_ETH1ADDR)  "\0"
#endif
#ifdef CONFIG_ETH2ADDR
 "eth2addr=" MK_STR(CONFIG_ETH2ADDR)  "\0"
#endif
#ifdef CONFIG_ETH3ADDR
 "eth3addr=" MK_STR(CONFIG_ETH3ADDR)  "\0"
#endif
#ifdef CONFIG_ETH4ADDR
 "eth4addr=" MK_STR(CONFIG_ETH4ADDR)  "\0"
#endif
#ifdef CONFIG_ETH5ADDR
 "eth5addr=" MK_STR(CONFIG_ETH5ADDR)  "\0"
#endif
#ifdef CONFIG_IPADDR
 "ipaddr=" MK_STR(CONFIG_IPADDR)  "\0"
#endif
#ifdef CONFIG_SERVERIP
 "serverip=" MK_STR(CONFIG_SERVERIP)  "\0"
#endif
#ifdef CONFIG_SYS_AUTOLOAD
 "autoload=" CONFIG_SYS_AUTOLOAD   "\0"
#endif
#ifdef CONFIG_PREBOOT
 "preboot=" CONFIG_PREBOOT   "\0"
#endif
#ifdef CONFIG_ROOTPATH
 "rootpath=" MK_STR(CONFIG_ROOTPATH)  "\0"
#endif
#ifdef CONFIG_GATEWAYIP
 "gatewayip=" MK_STR(CONFIG_GATEWAYIP) "\0"
#endif
#ifdef CONFIG_NETMASK
 "netmask=" MK_STR(CONFIG_NETMASK)  "\0"
#endif
#ifdef CONFIG_HOSTNAME
 "hostname=" MK_STR(CONFIG_HOSTNAME)  "\0"
#endif
#ifdef CONFIG_BOOTFILE
 "bootfile=" MK_STR(CONFIG_BOOTFILE)  "\0"
#endif
#ifdef CONFIG_LOADADDR
 "loadaddr=" MK_STR(CONFIG_LOADADDR)  "\0"
#endif
#ifdef  CONFIG_CLOCKS_IN_MHZ
 "clocks_in_mhz=1\0"
#endif
#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
 "pcidelay=" MK_STR(CONFIG_PCI_BOOTDELAY) "\0"
#endif
#ifdef  CONFIG_EXTRA_ENV_SETTINGS
 CONFIG_EXTRA_ENV_SETTINGS   //扩展的命令会存放在这里。
#endif
 "\0"
};

6.init_baudrate,  /* initialze baudrate settings */   
初始化波特率设置。定义在uboot/lib_arm/board.c
设置gd->bd->bi_baudrate 和gd->baudrate为定义的波特率

7。serial_init
定义在uboot/cpu/arm926ejs/lpc3250/serial.c中,相关的移植文件夹中。
根据CFG_UART_SEL确定是哪一个UART,然后初始化该串口。初始化之后就可以使用串口发送信息了。
8。console_init_f,  
/* stage 1 init of console */   common/console.c
int console_init_f(void)
{
 gd->have_console = 1; 

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

 return 0;
}

9.display_banner,
/* say that we are here */uboot/lib_arm/board.c中定义。主要用来显示uboot的版本信息和编译时间。
static int display_banner (void)
{
 printf ("\n\n%s\n\n", version_string);   。
 debug ("U-Boot code: %08lX -> %08lX  BSS: -> %08lX\n",
        _armboot_start, _bss_start, _bss_end);
#ifdef CONFIG_MODEM_SUPPORT
 debug ("Modem Support enabled\n");
#endif
#ifdef CONFIG_USE_IRQ
 debug ("IRQ Stack: %08lx\n", IRQ_STACK_START);
 debug ("FIQ Stack: %08lx\n", FIQ_STACK_START);
#endif

 return (0);
}

const char version_string[] =
 U_BOOT_VERSION" (" U_BOOT_DATE " - " U_BOOT_TIME ")"CONFIG_IDENT_STRING;
打印出来的信息为:U-Boot 2010.06 (Mar 14 2011 - 11:17:26)
10。dram_init,  
/* configure available RAM banks *///board/xxxx/xxxx/xxxxx.c中,相关的移植文件中
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;( PHYS_SDRAM_1定义在smartarm3250.h中,代表SDRAM的起始物理地址)
设置gd->bd->bi_dram[0].size
这两个值的大小都是根据phyhwdesc.dramcfg 来设置的。

11。display_dram_config
//uboot/lib_arm/board.c
打印出DRAM的大小。
DRAM:  64 MiB

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yuanlulu/archive/2011/03/17/6256825.aspx

0 0
原创粉丝点击