JZ2440 Uboot 启动过程分析续

时间:2024-04-02 13:18:20

通过上一节的分析我们知道:

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")       获取内核启动命令

JZ2440 Uboot 启动过程分析续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)按照固定格式存放参数

JZ2440 Uboot 启动过程分析续

2、  通过执行下面函数启动内核,该函数第二个参数为MACH_TYPE_S3C2440内核ID

内核启动时会根据该ID来判断内核是否支持该单板,即是否支持该MCU

JZ2440 Uboot 启动过程分析续

JZ2440 Uboot 启动过程分析续

在u-boot-1.1.6/board/100ask24x0目录下100ask24x0.c中

第三个参数为内核启动参数地址0x30000100

JZ2440 Uboot 启动过程分析续

 JZ2440 Uboot 启动过程分析续              

三、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存放内核

剩下的部分存放根文件系统

JZ2440 Uboot 启动过程分析续

3、  SDRAM分区

 JZ2440 Uboot 启动过程分析续JZ2440 Uboot 启动过程分析续JZ2440 Uboot 启动过程分析续

 

四、分析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命令