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;
    }
  • 相关阅读:
    控制器生命周期逻辑调用
    数据持久化
    Mac屏幕录制Gif
    iOS开发应用上架必读最新苹果审核规则
    过滤字符串中的非汉字、字母、数字
    文字加描边
    博客全局修改需求
    iOS Xcode12 运行iOS15系统程序卡在启动页要等很久才能进入主页
    macOS环境:安装Go(21-10-22完)
    关闭WIN10自动配置 IPV4 地址 169.254解决方法
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/8111283.html
Copyright © 2011-2022 走看看