之前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经常被访问,因此放在寄存器中提升访问效率。
<code>gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - </code>
<code> </code><code>sizeof</code><code>(gd_t);</code>
//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的位置处
<code>gd = (gd_t*)gd_base;</code>
//上面已经得到gd_base是一个内存地址,然后通过强制类型转换使其变为一个指针,并赋给gd,使得gd指向这段内存空间
<code>memset</code> <code>((</code><code>void</code><code>*)gd, 0, </code><code>sizeof</code> <code>(gd_t)); </code>
<code>gd->bd = (bd_t*)((</code><code>char</code><code>*)gd - </code><code>sizeof</code><code>(bd_t));</code>
<code> </code><code>memset</code> <code>(gd->bd, 0, </code><code>sizeof</code> <code>(bd_t));</code>
上面提到的gd只是一个指针,而并没有给它分配内存空间,并在使用之前对这片内存清零。后面使用了类似的方法给bd分配内存空间,并在使用前进行对这片内存空间进行清零。通过分析可知,gd就在bd的上面,两片内存空间紧挨着(中间隔了bd的大小)
<code>typedef</code> <code>struct</code> <code>bd_info {</code>
<code> </code><code>int</code> <code>bi_baudrate; </code><code>/* serial console baudrate */</code>
<code> </code><code>unsigned </code><code>long</code> <code>bi_ip_addr; </code><code>/* IP Address */</code>
<code> </code><code>unsigned </code><code>char</code> <code>bi_enetaddr[6]; </code><code>/* Ethernet adress */</code>
<code> </code><code>struct</code> <code>environment_s *bi_env;</code>
<code> </code><code>ulong bi_arch_number; </code><code>/* unique id for this board */</code>
<code> </code><code>ulong bi_boot_params; </code><code>/* where this board expects params */</code>
<code> </code><code>struct</code> <code>/* RAM configuration */</code>
<code> </code><code>{</code>
<code> </code><code>ulong start;</code>
<code> </code><code>ulong size;</code>
<code> </code><code>} bi_dram[CONFIG_NR_DRAM_BANKS];</code>
<code> </code>
<code> </code><code>typedef</code> <code>struct</code> <code>global_data {</code>
<code> </code><code>bd_t *bd;</code>
<code> </code><code>unsigned </code><code>long</code> <code>flags;</code>
<code> </code><code>unsigned </code><code>long</code> <code>baudrate;</code>
<code> </code><code>unsigned </code><code>long</code> <code>have_console; </code><code>/* serial_init() was called */</code>
<code> </code><code>unsigned </code><code>long</code> <code>reloc_off; </code><code>/* Relocation Offset */</code>
<code> </code><code>unsigned </code><code>long</code> <code>env_addr; </code><code>/* Address of Environment struct */</code>
<code> </code><code>unsigned </code><code>long</code> <code>env_valid; </code><code>/* Checksum of Environment valid? */</code>
<code> </code><code>unsigned </code><code>long</code> <code>fb_base; </code><code>/* base address of frame buffer */</code>
以上便是gd和bd这个两个全局变量指向的结构体的内容
本文转自 菜鸟养成记 51CTO博客,原文链接:http://blog.51cto.com/11674570/1834517