您的位置:首页 > 理论基础 > 数据结构算法

简单分析一下uboot的主要数据结构

2011-01-06 15:44 453 查看
转自http://zqwt.012.blog.163.com/blog/static/12044684201031385921253/

//现在,我们可以简单分析一下uboot的主要数据结构
//uboot的主要功能是引导OS的,但是本身也提供强大的其他功能,可以通过输入命令来完成许多操作,所以它本身也是一个比较完备的系统。
//uboot的大部分操作都是围绕其自身的数据结构,这些数据结构都是通用的,但是不同的板子初始化这些数据就不一样了,所以uboot的通用
//代码是依赖与这些重要的数据结构的。我们这里所分析的数据结构就是一些全局变量。下面,我们来开始分析:

1、global data数据结构定义,即全局数据变量指针,它保存了uboot运行需要的全局数据,位于文件 include/asm-arm/global_data.h
#ifndef __ASM_GBL_DATA_H
#define __ASM_GBL_DATA_H
/*
* The following data structure is placed in some memory which is
* 下面的一个数据结构被放置在内存中,在boot之后很早就可以允许对全局变量最小的设置,在系统初始化话阶段(直到我们已经设置好了内存控制器,以便于我们可以用RAM了)
* available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
* some locked parts of the data cache) to allow for a minimum set of
* global variables during system initialization (until we have set
* up the memory controller so that we can use RAM).
*
* Keep it *SMALL* and remember to set CFG_GBL_DATA_SIZE > sizeof(gd_t)
*
* CFG_GBL_DATA_SIZE在config文件中定义,start.S中会根据这个值分配栈空间给global_data,参见对start.S的分析stack_setup部分
*/

typedef struct global_data {
bd_t *bd; /* board info, 参见 include/asm-arm/u-boot.h */ //板子数据指针
unsigned long flags; //指示标志,如设备已经初始化标志等待
unsigned long baudrate; //串口波特率
unsigned long have_console; /* serial_init() was called 串口初始化标志 */
unsigned long reloc_off; /* Relocation Offset 重定位偏移,就是实际定向的位置与编译链接时指定的位置之差,一般为0 */
unsigned long env_addr; /* Address of Environment struct 环境参数地址*/
unsigned long env_valid; /* Checksum of Environment valid 环境参数CRC检验有效标志 */
unsigned long fb_base; /* base address of frame buffer 帧缓冲基地址 */
#ifdef CONFIG_VFD
unsigned char vfd_type; /* display type */
#endif
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 */
void **jt; /* jump table 跳转表,1.1.6中用来函数调用地址登记 */
} gd_t;

/*
* Global Data Flags 全局数据标志
*/
#define GD_FLG_RELOC 0x00001 /* Code was relocated to RAM */
#define GD_FLG_DEVINIT 0x00002 /* Devices have been initialized */
#define GD_FLG_SILENT 0x00004 /* Silent mode */

#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
/* 定义gd为gd_t类型指针,存储在寄存器r8中 */
/* register:表示变量对于执行速度非常重要,因此应该放在机器的寄存器中(寄存器独立于内存,通常在处理器芯片上) */
/* volatile:用于指定变量的值可以由外部过程异步修改,例如中断例程 */

#endif /* __ASM_GBL_DATA_H */

2、board info数据结构定义,即板子数据指针(板子有很多重要的参数),位于文件 include/asm-arm/u-boot.h
#ifndef _U_BOOT_H_
#define _U_BOOT_H_ 1

typedef struct bd_info {
int bi_baudrate; /* serial console baudrate 串口波特率*/
unsigned long bi_ip_addr; /* IP Address IP地址*/
unsigned char bi_enetaddr[6]; /* Ethernet adress MAC地址*/
struct environment_s *bi_env; /* environment struct 环境变量结构 */
ulong bi_arch_number; /* unique id for this board 标识这个板子的ID */
ulong bi_boot_params; /* where this board expects params 启动参数 */

struct /* RAM configuration RAM配置 */
{
ulong start;
ulong size;
} bi_dram[CONFIG_NR_DRAM_BANKS]; /* 每个DRAM bank的起始地址和大小,CONFIG_NR_DRAM_BANKS 定义DRAM的bank数 */
} bd_t;

