虽说前文分析内存管理框架构建的实现,提到了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'\n", 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也是来自于此。

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

Linux-3.14.12内存管理笔记【构建内存管理框架(4)】的更多相关文章

  1. Linux-3.14.12内存管理笔记【内存泄漏检测kmemleak示例】【转】

    本文转载自:http://blog.chinaunix.net/uid-26859697-id-5758037.html 分析完kmemleak实现后,照常实验一下,以确定功能正常. 如kmemche ...

  2. Linux中的Buffer Cache和Page Cache echo 3 > /proc/sys/vm/drop_caches Slab内存管理机制 SLUB内存管理机制

    Linux中的Buffer Cache和Page Cache echo 3 > /proc/sys/vm/drop_caches   Slab内存管理机制 SLUB内存管理机制 http://w ...

  3. 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配

    垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己 ...

  4. Win3内存管理之私有内存跟共享内存的申请与释放

    Win3内存管理之私有内存跟共享内存的申请与释放 一丶内存简介私有内存申请 通过上一篇文章.我们理解了虚拟内存与物理内存的区别. 那么我们有API事专门申请虚拟内存与物理内存的. 有私有内存跟共享内存 ...

  5. JVM自动内存管理机制——Java内存区域(下)

    一.虚拟机参数配置 在上一篇<Java自动内存管理机制——Java内存区域(上)>中介绍了有关的基础知识,这一篇主要是通过一些示例来了解有关虚拟机参数的配置. 1.Java堆参数设置 a) ...

  6. 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法

    垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己主动内存管理 上(一)内存分配 垃圾回收GC:.Net自己主动内存管理 上(二)内存算法 垃圾回收GC:.Net自己 ...

  7. Linux-3.14.12内存管理笔记【构建内存管理框架(1)】

    传统的计算机结构中,整个物理内存都是一条线上的,CPU访问整个内存空间所需要的时间都是相同的.这种内存结构被称之为UMA(Uniform Memory Architecture,一致存储结构).但是随 ...

  8. Linux-3.14.12内存管理笔记【构建内存管理框架(5)】

    前面已经分析了内存管理框架的构建实现过程,有部分内容未完全呈现出来,这里主要做个补充. 如下图,这是前面已经看到过的linux物理内存管理框架的层次关系. 现着重分析一下各个管理结构体的成员功能作用. ...

  9. Linux-3.14.12内存管理笔记【构建内存管理框架(2)】

    前面构建内存管理框架,已经将内存管理node节点设置完毕,接下来将是管理区和页面管理的构建.此处代码实现主要在于setup_arch()下的一处钩子:x86_init.paging.pagetable ...

  10. Linux-3.14.12内存管理笔记【构建内存管理框架(3)】

    此处接前文,分析free_area_init_nodes()函数最后部分,分析其末尾的循环: for_each_online_node(nid) { pg_data_t *pgdat = NODE_D ...

随机推荐

  1. 如何判断一个变量是否为数组(isArray)

    在我们平时的工作中经常会用到如何判断一个变量是否为数组.常用的方法很多,有用常用框架里面的,isArray.但是关于这个isArray的实现,各有不同. 常用的方法有如下几种 1.instanceof ...

  2. Linux selinux 规则导致audit拒绝

    Linux selinux 规则导致audit拒绝 转载注明来源: 本文链接 来自osnosn的博客,写于 2019-09-26. 查看 audit2why -d audit2allow 这两个命令. ...

  3. 可编程实验板EPM1270T144C5蜂鸣器音调频率选择

    always@(tone) begin case(tone) 'd1 : time_end=10'd1911 ;//L1 'd2 : time_end=10'd1702 ;//L2 'd3 : tim ...

  4. js 从两道面试题加深理解闭包与箭头函数中的this

     壹 ❀ 引 在本文之前我已经花了两个篇幅专门介绍了JavaScript中的闭包与this,正好今早地铁上看到了两道面试题,试着做了下发现挺有意思,所以想单独写一篇文章来记录解析过程.若你对于闭包与t ...

  5. Prometheus学习系列(九)之Prometheus 存储

    前言 本文来自Prometheus官网手册 和 Prometheus简介 存储 Prometheus是一个本地磁盘时间序列数据库,但也可选择与远程存储系统集成,其本地时间序列数据库以自定义格式在磁盘上 ...

  6. SpringMVC通过Redis实现缓存主页

    这里说的缓存只是为了提供一些动态的界面没办法作静态化的界面来减少数据库的访问压力,如果能够做静态化的话的还是采用nginx来做界面的静态化,这样可以承受高并发的访问能力. 好了,废话少说直接看实现代码 ...

  7. [转]uipath orchestrator installation

    本文转自:https://dotnetbasic.com/2019/08/uipath-orchestrator-installation.html UiPath Orchestrator Insta ...

  8. 修改vscode的文件,对应的磁盘文件不改变

    两种解决办法: 首先:修改VSCode默认配置文件,点击左下角设置标志图 -> 设置,出来了设置相关的东西,搜索 files.autoSave 第一种:把"files.autoSave ...

  9. java类成员的默认可访问性是什么?你猜

    先看下面TestModel: import org.apache.commons.collections4.BidiMap; import org.apache.commons.collections ...

  10. Docker 底层技术与端口映射

    容器底层实现技术  1.cgroup 实现了资源的限额:CPU,内存,硬盘 cgroup使用  docker run -d -m 100M httpd 2.namespace 实现了资源隔离 name ...