天天看点

uboot移植(五)——uboot启动的第二阶段(gd和bd)

   之前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-&gt;bd = (bd_t*)((</code><code>char</code><code>*)gd - </code><code>sizeof</code><code>(bd_t));</code>

<code> </code><code>memset</code> <code>(gd-&gt;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

继续阅读