zoukankan      html  css  js  c++  java
  • Linux-3.14.12内存管理笔记【构建内存管理框架(4)】

    虽说前文分析内存管理框架构建的实现,提到了find_zone_movable_pfns_for_nodes(),但这里不准备复述什么,仅针对required_movablecore和required_kernelcore做一个补充。

    以required_movablecore为例,代码中没有很清晰地表明该值从何而来,仅有一处cmdline_parse_movablecore()疑似赋值的实现:

    【file:/mm/page_alloc.c】
    /*
     * movablecore=size sets the amount of memory for use for allocations that
     * can be reclaimed or migrated.
     */
    static int __init cmdline_parse_movablecore(char *p)
    {
        return cmdline_parse_core(p, &required_movablecore);
    }
    

    而其中cmdline_parse_core()实现:

    【file:/mm/page_alloc.c】
    static int __init cmdline_parse_core(char *p, unsigned long *core)
    {
        unsigned long long coremem;
        if (!p)
            return -EINVAL;
     
        coremem = memparse(p, &p);
        *core = coremem >> PAGE_SHIFT;
     
        /* Paranoid check that UL is enough for the coremem value */
        WARN_ON((coremem >> PAGE_SHIFT) > ULONG_MAX);
     
        return 0;
    }
    

    可以推测其值是由此而来,继而可以找到:

    【file:/mm/page_alloc.c】
    early_param("movablecore", cmdline_parse_movablecore);
    

    这是一个函数注册宏,该宏展开后:

    static const char __setup_str_cmdline_parse_movablecore[] __attribute__ ((__section__(".init.rodata"))) __attribute__((aligned(1))) = "movablecore"; static struct obs_kernel_param __setup_cmdline_parse_movablecore __attribute__((__used__)) __attribute__ ((__section__(".init.setup"))) __attribute__((aligned((sizeof(long))))) = { __setup_str_cmdline_parse_movablecore, cmdline_parse_movablecore, 1 }
    

    由此借用于__section__属性定义,编译器通过arch/x86/kernel/vmlinux.lds链接脚本把__setup_cmdline_parse_movablecore放置在.init.setup段中。

    注册的函数将会在do_early_param()中调用,相关代码:

    【file:/init/main.c】
    /* Check for early params. */
    static int __init do_early_param(char *param, char *val, const char *unused)
    {
        const struct obs_kernel_param *p;
     
        for (p = __setup_start; p < __setup_end; p++) {
            if ((p->early && parameq(param, p->str)) ||
                (strcmp(param, "console") == 0 &&
                 strcmp(p->str, "earlycon") == 0)
            ) {
                if (p->setup_func(val) != 0)
                    pr_warn("Malformed early option '%s'
    ", param);
            }
        }
        /* We accept everything at this stage. */
        return 0;
    }
    

    可以看到借助于__setup_start和__setup_end的范围标记,将遍历.init.setup段中的排布的obs_kernel_param结构体,找到匹配的字符串及early成员为true的情况下,将会调用其中的setup_func钩子函数,由此将对应数据初始化。

    do_early_param()函数在初始化时的调用关系:

    do_early_param()函数在初始化时的调用关系:

    start_kernel()
    
    ->setup_arch()
    
    ->parse_early_param()
    
    ->parse_early_options()
    
    ->parse_args()
    
    ->parse_one()
    
    ->do_early_param()
    

    这里只能说明required_movablecore和required_kernelcore在何处初始化的,而其值的由来呢?其值通过入参传递,在parse_early_param()函数中通过strlcpy()来自于boot_command_line全局变量。而boot_command_line早期则是在/arch/x86/kernel/head_32.s的初始化中来自于boot_params。具体 do_early_param()处理的数据来自于grub.cfg,也就是说required_movablecore和required_kernelcore也是来自于此。

    好了,暂且分析至此,避免走偏了,该文也是一时好奇钻研了一下,记之以作备忘。

  • 相关阅读:
    virtual 关键字
    innerhtml和innertext的用法以及区别
    CSS中overflow:hidden
    CSS中的repeat
    VC++6.0打开文件出错的解决办法
    HTML+CSS基础总结
    Guid算法
    SQL初级阶段笔记
    text-decoration
    IDEA 在同一目录创建多个项目
  • 原文地址:https://www.cnblogs.com/linhaostudy/p/11628810.html
Copyright © 2011-2022 走看看