全局指针变量gd
DECLARE_GLOBAL_DATA_PTR;
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8") //定义了一个全局变量名字叫gd,这个全局变量是一个指针类型,占4字节。用volatile修饰表示可变的,用register修饰表示这个变量要尽量放到寄存器中,后面的asm("r8")是gcc支持的一种语法,意思就是要把gd放到寄存器r8中。
typedef struct global_data { bd_t *bd; /*板级信息*/ unsigned long flags; unsigned long baudrate; /*波特率*/ unsigned long have_console; /* serial_init() was called 控制台是否已经建立 */ unsigned long reloc_off; /* Relocation Offset 重定位时的偏移量 */ 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 #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; /* jump table 跳转表 */ } gd_t;
typedef struct bd_info { int bi_baudrate; /* serial console baudrate 波特率 */ unsigned long bi_ip_addr; /* IP Address IP地址 */ unsigned char bi_enetaddr[6]; /* Ethernet adress Mac地址 */ struct environment_s *bi_env; /*环境变量的指针*/ ulong bi_arch_number; /* unique id for this board 板子的机器码 */ ulong bi_boot_params; /* where this board expects params 启动参数的地址(uboot启动linux时要传给linux的参数) */ struct /* RAM configuration */ { ulong start; ulong size; } bi_dram[CONFIG_NR_DRAM_BANKS]; /*DRAM信息*/ #ifdef CONFIG_HAS_ETH1 /* second onboard ethernet port */ unsigned char bi_enet1addr[6]; #endif } bd_t;
这个全局变量gd(global data的简称)是uboot中很重要的一个全局变量(准确的说这个全局变量是一个结构体,里面有很多内容,这些内容加起来构成的结构体就是uboot中常用的所有的全局变量),这个gd在程序中经常被访问,因此放在register中提升效率。因此纯粹是运行效率方面考虑,和功能要求无关。并不是必须的。
gd_t中定义了很多全局变量,都是整个uboot使用的;其中有一个bd_t类型的指针,指向一个bd_t类型的变量,这个bd是开发板的板级信息的结构体,里面有不少硬件相关的参数,譬如波特率、IP地址、机器码、DDR内存分布。
start_armboot
- 定义函数指针数组init_fnc_ptr
init_fnc_t **init_fnc_ptr;
typedef int (init_fnc_t) (void); //init_fnc_t是一个函数类型
等效的我们可以写成如下这种形式
typedef int (* init_fnc_t) (void); //init_fnc_t是一个函数指针类型 init_fnc_t *init_fnc_ptr; //init_fnc_ptr是一个函数指针数组
- 全局指针变量gd和其成员bd的内存分配
(1)从之前的分析可知,uboot当前并没有初始化内存管理单元,所以此时要给gd和bd分配内存无法使用malloc之类的函数。只能人为的将它放置在一片固定的合适的地址空间中。
(2)gd_base表示将要为gd分配的内存的基地址
ulong gd_base; gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t); gd = (gd_t*)gd_base;
可见 gd前面是uboot自身部分(大概两百多KB),后面是堆(912KB)和栈(512KB)空间
(3)bd在gd空间前面紧挨着
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
&#