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启动流程

第一阶段

  1. 设置SV模式
  2. 关看门狗
  3. 初始化时钟
  4. 屏蔽中断
  5. 初始化SDRAM(如果用C语言写,需要先设置栈)
  6. 启动ICACHE;
  7. 重定位:
    • 1)初始化Nand/Nor Flash;
    • 1)使用链接文件,将代码段与数据段重定位到SDRAM区域;
    • 2)使用汇编,将代码与数据从Nand/Nor Flash拷贝到SDRAM;
    • 3)清BSS段
  8. 设置栈
  9. 将代码从Flash拷贝到SDRAM
  10. 清BSS段
  11. 调用C函数_start进入第二阶段

第二阶段

  1. 内核启动开始时,会调用串口接口从串口打印输出一些信息,但内核不会初始化串口,因此需要U-boot在刚开始初始化串口。
  2. 从NAND Flash里把内核读入内存中:从地址0x600000+64(UImage数据结构)读取到0x30008000,读取大小为2M。
  3. 设置参数:
    • 需要将环境参数传递给内核,因此使用tag机制,以结构体形式组织数据存储到特定区域中。在内核中以相同数据结构读取该区域,即可获取环境参数。
    • 设置Start Tag:设置地址和长度,如果没有使用数据段就填0;
    • 设置Memory Tag:有一个连续的memory,就设置一个;如果有多个不连续的memory,就要设置多个memory tag;
    • 设置Command Tag:存储从环境变量读取的bootargs环境参数;
    • 设置End Tag:设置地址和长度为0
  4. 根据命令决定执行的行为,跳转到: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下载地址

  1. 访问bin国际版;
  2. 搜索u-boot后的第一条信息,地址为https://www.denx.de/wiki/U-Boot;
  3. 在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

posted @ 2019-06-08 13:28  寒霜未降  阅读(263)  评论(0编辑  收藏  举报