1. 程式人生 > >atag信息處理

atag信息處理

ini 常用 ret and des decode uil lin inux

machine_desc->boot_params參數保存的是u-boot傳入的啟動參數的地址,如果沒有傳入啟動參數,使用如下的默認參數:

/*
 * This holds our defaults.默認的tags
 */
static struct init_tags {
    struct tag_header hdr1;
    struct tag_core   core;
    struct tag_header hdr2;
    struct tag_mem32  mem;
    struct tag_header hdr3;
} init_tags __initdata 
= { { tag_size(tag_core), ATAG_CORE }, { 1, PAGE_SIZE, 0xff }, { tag_size(tag_mem32), ATAG_MEM }, { MEM_SIZE }, { 0, ATAG_NONE } };

內核代碼通過下面的宏保存對不同的tag的處理函數,

struct tagtable {
    __u32 tag;
    int (*parse)(const struct tag *);
};

#define __tag __used __attribute__((__section__(".taglist.init")))
#define
__tagtable(tag, fn) static struct tagtable __tagtable_##fn __tag = { tag, fn }

通過__tagtable宏定義的struct tagtable都保存在特定的數據斷中,

/*vmlinux.lds*/
__tagtable_begin = .;
    *(.taglist.init)
__tagtable_end = .;

常用的3個atag解析宏定義如下:

static int __init parse_tag_core(const struct tag *tag)
{
    if (tag->hdr.size > 2
) { if ((tag->u.core.flags & 1) == 0) root_mountflags &= ~MS_RDONLY; ROOT_DEV = old_decode_dev(tag->u.core.rootdev); } return 0; } __tagtable(ATAG_CORE, parse_tag_core); static int __init parse_tag_mem32(const struct tag *tag) { if (meminfo.nr_banks >= NR_BANKS) { printk(KERN_WARNING "Ignoring memory bank 0x%08x size %dKB\n", tag->u.mem.start, tag->u.mem.size / 1024); return -EINVAL; } arm_add_memory(tag->u.mem.start, tag->u.mem.size); return 0; } __tagtable(ATAG_MEM, parse_tag_mem32); static int __init parse_tag_cmdline(const struct tag *tag) { strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE); return 0; } __tagtable(ATAG_CMDLINE, parse_tag_cmdline);

處理每一個tag時,使用下面的函數遍歷.taglist.init段,調用相應的處理函數,

/*
 * Scan the tag table for this tag, and call its parse function.
 * The tag table is built by the linker from all the __tagtable
 * declarations.
 */
static int __init parse_tag(const struct tag *tag)
{
    extern struct tagtable __tagtable_begin, __tagtable_end;
    struct tagtable *t;

    for (t = &__tagtable_begin; t < &__tagtable_end; t++)
        if (tag->hdr.tag == t->tag) {
            t->parse(tag);
            break;
        }

    return t < &__tagtable_end;
}

atag信息處理