#define bi_env_data bi_env->data
#define bi_env_crc bi_env->crc

#endif /* _U_BOOT_H_ */

3、环境变量指针 env_t *env_ptr = (env_t *)(&environment[0]); 该指针位于/common/env_flash.c

#include <common.h>

#if defined(CFG_ENV_IS_IN_FLASH) /* Environment is in Flash */

#include <command.h>
#include <environment.h>
#include <linux/stddef.h>
#include <malloc.h>

DECLARE_GLOBAL_DATA_PTR;

.............................

//可以在此加一个超链接,指向/common/env_flash.c这个源文件
env_t *env_ptr = (env_t *)(&environment[0]); //环境变量指针
//env_ptr指向环境参数区,系统启动时默认的环境参数environment[],定义在common/environment.c中。

............................

//这里列出common/environment.c的部分内容:

#ifndef __ASSEMBLY__
#define __ASSEMBLY__ /* Dirty trick to get only #defines */
#endif
#define __ASM_STUB_PROCESSOR_H__ /* don't include asm/processor. */
#include <config.h>
#undef __ASSEMBLY__
#include <environment.h>

..............................

env_t environment __PPCENV__ = {
ENV_CRC, /* CRC Sum */
#ifdef CFG_REDUNDAND_ENVIRONMENT
1, /* Flags: valid */
#endif
{
#if defined(CONFIG_BOOTARGS)
"bootargs=" CONFIG_BOOTARGS "/0" //定义传递给Linux内核的命令行参数
#endif
#if defined(CONFIG_BOOTCOMMAND)
"bootcmd=" CONFIG_BOOTCOMMAND "/0" //定义自动启动时执行的几条命令
#endif
#if defined(CONFIG_RAMBOOTCOMMAND)
"ramboot=" CONFIG_RAMBOOTCOMMAND "/0"
#endif
#if defined(CONFIG_NFSBOOTCOMMAND)
"nfsboot=" CONFIG_NFSBOOTCOMMAND "/0"
#endif
#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
"bootdelay=" MK_STR(CONFIG_BOOTDELAY) "/0" //定义执行自动启动的等候秒数
#endif
#if defined(CONFIG_BAUDRATE) && (CONFIG_BAUDRATE >= 0)
"baudrate=" MK_STR(CONFIG_BAUDRATE) "/0" //定义串口控制台的波特率
#endif
#ifdef CONFIG_LOADS_ECHO
"loads_echo=" MK_STR(CONFIG_LOADS_ECHO) "/0"
#endif
#ifdef CONFIG_ETHADDR
"ethaddr=" MK_STR(CONFIG_ETHADDR) "/0" //定义以太网接口的MAC地址
#endif
#ifdef CONFIG_ETH1ADDR
"eth1addr=" MK_STR(CONFIG_ETH1ADDR) "/0"
#endif
#ifdef CONFIG_ETH2ADDR
"eth2addr=" MK_STR(CONFIG_ETH2ADDR) "/0"
#endif
#ifdef CONFIG_ETH3ADDR
"eth3addr=" MK_STR(CONFIG_ETH3ADDR) "/0"
#endif
#ifdef CONFIG_ETHPRIME
"ethprime=" CONFIG_ETHPRIME "/0"
#endif
#ifdef CONFIG_IPADDR
"ipaddr=" MK_STR(CONFIG_IPADDR) "/0" //定义IP地址
#endif
#ifdef CONFIG_SERVERIP
"serverip=" MK_STR(CONFIG_SERVERIP) "/0"
#endif
#ifdef CFG_AUTOLOAD
"autoload=" CFG_AUTOLOAD "/0"
#endif
#ifdef CONFIG_ROOTPATH
"rootpath=" MK_STR(CONFIG_ROOTPATH) "/0"
#endif
#ifdef CONFIG_GATEWAYIP
"gatewayip=" MK_STR(CONFIG_GATEWAYIP) "/0" //定义网关
#endif
#ifdef CONFIG_NETMASK
"netmask=" MK_STR(CONFIG_NETMASK) "/0" //定义子网掩码
#endif
#ifdef CONFIG_HOSTNAME
"hostname=" MK_STR(CONFIG_HOSTNAME) "/0"
#endif
#ifdef CONFIG_BOOTFILE
"bootfile=" MK_STR(CONFIG_BOOTFILE) "/0" //定义缺省的下载文件
#endif
#ifdef CONFIG_LOADADDR
"loadaddr=" MK_STR(CONFIG_LOADADDR) "/0"
#endif
#ifdef CONFIG_PREBOOT
"preboot=" CONFIG_PREBOOT "/0"
#endif
#ifdef CONFIG_CLOCKS_IN_MHZ
"clocks_in_mhz=" "1" "/0"
#endif
#if defined(CONFIG_PCI_BOOTDELAY) && (CONFIG_PCI_BOOTDELAY > 0)
"pcidelay=" MK_STR(CONFIG_PCI_BOOTDELAY) "/0"
#endif
#ifdef CONFIG_EXTRA_ENV_SETTINGS
CONFIG_EXTRA_ENV_SETTINGS
#endif
"/0" /* Term. env_t.data with 2 NULs */
}
};
//还有三个参数:stdin、stdout、stderr
//分别定义标准输入设备、标准输出设备、标准出错信息输出设备。这三者一般情况下使用的是串口。

