6200 uboot 测试版分析(二)

6200uboot启动过程

注:PC此时跳到0x42800000处开始执行

在这启动过程中主要包括系统信息采集(CPU信息、MAC、外设信息),配置一些系统模块正常工作,DDR2地址重映射(由0X40000000映射到0X00000000),今天阅读的Uboot_6200代码没有做PC重置,原来在Uboot_1.3.3版的代码会涉及到中断向量表搬移(从Norflash搬至ESRAM,以及PC重置)。

主要记录下今天阅读的uboot自启动下遇到的一个问题)。在void start_unicoreboot(void)最后会执行main_loop(),进入函数后,获取默认启动过程,同时延迟一段时间,调试人员按键以执行部分调试功能,该boot设置时间为3秒左右。当没有按键触发时,将继续执行。今天阅读的主要问题出在获取默认启动参数:

s 为char型指针,通过char *getenv(char *name)传入”bootcmd”字符串来获取参数并赋予s。内部调用env_get_char(nxt)来检测参数是否已存在,以及参数个数是否在范围内。确定一般要求后,检测参数开头是否匹配,匹配后返回参数地址。而后在调用其他参数进行参数解析,

由解析出的第一个参数(即命令名)来获取所在结构体地址,而该结构体cmd_tbl_t则预设了对于该命令即其他解析出来的参数做出适当的处理(该boot中参数为”bootcmd=bootm 0X40000000,注意该一定是不对的,因为PC起始为0x42800000……我没有获得完整的版本,但是通过对0x40000000修改及连接脚本和./board/prochip/SEP611/config.mk中的TEXT_BASE的修改是可以改正的)。问题在于那个参数所在的数组使我从开始做了错误的分析,

uchar default_environment[] =

{

#ifdef        CONFIG_BOOTARGS

         "bootargs="     CONFIG_BOOTARGS                           "\0"

#endif

#ifdef        CONFIG_BOOTCOMMAND

         "bootcmd="     CONFIG_BOOTCOMMAND               "\0"

#endif

};

  1. 犯了一个非常低级的错误,没有看类型声明
  2. 其次这个代码风格还行,但是如果自己写一定要加上显著说明,以防再次犯错。
  3. 字符串定义可以加上括号,这个有点遗忘了,也造成了我的误解。

对于uboot_cmd_cfg的嵌入还有一点不理解,

#define  Struct_Section  __attribute__ ((unused,section,”u_boot_cmd”)).

其次

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)\

cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name,maxargs,rep,cmd,usage,help}

以及cmd_tbl_t的构成。

做下整理

阅读下链接脚本u-boot.lds

section定义了:

__u_boot_cmd_start=.;

.u_boot_cmd:{*(.u_boot_cmd)}

__u_boot_cmd_end=.;

这说明编译的u_boot_cmd段被存放于该处(由__u_boot_cmd_start及__u_boot_cmd_end界定)

声明类型:

struct cmd_tbl_s

{

    char    *name;      /* Command Name         */

    int     maxargs;    /* maximum number of arguments  */

    int     repeatable; /* autorepeat allowed?      */

                    /* Implementation function  */

    int     (*cmd)(struct cmd_tbl_s *, int, int, char *[]);

    char    *usage;     /* Usage message    (short) */

#ifdef  CFG_LONGHELP

    char    *help;      /* Help  message    (long)  */

#endif

#ifdef CONFIG_AUTO_COMPLETE

    /* do auto completion on the arguments */

    int (*complete)(int argc, char *argv[], char last_char, int maxv, char *cm

dv[]);

#endif

};

typedef struct cmd_tbl_s    cmd_tbl_t;

重要的是下面的宏定义

#define  Struct_Section  __attribute__ ((unused,section,”u_boot_cmd”)).

第一次遇到这种定义,应该和编译器相关,对于这部分知识了解不多,应该是说明:

该段存放于u_boot_cmd段处,且其他部分不得占用该空间。

#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help)\

cmd_tbl_t __u_boot_cmd_##name Struct_Section = {#name,maxargs,rep,cmd,usage,help}

这是一个宏定义,涉及到##和#运算符。

看如下一个变量的定义就很清楚了:

U_BOOT_CMD(

    bootm,  CFG_MAXARGS,    1,  do_bootm,

    "bootm   - boot application image from memory\n",

    "[addr [arg ...]]\n    - boot application image stored in memory\n"

    "\tpassing arguments 'arg ...'; when booting a Linux kernel,\n"

"\t'arg' can be the address of an initrd image\n"

);

函数定义:

int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])

 120 {

 121     ulong       iflag;

 122     const char  *type_name;

 123     uint        unc_len = CFG_BOOTM_LEN;

 124     uint8_t     comp, type, os;

………………………………………………………………

下面就开始涉及到搬运即解压内核了(bootm 0x40000000

原文地址:https://www.cnblogs.com/openix/p/2367555.html