之前uboot启动第一阶段的最后将指针指向了start_armboot这个函数,这里也
是uboot启动的第二阶段的开始并且uboot启动第二阶段大部分是在这个函数中完成
的。
DECLARE_GLOBAL_DATA_PTR;这个宏在大部分中的文件中都有这个宏,这个宏的
实际定义是在include/asm-arm/Global_data.h
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
这个宏的意思是:定义了一个全局变量名字为gd,这个全局变量是一个指针类型,占4个字节,用volatile修饰表示可变的;用register修饰表示这个变量要尽量放到寄存器中去;asm("r8")是gcc支持的一种语法,意思是要把gd放到寄存器r8中。
综合分析:DECLARE_GLOBAL_DATA_PTR就是定义了一个要放在寄存器r8中的全局变量,名字叫gd,类型是一个指向gd_t类型变量的指针。gd_t中定义了很多全局变量,都是整个uboot使用的,其中有一个bd_t类型的指针bd,指向结构体bd_info,这个结构体里面定义的是和开发板硬件先关的全局变量(譬如 ip地址 串口波特率 等)
全局变量gd是uboot中很重要的一个全局变量(准确的说这个全局变量是一个结构体,里面有很多内容,这些内容加起来构成的结构体就是uboot中常用的所有全局变量),由于gd经常被访问,因此放在寄存器中提升访问效率。
gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t);
//uboot区:CFG_UBOOT_BASE (33e00000)+CFG_UBOOT_SIZE(uboot的实际大小,我们这里给了2M)
//堆区:长度为CFG_MALLOC_LEN ,实际长度为912KB
//栈区:长度为CFG_STACK_SIZE,实际长度为512KB
//gd:长度为sizeof(gd_t),实际为36字节
//bd:长度为sizeof(bd_t),实际长度为44字节左右
//所以gd_base的大概位置是离uboot起始地址(33e00000)往上走624KB的位置处
gd = (gd_t*)gd_base;
//上面已经得到gd_base是一个内存地址,然后通过强制类型转换使其变为一个指针,并赋给gd,使得gd指向这段内存空间
memset ((void*)gd, 0, sizeof (gd_t)); gd->bd = (bd_t*)((char*)gd - sizeof(bd_t)); memset (gd->bd, 0, sizeof (bd_t));
上面提到的gd只是一个指针,而并没有给它分配内存空间,并在使用之前对这片内存清零。后面使用了类似的方法给bd分配内存空间,并在使用前进行对这片内存空间进行清零。通过分析可知,gd就在bd的上面,两片内存空间紧挨着(中间隔了bd的大小)
typedef struct bd_info { int bi_baudrate; /* serial console baudrate */ unsigned long bi_ip_addr; /* IP Address */ unsigned char bi_enetaddr[6]; /* Ethernet adress */ struct environment_s *bi_env; ulong bi_arch_number; /* unique id for this board */ ulong bi_boot_params; /* where this board expects params */ struct /* RAM configuration */ { ulong start; ulong size; } bi_dram[CONFIG_NR_DRAM_BANKS]; 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 */
以上便是gd和bd这个两个全局变量指向的结构体的内容