Chinaunix首页 | 论坛 | 博客
  • 博客访问: 294177
  • 博文数量: 44
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 1354
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-08 15:38
个人简介

人生像是在跑马拉松,能够完赛的都是不断地坚持向前迈进;人生就是像在跑马拉松,不断调整步伐,把握好分分秒秒;人生还是像在跑马拉松,能力决定了能跑短程、半程还是全程。人生其实就是一场马拉松,坚持不懈,珍惜时间。

文章分类

分类: LINUX

2015-01-25 19:42:39

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

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

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

而其中cmdline_parse_core()实现:

  1. 【file:/mm/page_alloc.c】
  2. static int __init cmdline_parse_core(char *p, unsigned long *core)
  3. {
  4.     unsigned long long coremem;
  5.     if (!p)
  6.         return -EINVAL;
  7.  
  8.     coremem = memparse(p, &p);
  9.     *core = coremem >> PAGE_SHIFT;
  10.  
  11.     /* Paranoid check that UL is enough for the coremem value */
  12.     WARN_ON((coremem >> PAGE_SHIFT) > ULONG_MAX);
  13.  
  14.     return 0;
  15. }

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

  1. 【file:/mm/page_alloc.c】
  2. 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()中调用,相关代码:

  1. 【file:/init/main.c】
  2. /* Check for early params. */
  3. static int __init do_early_param(char *param, char *val, const char *unused)
  4. {
  5.     const struct obs_kernel_param *p;
  6.  
  7.     for (p = __setup_start; p < __setup_end; p++) {
  8.         if ((p->early && parameq(param, p->str)) ||
  9.             (strcmp(param, "console") == 0 &&
  10.              strcmp(p->str, "earlycon") == 0)
  11.         ) {
  12.             if (p->setup_func(val) != 0)
  13.                 pr_warn("Malformed early option '%s'\n", param);
  14.         }
  15.     }
  16.     /* We accept everything at this stage. */
  17.     return 0;
  18. }

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

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

start_kernel()

->setup_arch()

->parse_early_param()

->parse_early_options()

->parse_args()

->parse_one()

->do_early_param()

这里只能说明required_movablecorerequired_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_movablecorerequired_kernelcore也是来自于此。

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

阅读(2507) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~