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

转自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   分享到:          
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值