zoukankan      html  css  js  c++  java
  • atag信息处理

    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
    ",
                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);

    注意,上面的defaul_command_line定义在arch/arm/kernel/setup.c中

    static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;

    其中CONFIG_CMDLINE在“.config”配置文件中定义的。定义如下:
    CONFIG_CMDLINE="root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200 mem=64M"
    default_command_line 原来的内容是我们配置文件中确定的,但是现在,被tag->u.cmdline.cmdline覆盖了。可见,从uboot传递过来的命令行参数的优先级要高于配置文件的默认命令行。

    处理每一个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;
    }
  • 相关阅读:
    高级特性(4)- 数据库编程
    UVA Jin Ge Jin Qu hao 12563
    UVA 116 Unidirectional TSP
    HDU 2224 The shortest path
    poj 2677 Tour
    【算法学习】双调欧几里得旅行商问题(动态规划)
    南洋理工大学 ACM 在线评测系统 矩形嵌套
    UVA The Tower of Babylon
    uva A Spy in the Metro(洛谷 P2583 地铁间谍)
    洛谷 P1095 守望者的逃离
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/8111283.html
Copyright © 2011-2022 走看看