下面这段函数出现在在u-boot启动的流程中
sw_patch_t **sw_patch = &LS_sw_patch_start;
while (sw_patch!=&LS_bootm_stack) {
(*sw_patch)();
++sw_patch;
}
LS_sw_patch_start 出现在u-boot.lds中
. = ALIGN(4);
.soft_patch : {
LS_sw_patch_start = .;
KEEP(*(.soft_patch.0));
KEEP(*(.soft_patch.1));
KEEP(*(.soft_patch.2));
KEEP(*(.soft_patch.3));
KEEP(*(.soft_patch.4));
KEEP(*(.soft_patch.5));
KEEP(*(.soft_patch.6));
KEEP(*(.soft_patch.7));
KEEP(*(.soft_patch.8));
KEEP(*(.soft_patch.9));
KEEP(*(.soft_patch.10));
KEEP(*(.soft_patch.11));
KEEP(*(.soft_patch.12));
KEEP(*(.soft_patch.13));
KEEP(*(.soft_patch.14));
KEEP(*(.soft_patch.15));
KEEP(*(.soft_patch.16));
KEEP(*(.soft_patch.17));
KEEP(*(.soft_patch.18));
KEEP(*(.soft_patch.19));
KEEP(*(.soft_patch.20));
KEEP(*(.soft_patch.21));
KEEP(*(.soft_patch.22));
KEEP(*(.soft_patch.23));
LS_bootm_stack = .;
KEEP(*(.soft_patch.99));
LS_sw_patch_end = .;
}
那么 KEEP(*(.soft_patch.18));这些代表什么呢?
PATCH_REG(swp_flash_init, 1);
PATCH_REG(swp_env, 3);
PATCH_REG(swp_uart, 5);
#ifdef CONFIG_OTTO_FLASH_LAYOUT
PATCH_REG(swp_gen_fl, 5);
#endif /* #ifdef CONFIG_OTTO_FLASH_LAYOUT */
PATCH_REG(swp_pci, 7);
PATCH_REG(swp_studio, 9);
PATCH_REG(swp_console_r, 11);
PATCH_REG(swp_env_set, 13);
PATCH_REG(swp_spi, 15);
PATCH_REG(swp_misc, 17);
PATCH_REG(swp_post, 19);
PATCH_REG(swp_eth, 21);
PATCH_REG是一个宏,定义在include/common.h中
#define PATCH_REG(x, lvl) \
void_func * __swp_##x __attribute__ ((section (".soft_patch." #lvl))) = x
在c语言中##表示连接前后两个字符串
__attribute__是GNU的新特性,它可以定义函数和结构,联合体之类的属性。在这里就是把函数编译连接到.soft_patch段之中。所以,上面的函数经过宏展开后就是void_func * __swp_swp_eth = swp_eth,并且在soft_patch段中。所以u-boot的主流程函数中就是定位到soft_patch的地址,然后依次执行这一段代码对应的每个指针指向的函数。
感觉好神奇