在前面一章中,已经下载并编译了u-boot。
我使用的是u-boot-2015.05, 解压后,配置,编译:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- vexpress_ca9x4_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
u-boot 的启动过程可以分为两种,单阶段和多阶段两种。u-boot 为两个阶段的启动过程。
第一阶段 通常用汇编语言实现,完成一些依赖于CPU体系结构的初始化,设置栈,并调用第二阶段代码。
第二阶段 通常用C语言实现,完成体系结构之外的功能,检测内存映射,搬移内核,设置内核启动参数,调用内核。
总结一下:
u-boot:有两个阶段,实现两次初始化(第一阶段的基本硬件初始化,第二阶段体系结构外的硬件初始化),实现两次搬移(第一阶段 u-boot自搬移,把自己搬移到内存RAM中执行,把内核搬移到内存RAM中)。
关于u-boot的目录结构和源码阅读,在这里不做过多描述,这里实现一个简易的控制命令。
u-boot的每一个控制命令都是通过U_BOOY_CMD 宏定义来实现的,这个宏在 include/command.h 文件中定义。
#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \
U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, NULL)
每一个命令定义了一个cmd_tbl_t 结构体。
结构体包含的成员变量有:命令名称、最大参数个数、重复次数、命令执行函数、用法、帮助。
从控制台输入的命令都被送到 common/command.c 中的find_cmd() 函数解析执行,根据匹配输入的命令,从列表中找到对应的命令结构体,并调用处理函数完成命令处理。
find_cmd_tbl 查找代码:
接下来实现自己的u-boot命令
1.在 include/configs/vexpress_ca9x4.h中添加一项宏定义
#define CONFIG_CMD_HELLOWORLD 1
2.在common/ 文件夹下建立cmd_helloworld.c
#include <common.h>
#include <command.h>
#ifdef CONFIG_CMD_HELLOWORLD
void helloworld (cmd_tbl_t *cmdtp,int flag, int argc, char *argv[])
{
int i=0;
for(i=0;i<argc;i++)
{
printf("-----------Hello World!\n");
printf("argv[%d]=%s\n",i,argv[i]);
}
}
U_BOOT_CMD(hello,3,2,helloworld,"hello command","add u-boot hello cmd\n");
#endif
3.在common/Makefile中添加
obj-y += cmd_helloworld.o
4.重新编译,加载u-boot,在命令行输入help和hello命令查看结果。