[Linux内存]永久内存映射kmap

一:kmap()和kunmap()函数
永久内核映射允许内核建立高端页框到内核地址空间的长期映射。他使用主内核页表中一个专门的页表,其页表地址存放在pkmap_page_table中,页表包含512项或1024项,
因此,内核一次最多访问2M或4M的高端内存(地址范围是 4G-8M 到 4G-4M 之间,这个地址空间起叫“内核永久映射空间”或者“永久内核映射空间”)。
kmap()和kunmap()函数不能用于中断处理程序,因为其可能会睡眠。

pkmap_count是一个容量为LAST_PKMAP的整数数组,其中每个元素都对应一个持久映射页。
宏定义与关键变量定义:
 pkmap_page_table:高端内存主内核页表中,一个用于永久内核映射的专用页表锁在的地址
 LAST_PKMAP: 上述页表所含有的表项(512或者1024)
 PKMAP_BASE:该页表所映射线性地址的start地址
 pkmap_count:对页表项提供计数器的数组
 page_address_htable:散列表,用于记录高端页框与永久内核映射的线性地址之间的关系
 page_address_map:一个数据结构,包含指向页描述符的指针和分配给页框的线性地址;用于为高端内存的每
      个页框提供当前映射,它被包含在page_address_htable这个hansh表中

内核主要通过以下数据结构来建立物理页page与其在虚拟内存区位置的关联

struct page_address_map {        //页地址映射
        struct page *page;            //页的描述结构
        void *virtual;                //页的虚拟地址
        struct list_head list;           //通过list字段链接到页表池全局链表page_address_pool中或page_address_htable[hash_ptr(page,PA_HASH_ORDER)].lh
};

 1 void *kmap(struct page* page)
 2 {
 3     if(!PageHighMem(page))//判断是否是高端内存
 4        return page_address(page);
 5     return kmap_high(page);
 6 }
 7 
 8 void *kmap_high(struct page *page)
 9 {
10     unsigned long vaddr;
11     spin_lock(&kmap_lock);//自旋锁
12    vaddr = (unsigned long) page_address(page);
13     if(!vaddr)   //如果该page在虚拟内存中部对应有效的地址,那么调用map_new_virtual()函数进行映射该页,
14         vaddr = map_new_virtual(page);
15     pkmap_count[(vaddr - PKMAP_BASE) >> PAGE_SHIFT]++;//pkamp_count数组包含LAST_PKAMP个计数器
16     spin_unlock(&kmap_lock);
17      return (void *) vaddr; 
18 }


 

二:kmap_atomic()临时内存函数
kmap_atomic()函数主要用于建立临时内存映射,它不能用于可能建立睡眠的代码。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值