u-boot
1. u-boo打补丁与编译操作
- 解压缩:tar xjf u-boot-1.1.6.tar.bz2
- 进入加压后的文件夹:u-boot-1.1.6
- 打补丁: patch -p1 < ../u-boot-1.1.6.jz2440.patch
- 配置: make 100ask24x0_config
- 编译: make
Note:
1. 补丁文件中,“-”表示原来的代码,"+"代码修改的代码
如下所示,
@@部分内容指示代码变化内容;
-28,7表示原来的代码从28行起,有7行;
+28, 7表示修改后的代码从28行起,有7行。
diff -urN u-boot-1.1.6/common/cmd_nand.c u-boot-1.1.6_jz2440_20171103/common/cmd_nand.c --- u-boot-1.1.6/common/cmd_nand.c 2006-11-02 22:15:01.000000000 +0800 +++ u-boot-1.1.6_jz2440_20171103/common/cmd_nand.c 2017-11-03 14:19:59.253590991 +0800 @@ -28,7 +28,7 @@ #ifdef CONFIG_SHOW_BOOT_PROGRESS # include <status_led.h> -# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) +# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg) #else # define SHOW_BOOT_PROGRESS(arg) #endif
2. 命令: patch -p1 < ../u-boot-1.1.6.jz2440.patch中-p1表示忽略补丁文件中指示路径中的第一项;
3. 烧写到开发板后,输入?或help,可以查看u-boot命令
2. u-boot启动流程
第一阶段
- 设置SV模式
- 关看门狗
- 初始化时钟
- 屏蔽中断
- 初始化SDRAM(如果用C语言写,需要先设置栈)
- 启动ICACHE;
- 重定位:
- 1)初始化Nand/Nor Flash;
- 1)使用链接文件,将代码段与数据段重定位到SDRAM区域;
- 2)使用汇编,将代码与数据从Nand/Nor Flash拷贝到SDRAM;
- 3)清BSS段
- 设置栈
- 将代码从Flash拷贝到SDRAM
- 清BSS段
- 调用C函数_start进入第二阶段
第二阶段
- 内核启动开始时,会调用串口接口从串口打印输出一些信息,但内核不会初始化串口,因此需要U-boot在刚开始初始化串口。
- 从NAND Flash里把内核读入内存中:从地址0x600000+64(UImage数据结构)读取到0x30008000,读取大小为2M。
- 设置参数:
- 需要将环境参数传递给内核,因此使用tag机制,以结构体形式组织数据存储到特定区域中。在内核中以相同数据结构读取该区域,即可获取环境参数。
- 设置Start Tag:设置地址和长度,如果没有使用数据段就填0;
- 设置Memory Tag:有一个连续的memory,就设置一个;如果有多个不连续的memory,就要设置多个memory tag;
- 设置Command Tag:存储从环境变量读取的bootargs环境参数;
- 设置End Tag:设置地址和长度为0
- 根据命令决定执行的行为,跳转到:Linux内核执行
- 调用跳转函数时需要传入参数,包括:0,机器ID(S3C2440的机器ID为362),参数位置(tag的地址)
注1:
NOR Flash启动时,0地址对应的是Nor Flash,而NOR Flash是不可直接写的;
NAND Flash启动时,0地址对应的是片内RAM,而片内RAM是可写的。
通过这种方法可以判断出启动对象是NOR Flash还是NAND Flash
3 u-boot下载地址
- 访问bin国际版;
- 搜索u-boot后的第一条信息,地址为https://www.denx.de/wiki/U-Boot;
- 在source code中使用FTP下载。
4 u-boot命令实现
u-boot使用cmd_tbl_t实现命令结构体;
struct cmd_tbl_s { char *name; /* Command Name */ int maxargs; /* maximum number of arguments */ /* * Same as ->cmd() except the command * tells us if it can be repeated. * Replaces the old ->repeatable field * which was not able to make * repeatable property different for * the main command and sub-commands. */ int (*cmd_rep)(struct cmd_tbl_s *cmd, int flags, int argc, char * const argv[], int *repeatable); /* Implementation function */ int (*cmd)(struct cmd_tbl_s *, int, int, char * const []); char *usage; /* Usage message (short) */ #ifdef CONFIG_SYS_LONGHELP char *help; /* Help message (long) */ #endif #ifdef CONFIG_AUTO_COMPLETE /* do auto completion on the arguments */ int (*complete)(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]); #endif };
例如u-boot中的help命令实现如下:
static int do_help(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #ifdef CONFIG_CMDLINE cmd_tbl_t *start = ll_entry_start(cmd_tbl_t, cmd); const int len = ll_entry_count(cmd_tbl_t, cmd); return _do_help(start, len, cmdtp, flag, argc, argv); #else return 0; #endif } U_BOOT_CMD( help, CONFIG_SYS_MAXARGS, 1, do_help, "print command description/usage", "\n" " - print brief description of all commands\n" "help command ...\n" " - print detailed usage of 'command'" );
5 u-boot启动内核
1.从Flash中读内核:nand read.jffs2 0x30007FC0 ox00060000 0x00200000
2.启动内核:bootm 0x30007FC0
Flash上存储的内核:uimage包括两部分:64byte头+真正的内核代码
如果将内核保存在0x30008000,则将Flash拷贝地址放在0x30007FC0