gd_t和bd_t是u-boot中两个重要的数据结构,在初始化操作很多都要靠这两个数据结构来保存或传递.分别定义在./include/asm/global_data.h和./include/asm/u_boot.h
1.gd_t: global data数据结构定义,位于文件 include/asm-arm/global_data.h。其成员主要是一些全局的系统初始化参数。需要用到时用宏定义:DECLARE_GLOBAL_DATA_PTR,指定占用寄存器R8。
2.bd_t : board info数据结构定义,位于文件 include/asm-arm/u-boot.h。保存板子参数。
#ifndef __ASM_GBL_DATA_H
#define __ASM_GBL_DATA_H
typedef struct global_data
{
bd_t *bd; //开发板相关参数,结构体变量,参考u-boot.h
unsigned long flags; //指示标志,如设备已经初始化标志等
unsigned long baudrate; //串行口通讯速率
unsigned long have_console;
unsigned long reloc_off;
unsigned longenv_addr;
unsigned longenv_valid;
unsigned longfb_base;
#ifdef CONFIG_VFD
unsigned charvfd_type;
#endif
#if 0
unsigned long cpu_clk;
unsigned long bus_clk; // 总线时钟
unsigned long ram_size;
unsigned long reset_status;
#endif
void **jt;
}gd_t;
#define GD_FLG_RELOC 0x00001
#define GD_FLG_DEVINIT 0x00002
#define GD_FLG_SILENT 0x00004
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
#endif
typedef struct bd_info {
int bi_baudrate;
unsigned long bi_ip_addr;
unsigned char bi_enetaddr[6];
struct environment_s *bi_env; //结构体变量定义见46行
ulong bi_arch_number;
ulong bi_boot_params;
struct
{
ulong start;
ulong size;
} bi_dram[CONFIG_NR_DRAM_BANKS];
}bd_t;
=====================================================================
=====================================================================
下面是lib_arm\board.c文件分析
typedef int (init_fnc_t) (void); //自定义数据类型
init_fnc_t *init_sequence[]= {
cpu_init,
board_init,
interrupt_init,
env_init,
init_baudrate,
serial_init,
console_init_f,
display_banner,
dram_init,
display_dram_config, //显示RAM的配置大小 -- lib_arm/board.c
#if defined(CONFIG_VCMA9)
checkboard,
#endif
NULL,
};
//整个u-boot的执行就进入等待用户输入命令,解析并执行命令的死循环中。
//start_armboot是U-Boot执行的第一个C语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。
void start_armboot (void)
{
DECLARE_GLOBAL_DATA_PTR;
ulong size;
init_fnc_t**init_fnc_ptr; //这个是函数的指针,指向==>硬件初始化的函数
char *s;
#if defined(CONFIG_VFD)
unsigned long addr;
#endif
#if CFG_LED_FLASH
LED();
#endif
gd = (gd_t*)(_armboot_start -CFG_MALLOC_LEN-sizeof(gd_t)); //计算出gd在RAM中的地址
memset ((void*)gd, 0, sizeof (gd_t)); //给全局数据变量gd安排空间,用0填充全局数据表*gd
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t)); //给板子数据变量gd->bd安排空间
memset (gd->bd, 0, sizeof (bd_t)); //gd区包含了bd区,gd_t,bd_t都是结构体变量,
//用0填充(初始化) *gd->bd board info数据结构定义,位于文件 include/asm-arm/u-boot.h
monitor_flash_len = _bss_start - _armboot_start; // 取u-boot的长度
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)
{
if ((*init_fnc_ptr)() != 0) {
hang (); //打印错误信息并死锁
}
}
size = flash_init (); //drivers/cfi_flash.c或自定义
display_flash_config (size);
#ifdef CONFIG_VFD //如果定义了VFD(真空荧光显示),就定义页面大小为4096B
# ifndef PAGE_SIZE
# define PAGE_SIZE 4096
# endif
addr = (_bss_start + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
size = vfd_setmem (addr);
gd->fb_base = addr; //全局数据gd中定义的帧缓冲区的基地址
#endif
mem_malloc_init (_armboot_start - CFG_MALLOC_LEN); //malloc使用的内存空间地址0x0c700000-129k(0x00080400)
#if (CONFIG_COMMANDS & CFG_CMD_NAND) //如果有nandflash的话就在下面的代码中进行初始化
puts ("NAND:");
nand_init();
#endif
#ifdef CONFIG_HAS_DATAFLASH
AT91F_DataflashInit();
dataflash_print_info();
#endif
env_relocate ();
#ifdef CONFIG_VFD
drv_vfd_init(); //vfd初始化,在分配帧缓冲区之后必须的
#endif
gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
{
int i;
ulong reg;
char *s, *e;
uchar tmp[64];
i = getenv_r ("ethaddr", tmp, sizeof (tmp));
s = (i > 0) ? tmp : NULL;
for (reg = 0; reg < 6; ++reg){
gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
if (s)
s = (*e) ? e + 1 : e;
}
}
devices_init ();
jumptable_init (); //跳转表初始化
console_init_r ();
#if defined(CONFIG_MISC_INIT_R)
misc_init_r ();
#endif
enable_interrupts ();
。。。。。。
for ( ; ; ){
main_loop (); //主循环函数处理执行用户命令 -- common/main.c
}
}
void hang (void)
{
puts ("### ERROR ### Please RESET the board ###\n"); //输出错误信息需要reset,进入死循环
for ( ; ; );
}