LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2222|回复: 3

Linux内核如何使用大于1GB的物理内存。

[复制链接]
发表于 2007-5-20 19:12:58 | 显示全部楼层 |阅读模式
Linux内核建立页表项时,最多就建立了从PAGE_OFFSET(第3GB开始到4GB结束)的1G线性地址供内核使用。
如果要使用超过896M的物理内存的话,必须通过物理内存区域这个概念去完成。内核为了支持大内存,特地的为每个cpu创建了不同的内存区域。有ZONE_DMA (0-16 MB),ZONE_NORMAL (16-896 MB)和ZONE_HIGHMEM (896 MB and higher)。内核通过每个区域的struct mem_map来创建所有物理页的信息。
如果一个应用程序进行了系统调用,请求分配内存,如果不是DMA的请求,如果ZONE_NORMAL的物理内存已经用尽。那么内核使用get_free_page()会从Highmem区域拿到可用的物理内存页,而且还会通过kmap()把这个物理地址临时映射到内核所能管理的从3G到4G的虚拟地址空间中。因为kmap的映射是临时性的,并且有时会不可用。所以内核对大内存的支持还称不得上完美。

如果要使用内存区域的特性,必须要在编译内核时加上HIGHMEM_CONFIG选项。
发表于 2007-6-6 13:45:11 | 显示全部楼层
The kmap( ) function establishes a permanent kernel mapping. It is essentially equivalent to the following code:

void * kmap(struct page * page)
{
    if (!PageHighMem(page))
        return page_address(page);
    return kmap_high(page);
}


The kmap_high( ) function is invoked if the page frame really belongs to high memory. The function is essentially equivalent to the following code:

void * kmap_high(struct page * page)
{
    unsigned long vaddr;
    spin_lock(&kmap_lock);
    vaddr = (unsigned long) page_address(page);
    if (!vaddr)
        vaddr = map_new_virtual(page);
    pkmap_count[(vaddr-PKMAP_BASE) >> PAGE_SHIFT]++;
    spin_unlock(&kmap_lock);
    return (void *) vaddr;
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-6-6 17:23:23 | 显示全部楼层
多谢seskissinger兄补充
回复 支持 反对

使用道具 举报

发表于 2007-6-7 11:25:53 | 显示全部楼层
kmap()映射高端内存,但高端内存并不等同于大于1G的物理内存啊,kmap()能够映射的空间很有限,如你的物理内存真大于1G了,单纯靠kmap()帮不了根本的忙,用kmap()就像个swap,用过后还得kunmap()出去
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表