易网时代-编程资源站
Welcome
微信登录
首页
/
操作系统
/
Linux
/
Linux物理内存管理区初始化
Linux物理内存管理区在start_kernel函数中进行初始化,此时启动分配器已经建立,所以可以从bootmem中分配需要的内存。
一、全局变量初始化
max_pfn:最大物理页面帧号
start_kernel()->setup_arch()->e820_end_of_ram_pfn()找出最大可用内存页面帧号。
void
__init setup_arch(
char
**cmdline_p)
{
……
/*
* partially used pages are not usable - thus
* we are rounding upwards:
*/
/*遍历e820.map,找到系统中得最大内存数,
这个内存数需小于4G*/
max_pfn = e820_end_of_ram_pfn();
……
}
unsigned
long
__init e820_end_of_ram_pfn(
void
)
{
/*MAX_ARCH_PFN为4G空间*/
return
e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
}
/*
* Find the highest page frame number we have available
*/
static
unsigned
long
__init e820_end_pfn(unsigned
long
limit_pfn, unsigned type)
{
int
i;
unsigned
long
last_pfn = 0;
unsigned
long
max_arch_pfn = MAX_ARCH_PFN;
/*4G地址空间对应的页面数*/
/*对e820中所有的内存块,其中e820为从bios中探测到的页面数存放处*/
for
(i = 0; i < e820.nr_map; i++) {
struct
e820entry *ei = &e820.map[i];
/*第i个物理页面块*/
unsigned
long
start_pfn;
unsigned
long
end_pfn;
if
(ei->type != type)
/*与找的类型不匹配*/
continue
;
/*起始地址对应的页面帧号*/
start_pfn = ei->addr >> PAGE_SHIFT;
/*结束物理地址对应的页面帧号*/
end_pfn = (ei->addr + ei->size) >> PAGE_SHIFT;
if
(start_pfn >= limit_pfn)
continue
;
if
(end_pfn > limit_pfn) {
last_pfn = limit_pfn;
/*找到的结束页面帧号大于限制大小时*/
break
;
}
if
(end_pfn > last_pfn)
last_pfn = end_pfn;
/*保存更新last_pfn*/
}
if
(last_pfn > max_arch_pfn)
/*大于4G空间时*/
last_pfn = max_arch_pfn;
/*打印输出信息*/
printk(KERN_INFO
"last_pfn = %#lx max_arch_pfn = %#lx "
,
last_pfn, max_arch_pfn);
/*返回最后一个页面帧号*/
return
last_pfn;
}
max_low_pfn:低端内存最大页面数
start_kernel()->setup_arch()->find_low_pfn_range()
/*
* Determine low and high memory ranges:
*/
/*找到低端内存的做大内存页面数,初始化两个变量*/
void
__init find_low_pfn_range(
void
)
{
/* it could update max_pfn */
/*当内存的大小本来就小于低端内存的做大页框数时;
直接没有高端地址映射*/
if
(max_pfn <= MAXMEM_PFN)
lowmem_pfn_init();
else
/*这是一般PC机的运行流程,存在高端映射*/
highmem_pfn_init();
}
我们直接看具有高端地址空间的部分。
/*
* We have more RAM than fits into lowmem - we try to put it into
* highmem, also taking the highmem=x boot parameter into account:
*/
/*高端地址空间的页面数可以在启动中进行配置;
如果不配置,在这里进行设置大小*/
void
__init highmem_pfn_init(
void
)
{
/*MAXMEM_PFN为最大物理地址-(4M+4M+8K+128M);
所以低端内存的大小其实比我们说的896M低一些*/
max_low_pfn = MAXMEM_PFN;
if
(highmem_pages == -1)
/*高端内存页面数如果在开机没有设置*/
highmem_pages = max_pfn - MAXMEM_PFN;
/*总页面数减去低端页面数*/
/*如果highmem_pages变量在启动项设置了,那么在这里就要进行这样的判断,因为可能出现不一致的情况*/
if
(highmem_pages + MAXMEM_PFN < max_pfn)
max_pfn = MAXMEM_PFN + highmem_pages;
if
(highmem_pages + MAXMEM_PFN > max_pfn) {
printk(KERN_WARNING MSG_HIGHMEM_TOO_SMALL,
pages_to_mb(max_pfn - MAXMEM_PFN),
pages_to_mb(highmem_pages));
highmem_pages = 0;
}
#ifndef CONFIG_HIGHMEM
/* Maximum memory usable is what is directly addressable */
printk(KERN_WARNING
"Warning only %ldMB will be used. "
, MAXMEM>>20);
if
(max_pfn > MAX_NONPAE_PFN)
printk(KERN_WARNING
"Use a HIGHMEM64G enabled kernel. "
);
else
printk(KERN_WARNING
"Use a HIGHMEM enabled kernel. "
);
max_pfn = MAXMEM_PFN;
#else /* !CONFIG_HIGHMEM *//*存在高端地址情况*/
#ifndef CONFIG_HIGHMEM64G
/*在没有配置64G的情况下,内存的大小不能超过4G*/
if
(max_pfn > MAX_NONPAE_PFN) {
max_pfn = MAX_NONPAE_PFN;
printk(KERN_WARNING MSG_HIGHMEM_TRIMMED);
}
#endif /* !CONFIG_HIGHMEM64G */
#endif /* !CONFIG_HIGHMEM */
}
1
2
3
下一页
为GRUB2添加背景图片Linux内存管理之活动内存区相关资讯 Linux基础教程
Linux基础教程:对文件打包压缩 (03月08日)
基础教程:Linux 新手应该知道的 (09/06/2015 21:17:20)
Linux基础教程:find 与 xargs (04/05/2015 10:20:11)
Linux基础教程:tar 命令使用介绍 (12/03/2015 13:19:47)
Linux基础教程(1)操作系统基础 (08/15/2015 20:44:01)
Linux基础教程:从源码安装软件 (04/05/2015 10:14:45)
本文评论 查看全部评论 (0)
表情: 姓名:
匿名
字数
版权所有©石家庄振强科技有限公司2024
冀ICP备08103738号-5
网站地图