4、设备相关

//标准IO设备数组
//设备列表
//device_t的定义:include/devices.h

#include <lists.h>

#ifndef _DEVICES_H_
#define _DEVICES_H_

/*
* CONSOLE DEVICES
*/

#define DEV_FLAGS_INPUT 0x00000001 /* Device can be used as input console */
#define DEV_FLAGS_OUTPUT 0x00000002 /* Device can be used as output console */
#define DEV_FLAGS_SYSTEM 0x80000000 /* Device is a system device */
#define DEV_EXT_VIDEO 0x00000001 /* Video extensions supported */

/* Device information */
typedef struct {
int flags; /* Device flags: input/output/system */
int ext; /* Supported extensions */
char name[16]; /* Device name */

/* GENERAL functions */

int (*start) (void); /* To start the device */
int (*stop) (void); /* To stop the device */

/* OUTPUT functions 输出函数 */

void (*putc) (const char c); /* To put a char */
void (*puts) (const char *s); /* To put a string (accelerator) */

/* INPUT functions 输入函数 */

int (*tstc) (void); /* To test if a char is ready... */
int (*getc) (void); /* To get that char */

/* Other functions */

void *priv; /* Private extensions */
} device_t;

/*
* VIDEO EXTENSIONS
*/
#define VIDEO_FORMAT_RGB_INDEXED 0x0000
#define VIDEO_FORMAT_RGB_DIRECTCOLOR 0x0001
#define VIDEO_FORMAT_YUYV_4_4_4 0x0010
#define VIDEO_FORMAT_YUYV_4_2_2 0x0011

typedef struct {
void *address; /* Address of framebuffer */
ushort width; /* Horizontal resolution */
ushort height; /* Vertical resolution */
uchar format; /* Format */
uchar colors; /* Colors number or color depth */
void (*setcolreg) (int, int, int, int);
void (*getcolreg) (int, void *);
} video_ext_t;

//uboot把可以用为控制太输入输出的设备添加到设备列表devlist,并把当前用作标准IO的设备指针加入到stdio_devices数组中去
//在调用标准IO函数如printf()时将调用stdio_devices数组对应设备的IO函数如putc()

...........................................


1人 | 分享到:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: