bd_t gd_t 及board.c的分析

本文详细解析了U-Boot的初始化过程,包括关键数据结构gd_t和bd_t的定义及使用,以及启动函数start_armboot的具体实现。通过分析U-Boot如何设置硬件参数和初始化各个设备,为读者提供了深入理解U-Boot工作原理的基础。
摘要由CSDN通过智能技术生成
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源码地址段分析图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>