NULL, /* Terminate this list */ };
可以看到时钟,内存,串口,控制台等初始化函数的调用,其中串口的初始化要先于内存初始化。
2.7 relocate_code 函数
到目前为止,boot代码都是在Flash中运行,但是代码最终是要到RAM中运行的,在上面的board_init_f函数中已经将RAM初始化好了,具备了在RAM中运行程序的能力,现在relocate_code函数需要做两个事情:
1 从Flash中拷贝uboot的代码到RAM
2 记下现在执行代码的偏移,跳转到RAM中相应的位置执行。 2.8 board_init_r 函数
该函数为板级初始化的第二阶段,主要是初始化PCI,PCIE,网口,Flash等设备,关闭看门狗,把前面借dcache做堆栈的空间解锁,还给cache。在一切设备都初始化好后,便会进去main_loop的死循环中。
16
3 U-Boot 关键的数据结构
U-boot的主要功能是用于引导OS的,但是本身也提供了许多强大的功能,可以通过输入命令行来完成许多操作。所以它本身也是一个很完备的系统。U-boot的大部分操作都是围绕它自身的数据结构,这些数据结构是通用的,但是不同的板子初始化这些数据就不一样了。所有U-boot的通用代码是依赖于这些重要的数据结构的。 3.1 gd全局数据变量指针
它保存了U-boot运行需要的全局数据,类型定义:
typedef struct global_data {
bd_t *bd; //board data pointor板子数据指针
unsigned long flags; //指示标志,如设备已经初始化标志等。 unsigned long baudrate; //串口波特率 unsigned long have_console; //串口初始化标志
unsigned long reloc_off; //重定位偏移,就是实际定向的位置与编译连接时指定的位置之差,一般为0
unsigned long env_addr; //环境参数地址
unsigned long env_valid; //环境参数CRC检验有效标志 unsigned long fb_base; //base address of frame buffer #ifdef CONFIG_VFD
unsigned char vfd_type; //display type #endif
void **jt; //跳转表 } gd_t;
3.2 bd 板子数据指针
板子很多重要的参数。类型定义如下: typedef struct bd_info {
17
int bi_baudrate; //串口波特率 unsigned long bi_ip_addr; //IP地址 unsigned char bi_enetaddr[6]; //MAC地址 struct environment_s *bi_env;
ulong bi_arch_number; //unique id for this board ulong bi_boot_params; //启动参数
struct //RAM配置 {
ulong start; ulong size;
} bi_dram[CONFIG_NR_DRAM_BANKS];
} bd_t;
3.3环境变量指针
env_t *env_ptr = (env_t *)(&environment[0]); (common/Env_nand.c)
env_ptr指向环境参数区,系统启动是默认的环境参数environment[],定义在common/environment.c中。 参数解释: bootdelay 定义执行自动启动的等候秒数 baudrate 定义串口控制台的波特率 netmask 定义以太网接口的掩码 ethaddr 定义以太网接口的MAC地址 bootfile 定义缺省的下载文件
bootargs 定义传递给Linux内核的命令行参数
18
bootcmd 定义自动启动时执行的几条命令 serverip 定义tftp服务器段的IP地址 ipaddr 定义本地的IP地址
stdin 定义标准输入设备,一般是串口 stdout 定义标准输出设备,一般是串口 stderr 定义标准错误信息输出设备,一般是串口
3.4设备相关
标准IO设备数组 evice_t *stdio_devices[] = {NULL, NULL, NULL}; 设备列表 list_t devlist = 0; device_t的定义: include/devices.h 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 */ /* 输出函数 */
void (*putc)(const char c); /* To put a char */
void (*puts)(const char *s); /* To put a string(accelerator) */ /* 输入函数 */
int (*tstc)(void); /* To test if a char is ready… */
19
int (*getc)(void); /* To get that char */ /* Other functions */
void *priv; /* Private extensions */\\
} device_t;
U-boot把可以用为控制台输入输出的设备添加到设备列表devlist,并把当前用作标准IO的设备指针加到stdio_devices数组中。
3.5命令结构体类型定义:include/command.h struct cmd_tbl_s {
char *name;
/* Command Name 命令名
*/
在调用标准IO函数如printf()时将调用stdio_devices数组对应设备的IO函数如putc()。
int maxargs; /* maximum number of arguments int repeatable;
/* autorepeat allowed?
*/
最大参数个数*/
/* Implementation function 命令执行函数*/
int (*cmd)(struct cmd_tbl_s *, int, int, char *[]); char *usage;
/* Usage message (short)
*/
#ifdef CFG_LONGHELP
char *help; #endif
#ifdef CONFIG_AUTO_COMPLETE
/* do auto completion on the arguments */
int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cmdv[]); #endif };
20
/* Help message (long) */