uboot中重要的全局变量——gd

1、gd变量的定义和声名

#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
解析:
(1)gd是一个gd_t类型的全局变量,用宏的方式来声明这个变量是方便使用,在要使用gd变量的文件里添加这个宏即可。
(2)register:希望gd变量尽可能放在寄存器里;
(3)volatile:指明这个变量是易变的,每次使用gd变量时都去地址处读取,不要使用缓存的gd变量的值;
(4)gd_t:gd变量时gd_t类型;
(5)asm (“r8”):用r8寄存器来存放gd变量
备注:这个宏只是定义了gd指针变量,还没有给该指针赋值;

2、gd变量的赋值

2.1、摘抄自uboot中对gd变量的赋值

	#ifdef CONFIG_ENABLE_MMU
	#define CFG_UBOOT_BASE		0xc3e00000
	#else
	#define CFG_UBOOT_BASE		0x33e00000  /*yan*/
	#endif

	/* total memory required by uboot */
	#define CFG_UBOOT_SIZE		(2*1024*1024)

	#define CFG_ENV_SIZE		0x4000	/* Total Size of Environment Sector */
	#define CFG_MALLOC_LEN		(CFG_ENV_SIZE + 896*1024) //16k+896k=912k

	#define CFG_STACK_SIZE		512*1024

	ulong gd_base;
	gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t); //为全局变量gd找合适的内存
	gd = (gd_t*)gd_base; 
	memset ((void*)gd, 0, sizeof (gd_t));
	gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
	memset (gd->bd, 0, sizeof (bd_t));

2.2、分析uboot中对gd变量的赋值

uboot此时还没有初始化堆管理器,意味着没人帮我们管理内存,不能直接malloc内存赋值给gd。整个内存现在需要我们手动去管理,我们要对内存有规划的使用,确保gd指向的内存空闲并且不会和其他地方冲突。下面是内存规划的示意图:
(1)CFG_UBOOT_BASE:uboot的链接地址,uboot会被重定位到此地址;
(2)CFG_UBOOT_SIZE:这个是我们预留给uboot使用的空间大小;
(3)CFG_MALLOC_LEN:给堆管理器预留的空间大小,将来这部分内存会用堆管理器来管理,堆管理器初始化之后就可以用malloc和free来使用内存;
(4)CFG_ENV_SIZE:给环境变量预留的内存,将来用malloc来申请;
(5)CFG_STACK_SIZE:栈的大小;
(6)sizeof(gd_t):gd_t结构体大小
(7)sizeof(bd_t):bd_t结构体大小

在这里插入图片描述

3、相关的结构体

	typedef struct environment_s {
    
    
		ulong crc;			/* CRC32 over data bytes    */
		unsigned char flags;		/* active or obsolete */
		char *data;
	} env_t;

	typedef struct bd_info {
    
    
		int			bi_baudrate;	/* 串口/控制台波特率 */
		unsigned long	bi_ip_addr;	/* 默认的ip地址 */
		unsigned char	bi_enetaddr[6]; /* MAC地址 */
		struct environment_s	       *bi_env; /*环境变量*/
		ulong	        bi_arch_number;	/*板级ID*/
		ulong	        bi_boot_params;	/* 传递给内核启动参数所在的内存地址 */
		struct				/* RAM configuration */
		{
    
    
		ulong start;
		ulong size;
		}bi_dram[CONFIG_NR_DRAM_BANKS];/*每片内存的地址地址和大小*/

	} bd_t;
	
	typedef	struct	global_data {
    
    
		bd_t		*bd;	/*开发板的相关信息*/
		unsigned long	flags;	/*标志位*/
		unsigned long	baudrate;	/*串口/控制台波特率,和bd里的波特率是一样的*/
		unsigned long	have_console;	/* 是否有控制台 */
		unsigned long	reloc_off;	/* 偏移量 */
		unsigned long	env_addr;	/* 环境变量所在的地址 */
		unsigned long	env_valid;	/* 环境变量的有效标志位 */
		unsigned long	fb_base;	/* LCD显示的缓存 */
		void		**jt;		/* 跳转表 */
	} gd_t;

おすすめ

転載: blog.csdn.net/weixin_42031299/article/details/121199471