在 uboot 第一阶段启动完成后将会调用 start_armboot 开始第二阶段的启动流程,这个阶段的代码由 c 语言编写,分析如下:
一、基础数据结构
第二阶段主要用到了两个数据结构即 gd_t 和 bd_t,其定义如下:
/* 全局数据结构 */
typedef struct global_data {
bd_t *bd; /* 指向板级信息结构 */
unsigned long flags; /* 标记位 */
unsigned long baudrate; /* 串口波特率 */
unsigned long have_console; /* serial_init() was called */
unsigned long env_addr; /* 环境参数地址 */
unsigned long env_valid; /* 环境参数 CRC 校验有效标志 */
unsigned long fb_base; /* fb 起始地址 */
#ifdef CONFIG_VFD
unsigned char vfd_type; /* 显示器类型(VFD代指真空荧光屏) */
#endif
#if 0
unsigned long cpu_clk; /* cpu 频率*/
unsigned long bus_clk; /* bus 频率 */
phys_size_t ram_size; /* ram 大小 */
unsigned long reset_status; /* reset status register at boot */
#endif
void **jt; /* 跳转函数表 */
} gd_t;
/* Global Data Flags */
#define GD_FLG_RELOC 0x00001 /* 代码已经转移到 RAM */
#define GD_FLG_DEVINIT 0x00002 /* 设备已经完成初始化 */
#define GD_FLG_SILENT 0x00004 /* 静音模式 */
#define GD_FLG_POSTFAIL 0x00008 /* Critical POST test failed */
#define GD_FLG_POSTSTOP 0x00010 /* POST seqeunce aborted */
#define GD_FLG_LOGINIT 0x00020 /* Log Buffer has been initialized */
#define GD_FLG_DISABLE_CONSOLE 0x00040 /* Disable console (in & out) */
/* 定义一个寄存器变量,占用寄存器r8,作为 gd_t 的全局指针 */
#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("r8")
/* 板级信息结构 */
typedef struct bd_info {
int bi_baudrate; /* serial console baudrate */
unsigned long bi_ip_addr; /* IP Address */
struct environment_s *bi_env; /* 板子的环境变量 */
ulong bi_arch_number; /* 板子的 id */
ulong bi_boot_params; /* 板子的启动参数 */
struct /* RAM 配置 */
{
ulong start;
ulong size;
} bi_dram[CONFIG_NR_DRAM_BANKS];
} bd_t;
/**************************************************************************
*
* 每个环境变量以形如"name=value"的字符串存储并以'\0'结尾,环境变量的尾部以两个'\0'结束。
* 新增的环境变量都依次添加在尾部,如果删除一个环境变量需要将其后面的向前移动
* 如果替换一个环境变量需要先删除再新增。
*
* 环境变量采用 32 bit CRC 校验.
*
**************************************************************************
*/
/* 我们平台定义了8kB大小的环境变量存储区,地址空间位于4M ~ 6M */
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET 0x00400000 /* 4M ~ 6M */
#define CONFIG_ENV_SIZE 8192 /* 8KB */
#define CONFIG_ENV_RANGE 0x00200000
#define ENV_SIZE (CONFIG_ENV_SIZE - ENV_HEADER_SIZE)
/* 环境变量结构 */
typedef struct environment_s {
uint32_t crc; /* CRC32 over data bytes */
#ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT
unsigned char flags; /* active/obsolete flags */
#endif
unsigned char data[ENV_SIZE]; /* Environment data */
} env_t;
这两个类型变量记录了刚启动时的信息,还将记录作为引导内核和文件系统的参数,如 bootargs 等,并且将来还会在启动内核时,由 uboot 交由 kernel 时会有所用。
二、启动流程
1、init_sequence
start_armboot 首先为全局数据结构和板级信息结构分配内存,代码如下:
#define CONFIG_UNCONTINUOUS_MEM
#define CONFIG_SYS_MALLOC_END (MDDR_BASE_ADDR + 0x006000