u-boot移植随笔:一些内存地址的研究(gd_t和bd_t结构体)

如果在./arch/arm/lib/board.c文件中定义了DEBUG宏的话,在u-boot启动时就会打印u-boot映像在内存中地址以及其它一些信息。如:

可以看到u-boot在内存中的地址为33F80000。这个地址可以在相应的开发板(我的是smdk2440目录)中的config.mk文件中找到说明。在编译生成的System.map文件中第一行为:33f80000 T _start

 

使用md.b查看这个地址,可以看到:

如果使用UltraEdit打开编译生成的u-boot.bin文件,可以发现前面4行的内容是一样的。因为u-boot启动时将自己搬到了33f80000这个地址了。

在很久以前我写了个测试u-boot内存分布的例子,里面将gd_t和bd_t结构体的地址打印出来了。——其实,前天遇到那个未定义指令的错误中就包含有大量有用的信息。

在代码中经常看到一个宏:

DECLARE_GLOBAL_DATA_PTR;

它就是将gd_t结构体地址放到寄存器r8中,这里看到r8的内容是33f4ffe0(至于其它寄存器的内容,这里不说了)。好,查看一下这个地址:

我们知道,bd_t是一个结构体(这是废话)。它的定义如下:

它的sizeof为32,这在前面的文章中证明了——4(大小)*8(成员) = 32。

现在就对照一下前面看到的地址中的内容,看看这个结构体变成了怎么样了(ARM默认为小端模式(?),而看到的地址是增长的,因此看到的数据都是反过来的)。

1、bd:指向bd_t的指针。c4 ff f4 33=>0x33f4ffc4,即bd_t结构体的地址(这里,指针占4字节)。
2、flags:标志,说明见下。03 00 00 00=>3,即flags为3,gd->flags |= GD_FLG_RELOC(宏定义,值为1)(board.c),gd->flags |= GD_FLG_DEVINIT(宏定义,值为2)(console.c),它们分别表示代码已经加载(relocate)到RAM、设备已经初始化好了。
3、baudrate:波特率。00 c2 01 00=> 0x1c200,即115200(dec),表示波特率为115200。
4、have_console:是否有控制台(终端,或串口之类的),01 00 00 00=>1,表示调用了serial_init函数。
5、env_addr:环境变量的地址,0c 00 f5 33=>0x33f5000c,环境变量结构体地址(就是看到的bootxxx那个地址)。
6、env_valid:环境变量checksum有效乎?01 00 00 00=>1,环境变量checksum有效。
7、fb_base:frame buffer的基地址,00 00 00 00=>0,暂时没有研究。
8、jt:一个jump table,50 00 f6 33=>0x33f60050,jump table有待研究。(查看这个地址得到许多其它的“地址”,见下)

(注:关于env_addr和env_valid在代码中的用法,见./common/env_common.c中代码。)

 

我们再来看看bd_t结构体地址:

它的定义如下:

它的sizeof为28,同样在前面的文章中证实了。

我们也分析一下:

1、bi_baudrate:波特率,00 c2 01 00=> 0x1c200,即115200(dec),表示波特率为115200。
2、bi_ip_addr:c0 a8 01 c8=> 十进制为:192 168 1 200,即服务器IP地址(注意:网络为大端模式)。 gd->bd->bi_ip_addr

= getenv_IPaddr ("ipaddr");(board.c)

3、bi_env:环境变量?00 00 00 00=> 0,没研究过。
4、bi_arch_number:machine type id。f0 03 00 00=>0x000003f0,开发板机器ID,即1008(MACH_TYPE_SMDK2440),gd->bd->bi_arch_number = MACH_TYPE_SMDK2440; (smdk2440.c)
5、bi_boot_params:准确地说,这是启动参数的地址,00 01 00 30=>0x30000100,gd->bd->bi_boot_params =0x30000100;(smdk2440.c),与内核中需要一致。
6、start:内存起始地址,00 00 00 30=>0x30000000,RAM起始地址,即0x30000000。
7、size:内存大小,00 00 00 04=>0x04000000,RAM大小,64MB,来自config.mk文件的:SMDK2410(SMDK2440亦一样) has 1 bank of 64 MB DRAM

8、04 c4 ff f4 33 就是gd_t结构体的地址了,前面分析过了。

 

其实不用这么麻烦的,直接在u-boot下输入db就可以查看开发板的一些信息了(看代码就知道,其实两种方法没本质的区别)。

 

前面说到的jump table的地址内容是这样的:

里面就是一些33f8xxxx地址,具体的,查了也没什么发现。jump table留到以后有机会再看看。

 

这次的实验,加上以前画的那张图,结合起来,可以对u-boot在内存中分布有一些了解了。

 

补记(2011-3-20):

前面说的大端小端模式,有必要澄清一下:一个字节是最小的单位,因此它不可能存在大端小端的问题,这些模式只针对大于一个字节以上的数据,比如我们看到的地址是4个字节(32bit),因此md.b看到的数据就要反过来,但是像环境变量这些可读字符,不能用这个规则来读,即我们看到的、在内存显示的,就是它们实际的形式。

 

2011-3-22记:

经过初步测试,发现jump table里面的地址是一些常用函数,或者称为库函数,如33f8c824地址是get_version函数。其它的如serial_getc、serial_puts、printf、malloc、free、getenv、setenv、i2c_write、i2c_read,等等。参见exports.c、exports.h和_exports.h等等文件。

                                                                                                                                             木草山人于3.07

©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页