您的位置:首页 > 产品设计 > UI/UE

uboot的init_sequence 分析

2013-12-29 01:23 302 查看
第一个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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: