Chinaunix首页 | 论坛 | 博客
  • 博客访问: 88211
  • 博文数量: 26
  • 博客积分: 404
  • 博客等级: 一等列兵
  • 技术积分: 200
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-15 12:50
文章分类
文章存档

2011年(24)

2009年(2)

分类: 嵌入式

2011-11-08 12:54:48

转自:~xiaoshe/2010/01/03/u-boot%E7%9A%84%E5%86%85%E5%AD%98%E5%88%86%E5%B8%83%E5%92%8C%E5%85%A8%E5%B1%80%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/

U-boot,除非在RAM中调试,一般情况下都是从flash中执行一段代码,然后将flash中储存的代码和数据搬移到ram中,然后跳转到ram中执行。当然这应该也是一般的bootloader的执行方式,大家都差不多,但是各个bootloader的内存规划(栈,堆之类的)也 不太一样,而且u-boot还在内存空间中规划了一些用于存放环境变量和一些数据结构的空间,所以如果不了解一下的话,直接看代码的话就会有一点迷糊。有必要先介绍一下。

关于u-boot的内存分布,或者说内存映射,网上有人画了一幅图,比较的清晰,如下:

上面的图上其实漏了一个部分,就是在flash中,一般情况在紧跟U-boot映像的后面,还有一个存放环境变量的区域(不过这个区域好像是可选可不选的),一般都是在flash中取一个sector来存放环境变量。

  • U-boot映像:U-boot烧写进flash的映像,在uboot的术语中,这部分的大小叫做monitor_size.所以在uboot中,这个二进制文件就叫做monitor.这个U-boot映像会被运送到RAM中,从图中也可以看见RAM中有一块也是U-boot映像。
  • 环境变量区域:环境变量存放在flash和RAM中各一份,在flash中一般存放在紧随Monitor也即U-boot镜像的下一个sector中,存储一些诸如IP地址等信息,在程序被拷贝到RAM中时,环境变量也同时被拷贝到RAM中。
  • CFG_MALLOC_LEN:这个区域是用来存放堆数据和环境变量的,这个区域是紧接着RAM中的U-boot镜像的,从图中也可以看出,在U-boot的基地址往下开辟了这一段区域。环境变量在本来保存在FLASH中,在系统初始化的时候,flash中的这些环境变量也同样被复制到RAM中,在系统运行的时候,可以修改RAM中的值来改变系统的环境变量,但是掉电重启后,还是用的FLASH中的设定值,当然也可以写flash来改变默认的环境变量。
  • GBL_DATA_SIZE:这个区域是紧接着CFG_MALLOC_LEN数据段的,从图上也可以看出来,这一段是用来存放一个gd_t数据结构的,这个数据是一个uboot中用到的数据结构,用来存放系统的一些信息,在下面会列出这个数据结构
  • 另外,在SDRAM_BASE开始的地址上,一般存放着二级跳转中断向量,这些中断向量一般是用来为uclinux等操作系统用的。
  • 其他的如栈的分布如上图所示。

下面列出在uboot中使用的gt_d数据结构的定义(arm系统):

值的含义也是比较的直观

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 */
#ifdef CONFIG_VFD
unsigned char   vfd_type;       /* display type */
#endif
#if 0
unsigned long   cpu_clk;        /* CPU clock in Hz!             */
unsigned long   bus_clk;
unsigned long   ram_size;       /* RAM size */
unsigned long   reset_status;   /* reset status register at boot */
#endif
void            **jt;           /* jump table */
} gd_t;

其中flags的可选项如下:

/*
* Global Data Flags
*/
#define GD_FLG_RELOC    0×00001         /* Code was relocated to RAM            */
#define GD_FLG_DEVINIT  0×00002         /* Devices have been initialized        */
#define GD_FLG_SILENT   0×00004         /* Silent mode                          */

其中bd_t数据结构的定义如下:

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];
#ifdef CONFIG_HAS_ETH1
/* second onboard ethernet port */
unsigned char   bi_enet1addr[6];
#endif
} bd_t;

------------------------------------------------------------------------------

关于数据区的一些说明:

  1. 注意:

  2. l bss段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小。

  3. 2 data(已手动初始化的数据)段则为数据分配空间,数据保存在目标文件中。

  4. 3 data段包含经过初始化的全局变量以及它们的值。

  5. 4 bss段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段后面。当这个内存区进入程序的地址空间后全部清零。包含DATA和BSS段的整个区段此时通常称为数据区。

 

 

阅读(2446) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~