init_sequence

第一个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架构相关的函数。
这个函数一般定义在arch/arm/cpu/arm926ejs/lpc3250/cpu.c中。3250目前不支持。
这个函数所做的工作是和cpu架构相关,比如使能cache,定义端口电压等。
2。board_init
板级初始化函数。在board/zhiyuan/smartarm3250/smart3250.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 */
typedefstructglobal_data {
bd_t*bd;
unsigned longflags;
unsigned longbaudrate;
unsigned longhave_console;/* serial_init() was called */
unsigned longenv_addr;/* Address of Environment struct */
unsigned longenv_valid;/* Checksum of Environment valid? */
unsigned longfb_base;/* base address of frame buffer */
#ifdef CONFIG_VFD
unsigned charvfd_type;/* display type */
#endif
#ifdef CONFIG_FSL_ESDHC
unsigned longsdhc_clk;
#endif
#if 0
unsigned longcpu_clk;/* CPU clock in Hz!*/
unsigned longbus_clk;
phys_size_tram_size;/* RAM size */
unsigned longreset_status;/* reset status register at boot */
#endif
void**jt;/* stdio的跳转表*/
} gd_t;

(arch/arm/include/asm/u-boot.h)
typedef struct bd_info {
intbi_baudrate;/* serial console baudrate */
unsigned longbi_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_nand.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[] = {
#ifdefCONFIG_BOOTARGS
"bootargs="CONFIG_BOOTARGS"\0"
#endif
#ifdefCONFIG_BOOTCOMMAND
"bootcmd="CONFIG_BOOTCOMMAND"\0"
#endif
#ifdefCONFIG_RAMBOOTCOMMAND
"ramboot="CONFIG_RAMBOOTCOMMAND"\0"
#endif
#ifdefCONFIG_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
#ifdefCONFIG_LOADS_ECHO
"loads_echo="MK_STR(CONFIG_LOADS_ECHO)"\0"
#endif
#ifdefCONFIG_ETHADDR
"ethaddr="MK_STR(CONFIG_ETHADDR)"\0"
#endif
#ifdefCONFIG_ETH1ADDR
"eth1addr="MK_STR(CONFIG_ETH1ADDR)"\0"
#endif
#ifdefCONFIG_ETH2ADDR
"eth2addr="MK_STR(CONFIG_ETH2ADDR)"\0"
#endif
#ifdefCONFIG_ETH3ADDR
"eth3addr="MK_STR(CONFIG_ETH3ADDR)"\0"
#endif
#ifdefCONFIG_ETH4ADDR
"eth4addr="MK_STR(CONFIG_ETH4ADDR)"\0"
#endif
#ifdefCONFIG_ETH5ADDR
"eth5addr="MK_STR(CONFIG_ETH5ADDR)"\0"
#endif
#ifdefCONFIG_IPADDR
"ipaddr="MK_STR(CONFIG_IPADDR)"\0"
#endif
#ifdefCONFIG_SERVERIP
"serverip="MK_STR(CONFIG_SERVERIP)"\0"
#endif
#ifdefCONFIG_SYS_AUTOLOAD
"autoload="CONFIG_SYS_AUTOLOAD"\0"
#endif
#ifdefCONFIG_PREBOOT
"preboot="CONFIG_PREBOOT"\0"
#endif
#ifdefCONFIG_ROOTPATH
"rootpath="MK_STR(CONFIG_ROOTPATH)"\0"
#endif
#ifdefCONFIG_GATEWAYIP
"gatewayip="MK_STR(CONFIG_GATEWAYIP)"\0"
#endif
#ifdefCONFIG_NETMASK
"netmask="MK_STR(CONFIG_NETMASK)"\0"
#endif
#ifdefCONFIG_HOSTNAME
"hostname="MK_STR(CONFIG_HOSTNAME)"\0"
#endif
#ifdefCONFIG_BOOTFILE
"bootfile="MK_STR(CONFIG_BOOTFILE)"\0"
#endif
#ifdefCONFIG_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 */
初始化波特率设置。定义在arch/arm/lib/board.c
设置gd->bd->bi_baudrate 和gd->baudrate为定义的波特率。

7。serial_init
定义在arch/arm/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;
}

8.display_banner,
/* say that we are here */arch/arm/lib/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)
9。dram_init,
/* configure available RAM banks *///board/zhiyuan/smartarm3250/smart3250.c中
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;( PHYS_SDRAM_1定义在smartarm3250.h中,代表SDRAM的起始物理地址)
设置gd->bd->bi_dram[0].size
这两个值的大小都是根据phyhwdesc.dramcfg 来设置的。

10。display_dram_config
//arch/arm/lib/board.c
打印出DRAM的大小。
DRAM: 64 MiB


总结:
除了对cache、时钟、NAND控制器和串口的硬件进行了初始化,其他的工作都是初始化一些环境和全局变量。

你可能感兴趣的:(C++,c,cache,C#,F#)