bd_t gd_t 及board.c的分析

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 (  ;  ;  );
}


linux u-boot源码地址段分析图:

猜你喜欢

转载自blog.csdn.net/qinglongzhan/article/details/79028426
T