kernel版本: 3.0.35
之前有提过u-boot将tags作为启动kernel的第三个参数传递:
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { ...... theKernel (0, machid, bd->bi_boot_params); /* does not return */ return 1; }
kernel对tags的解析有如下流程:
start_kernel -> main.c setup_arch -> setup.c setup_machine_tags -> mdesc->fixup //读取commondline parse_tags -> parse_tag -> //解析每一个tag t->parse //调用各个注册的tag对应的处理函数,这些都被存放在__tagtable_begin和__tagtable_end区间。那么__tagtable_begin又是在哪里定义的呢?
__tagtable_begin = .; *(.taglist.init) __tagtable_end = .;也就是说代码中被定义在.taglist.init段的都属于整个区间。
.taglist.int如何被用到?看一个例子:
static int __init parse_tag_mem32(const struct tag *tag) { return arm_add_memory(tag->u.mem.start, tag->u.mem.size); } __tagtable(ATAG_MEM, parse_tag_mem32);__tagtable:
#define __tag __used __attribute__((__section__(".taglist.init"))) #define __tagtable(tag, fn) \ static struct tagtable __tagtable_##fn __tag = { tag, fn }所以__tagtable就是把tag存放在了.taglist.init段,也就是__tagtable_begin和__tagtable_end区间。