• 2008-06-15

    Redboot 设备初始化说明 - [源码分析]

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://redboot.blogbus.com/logs/22987104.html

    当redboot启动完毕后,进入cyg_start 函数,在这个函数里进行了初始化设备的工作:

    for (init_entry = __RedBoot_INIT_TAB__; init_entry != &__RedBoot_INIT_TAB_END__;  init_entry++)
    {
     (*init_entry->fun)();
    }


    __RedBoot_INIT_TAB__ 为初始化表,初始化表是一个 struct init_tab_entry 的数组。
    而 struct init_tab_entry 只有一个函数 fun。

    而这一段初始化过程就是执行初始化表中的每一个fun函数。
    相关定义如下:

    extern struct init_tab_entry __RedBoot_INIT_TAB__[], __RedBoot_INIT_TAB_END__;

    struct init_tab_entry {
        void_fun_ptr fun;
    } CYG_HAL_TABLE_TYPE;


    如果希望在这个初始化过程中,执行某函数需要加入如下声明:

    RedBoot_init(net_init, RedBoot_INIT_LAST);

    net_init 是网络设备的初始化函数, RedBoot_INIT_LAST是表示放在 __RedBoot_INIT_TAB__ 表的尾部。

    -------------------------------------------------------------------

    大致的实现原理在下面简单解释 一下

    首先,_RedBoot_INIT_TAB__ 和 __RedBoot_INIT_TAB_END__ 有如下宏定义

     

    CYG_HAL_TABLE_BEGIN( __RedBoot_INIT_TAB__, RedBoot_inits );
    CYG_HAL_TABLE_END( __RedBoot_INIT_TAB_END__, RedBoot_inits );

     

    #define CYG_HAL_TABLE_BEGIN( _label, _name )                                 \
    __asm__(".section \".ecos.table." __xstring(_name) ".begin\",\"aw\"\n"       \
        ".globl " __xstring(CYG_LABEL_DEFN(_label)) "\n"                         \
        ".type    " __xstring(CYG_LABEL_DEFN(_label)) ",object\n"                \
        ".p2align " __xstring(CYGARC_P2ALIGNMENT) "\n"                           \
    __xstring(CYG_LABEL_DEFN(_label)) ":\n"                                      \
        ".previous\n"                                                            \
           )

    #define CYG_HAL_TABLE_END( _label, _name )                                   \
    __asm__(".section \".ecos.table." __xstring(_name) ".finish\",\"aw\"\n"      \
        ".globl " __xstring(CYG_LABEL_DEFN(_label)) "\n"                         \
        ".type    " __xstring(CYG_LABEL_DEFN(_label)) ",object\n"                \
        ".p2align " __xstring(CYGARC_P2ALIGNMENT) "\n"                           \
    __xstring(CYG_LABEL_DEFN(_label)) ":\n"                                      \
        ".previous\n" 

     

    解析后大致为:

    .section ".ecos.table.RedBoot_inits.begin","aw"
        .globl  __RedBoot_INIT_TAB__
        .type     __RedBoot_INIT_TAB__ ,object
        .p2align  5
    __RedBoot_INIT_TAB__ :
        .previous
      
    .section ".ecos.table.RedBoot_inits.finish","aw"
        .globl  __RedBoot_INIT_TAB_END__
        .type     __RedBoot_INIT_TAB_END__ ,object
        .p2align  5
    __RedBoot_INIT_TAB__ :
        .previous

     

    另外,对于 RedBoot_init(net_init, RedBoot_INIT_LAST); 宏定义分别如下:

     

     #define RedBoot_init(_f_,_p_) _RedBoot_init(_f_,_p_)

    #define _RedBoot_init(_f_,_p_)                                          \
    struct init_tab_entry _init_tab_##_p_##_f_                              \
      CYG_HAL_TABLE_QUALIFIED_ENTRY(RedBoot_inits,_p_##_f_) = { _f_ };


    #define CYG_HAL_TABLE_QUALIFIED_ENTRY( _name, _qual ) \
            CYGBLD_ATTRIB_SECTION(".ecos.table." __xstring(_name) ".data." \
                                  __xstring(_qual))

    #define RedBoot_INIT_FIRST 0000
    #define RedBoot_INIT_LAST  9999

     #define CYGBLD_ATTRIB_SECTION(__sect__) __attribute__((section (__sect__)))

     

    解析后大致为:

    struct init_tab_entry _init_tab_RedBoot_9999net_init
    __attribute__((section (.ecos.table.RedBoot_inits.data.9999net_init)))  =    { net_init };
     

    -------------------------------

     

    这种表结构在eCos的其他部分也经常使用,所以了解一下,很有必要的。

     

     

     

     

     

     

     

     

     

     


    收藏到:Del.icio.us




    评论

  • 谢谢关注, 你提到的这篇文章不错,有空看看,再跟你讨论吧 ^_^
  • 看了博主的文章,很受启发。现在正在做一个项目,遇到一个问题想请教博主。
    系统采用redboot 2.0启动linux 2.4,在进入linux后可以通过网页升级系统,升级的方法就是覆盖flash中的ramdisk.gz。为了保证系统的健壮,参考了http://www.ibm.com/developerworks/cn/linux/l-cn-safemode/index.html,从而使得升级失败后可以照常启动系统,自动重新网络升级,而不需要连接串口,用redboot一系列命令来重新升级。但目前不知道怎样使用redboot来实现对多重ramdisk的支持等等。
    不胜感谢。