天天看點

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

繼續閱讀