通过上一节的分析我们知道:
1、 Uboot的第一个启动文件为:cpu/arm920t/start.o
2、 连接脚本/board/100ask24x0/u-boot.lds 连接地址为0x33f80000
下面开始分析Start.s
.globl_start
_start: b reset
一、首先跳转到 reset
1、首先将MCU设置成 SVC32模式
2、关闭看门狗
3、 屏蔽所有中断
4、 初始化SDRAM
5、 初始化堆栈SP
6、 初始化时钟
7、 将uboot代码从flash(NOR或者NAND)中拷贝到SDRAM中的连接地址0x33f80000处
8、 清bss段
9、 _start_armboot执行该函数
二、通过对start_armboot函数的分析可知:
1、当uboot启动过程倒计时时按下空格键时进入Uboot菜单命令
Readline()读入串口命令
Run_command()解析并执行该命令
2、如果未按空格键当倒计时结束时将启动内核
s=getenv("bootcmd") 获取内核启动命令
run_command(0,s) 运行启动命令 载入内核
Bootcmd=read.jffs 0x30007fc0 kernel #从NAND读内核到SDRAM中
Bootm=0x30007fc0 #启动内核
Linux内核uImage由两部分组成 head(头部64字节)+真正内核
头部包含两个重要信息:
一个是内核的加载地址in_load:0x30008000
一个是内核的入口地址in_load: 0x30007fc0 + 64=0x30008000
然后通过do_bootm_linux()函数来启动内核
1、 该函数要告诉内核一些启动参数
Uboot在固定地址(0x30000100)按照固定格式存放参数
2、 通过执行下面函数启动内核,该函数第二个参数为MACH_TYPE_S3C2440内核ID
内核启动时会根据该ID来判断内核是否支持该单板,即是否支持该MCU
在u-boot-1.1.6/board/100ask24x0目录下100ask24x0.c中
第三个参数为内核启动参数地址0x30000100
三、NAND Flash(256Mb)和SDRAM(64Mb)的内部分区
1、NAND Flash分区情况在/u-boot-1.1.6/include/configs/100ask24x0.h中进行定义
#define MTDPARTS_DEFAULT"mtdparts=nandflash0:[email protected](bootloader)," \
"128k(params)," \
"2m(kernel)," \
"-(root)"
从0地址开始 256k存放bootloader
接下来128k存放 params 启动时的参数
接下来2M存放内核
剩下的部分存放根文件系统
3、 SDRAM分区
四、分析Uboot的命令如何实现
命令结构体:
U_BOOT_CMD
{
串口输入命令
最大参数个数
是否可重复 1表示可以 0代表不可以
该命令对应函数
短帮助信息
长帮助信息
}
根据上面格式自己添加一个 hello命令创建cmd_hello.c到 u-boot-1.1.6/common目录下,内容如下:
#include<common.h>
#include<watchdog.h>
#include<command.h>
#include<image.h>
#include<malloc.h>
#include<zlib.h>
#include<bzlib.h>
#include<environment.h>
#include<asm/byteorder.h>
intdo_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int i;
printf ("helloworld,%d\n",argc);
for(i=0;i<argc;i++)
{
printf("argv[%d]:%s\n",i,argv[i]);
}
return 0;
}
U_BOOT_CMD(
hello, CFG_MAXARGS, 1, do_hello,
"hello - just for test!\n",
"hello - long help fortest........................!\n"
);
然后修改u-boot-1.1.6/common目录下的Makefile 添加cmd_hello.o然后重新编译Uboot
然后烧到板子上 可以测试该hello命令