[置顶] linux内核启动2-setup_arch中的内存初始化(目前分析高端内存)
上一篇微博留下了这几个函数,现在我们来分析它们
sanity_check_meminfo();
arm_memblock_init(&meminfo, mdesc);
paging_init(mdesc);
request_standard_resources(mdesc);
在上一微博有展现根据启动参数初始化meminfo,记录了物理内存的开始和大小
sanity_check_meminfo();
有mmu的情况下这个函数才有意义,初始化高端内存,首先内核要选上这个
KernelFeatures下的
[*]High Memory Support
arch/arm/include/asm/setup.h
#ifdef CONFIG_ARCH_EP93XX
# define NR_BANKS 16
#else
#endif
struct membank {
phys_addr_t start;
unsigned longsize;
unsigned inthighmem;
};如果是高端内存highmem为1
struct meminfo {
int nr_banks;
struct membankbank[NR_BANKS];
};
extern struct meminfo meminfo;
我们现在的函数就是初始化meminfo这个全局变量
高端内存
linux内核的地址空间是3G~4G。假如说机器的内存为512M,那么内存的物
理地址范围是:0~512,而映射到内核空间的范围是3G~3G+512M(可以叫low memory).
+512G~4G,但是为了避免越界等安全问题
的考虑,高端内存又离开了低端内存8M空间,即从3G+512M+8M空间开始。linux内核又规定,高端内存至少为128M,即加入物理内存为1G,那么高端内存就是从896M~4G,即其最大地址:0xC0000000+896M,实际:0xC0000000+x(内存size)
简单举个例子,假设你有2G内存,而内核只有1G不能全部做线性映射,内核就会把前896M用于RAM线性映射,后128M可以通过更改映射关系访问剩下的内存。有三种方法:永久内核映射,临时映射,非连续内存分配(这些以后写关于内存管理的文章时再分析)。
没有全部贴
void __init sanity_check_meminfo(void)
{
int i, j, highmem= 0;
//wxl add
printk(KERN_NOTICE"vmalloc_min = %lx\n", vmalloc_min);
打印结果
vmalloc_min = ee000000
vmalloc_min = (void *)(VMALLOC_END - SZ_128M);
arch/arm/mach-s3c2410/include/mach/vmalloc.h
#define VMALLOC_END 0xF6000000UL
0xF6000000-0x8000000=0xEE000000
3808M
for (i = 0, j = 0;i < meminfo.nr_banks; i++) {
structmembank *bank = &meminfo.bank[j];
*bank =meminfo.bank[i];
#ifdef CONFIG_HIGHMEM
_va()是物理地址转换虚拟地址
#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
#define __va(x) ((void *)__phys_to_virt((unsigned long)(x)))
下面的条件告诉了我们高端地址范围,大于等于vmalloc_min的好理解,小于PAGE_OFFSET大概就是高端内存没有一次全部映射到内核空间,所以有低于PAGE_OFFSET的高端内存
if(__va(bank->start) >= vmalloc_min ||
__va(bank->start) < (void *) PAGE_OFFSET)
highmem = 1;
//wxl add
printk(KERN_NOTICE "start:bank->start = %lx bank->size = %lx __va = %lx highmem = %d\n",(unsigned long)bank->start, (unsigned long)bank->size, (unsignedlong)__va(bank->start), highmem);
打印结果
start: bank->start = 30000000 bank->size = 4000000 __va =c0000000 highmem = 0
bank->start bank->size就是上一篇微博提到的
bank->highmem = highmem;
/*
* Splitthose memory banks which are partially overlapping
* thevmalloc area greatly simplifying things later.
*/
假设__va(bank->start) < vmalloc_min;它的大小可能会超过低端内存,也就是起始地址在低端,结束地址超过低端范围,那么就要把它分开,你可以简单看看代码
if(__va(bank->start) < vmalloc_min &&
bank->size > vmalloc_min - __va(bank->start)) {
if(meminfo.nr_banks >= NR_BANKS) {
printk(KERN_CRIT "NR_BANKS too low, "
"ignoringhigh memory\n");
}else {
memmove(bank + 1, bank,
(meminfo.nr_banks - i) * sizeof(*bank));
meminfo.nr_banks++;
i++;
bank[1].size -= vmalloc_min - __va(bank->start);
bank[1].start = __pa(vmalloc_min - 1) + 1;
bank[1].highmem = highmem = 1;
j++;
}
bank->size = vmalloc_min - __va(bank->start);
}
//wxl add
printk(KERN_NOTICE "end: bank->start = %lx bank->size =%lx\n", (unsigned long)bank->start, (unsigned long)bank->size);
打印结果
end: bank->start = 30000000 bank->size = 4000000
#else
……
#endif
重设低端内存限制
if(!bank->highmem && bank->start + bank->size > lowmem_limit)
lowmem_limit =bank->start + bank->size;
j++;
}
……
未完待续,,,
[置顶] linux内核启动2-setup_arch中的内存初始化(目前分析高端内存)的更多相关文章
- [置顶] linux内核启动1-启动参数(启动参数的获取和处理,分析setup_arch)
最近公司要求调试一个内核,启动时有问题,所以就花了一点时间看看内核启动. 看的过程中总结了一点东西,希望可以帮助大家调试内核. 当我开始看的时候,第一件事是从网上搜集资料,不看不知道,一看吓一跳!牛人 ...
- linux内存(二)高端内存
来此网址 https://ilinuxkernel.com/?p=1013 Linux内核地址映射模型x86 CPU采用了段页式地址映射模型.进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访 ...
- linux-3.2.36内核启动2-setup_arch中的内存初始化1(arm平台 分析高端内存和初始化memblock)【转】
转自:http://blog.csdn.net/tommy_wxie/article/details/17093307 上一篇微博留下了这几个函数,现在我们来分析它们 sanity_c ...
- Linux内核启动分析
张超<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 我的代码可见https://www.shiyanlo ...
- Linux用户空间与内核空间(理解高端内存)
Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数 ...
- linux 用户空间与内核空间——高端内存详解
摘要:Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对 ...
- Linux用户空间与内核空间(理解高端内存)【转】
转自:http://www.cnblogs.com/wuchanming/p/4360277.html Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递 ...
- 高端内存映射之kmap持久内核映射--Linux内存管理(二十)
1 高端内存与内核映射 尽管vmalloc函数族可用于从高端内存域向内核映射页帧(这些在内核空间中通常是无法直接看到的), 但这并不是这些函数的实际用途. 重要的是强调以下事实 : 内核提供了其他函数 ...
- Linux内核高端内存 转
Linux内核地址映射模型x86 CPU采用了段页式地址映射模型.进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存. 段页式机制如下图. Linux内核地址空间划分 通 ...
随机推荐
- JavaScript 应用开发 #4:切换任务的完成状态
在勾选了任务项目左边的对号(复选框)以后,会将任务的状态标记为已完成,取消勾选的话,又会把任务的状态标记为未完成.所以, 我们需要一个可以切换任务完成状态的方法.在任务模型里面,表示任务状态的属性是 ...
- linux下安装apache2.2.27
1.首先下载httpd-2.2.27.tar.gz用linux命令下载 wget http://mirrors.cnnic.cn/apache//httpd/httpd-2.2.27.tar.gz 2 ...
- jQuery滑动并响应事件
jQuery滑动并打开指定页面: <!DOCTYPE html> <html> <head> <script src="http://code.jq ...
- 程序员带你十天快速入门Python,玩转电脑软件开发(四)
本系列文章立志于从一个已经习得一门编程语言的基础之上,全面介绍Python的相关开发过程和相关经验总结.本篇文章主要是基于上一篇的程序员带你十天快速入门Python,玩转电脑软件开发(三)的基础之上, ...
- MYSQL 基础操作
1.MySQL基础操作 一:MySQL基础操作 1:MySQL表复制 复制表结构 + 复制表数据 create table t3 like t1; --创建一个和t1一样的表,用like(表结构也一样 ...
- [Mime] MediaTypes--电子邮件类型类 (转载)
点击下载 MediaTypes.rar 这个类是关于 电子邮件类型类的操作,在发送电子邮件是规定以什么样的格式发送,Xml,HTML,文本等方式1.电子邮件类型帮助类,Xml格式,HTML格式等看下面 ...
- Android - 向服务器发送数据(GET).
在此,使用HTTP协议,通过GET请求,向服务器发送请求,这种方式适合于数据量小,数据安全性要求不高的情况下. 一,服务器端,使用Servlet. 在服务器端,定义一个HttpServlet的子类,以 ...
- 左偏树(Leftist Heap/Tree)简介及代码
左偏树是一种常用的优先队列(堆)结构.与二叉堆相比,左偏树可以高效的实现两个堆的合并操作. 左偏树实现方便,编程复杂度低,而且有着不俗的效率表现. 它的一个常见应用就是与并查集结合使用.利用并查集确定 ...
- 读书笔记之 - javascript 设计模式 - 享元模式
本章探讨另一种优化模式-享元模式,它最适合于解决因创建大量类似对象而累及性能的问题.这种模式在javascript中尤其有用,因为复杂的javascript代码很快就会用光浏览器的所有可用内存,通过把 ...
- 中文版Chrome浏览器不支持12px以下字体的解决方案
中文版Chrome浏览器不支持12px以下字体的解决方案 Chrome 27之前的中文版桌面浏览器会默认设定页面的最小字号是12px,英文版则没有限制,主要是因为chrome认为汉字小于12px就会增 ...