-
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的其他部分也经常使用,所以了解一下,很有必要的。
随机文章:
Redboot 的链接脚本 2008-06-16Redboot 常用命令详解(zt) 2008-06-06Redboot(i386)启动流程(三) 2008-05-22Redboot(i386)启动流程(二) 2008-05-21eCos编译配置说明 2008-04-27
收藏到: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的支持等等。
不胜感谢。