• [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与其在虚拟内存区位置的关联

    [cpp] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. struct page_address_map {        //页地址映射  
    2.         struct page *page;            //页的描述结构  
    3.         void *virtual;                //页的虚拟地址  
    4.         struct list_head list;           //通过list字段链接到页表池全局链表page_address_pool中或page_address_htable[hash_ptr(page,PA_HASH_ORDER)].lh  
    5. };  
    6.   
    7.  1 void *kmap(struct page* page)  
    8.  2 {  
    9.  3     if(!PageHighMem(page))//判断是否是高端内存  
    10.  4        return page_address(page);  
    11.  5     return kmap_high(page);  
    12.  6 }  
    13.  7   
    14.  8 void *kmap_high(struct page *page)  
    15.  9 {  
    16. 10     unsigned long vaddr;  
    17. 11     spin_lock(&kmap_lock);//自旋锁  
    18. 12    vaddr = (unsigned long) page_address(page);  
    19. 13     if(!vaddr)   //如果该page在虚拟内存中部对应有效的地址,那么调用map_new_virtual()函数进行映射该页,  
    20. 14         vaddr = map_new_virtual(page);  
    21. 15     pkmap_count[(vaddr - PKMAP_BASE) >> PAGE_SHIFT]++;//pkamp_count数组包含LAST_PKAMP个计数器  
    22. 16     spin_unlock(&kmap_lock);  
    23. 17      return (void *) vaddr;   
    24. 18 }  


     

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

  • 相关阅读:
    如何在Element 使用正则表达式校验
    Vs Code 微信小程序 神兵利器合集
    分享CSS公共类库(能在项目快捷使用CSS类)
    Element+Axios上传图片 OR 文件
    两种简洁的数组对象去重姿势
    VScode 格式化代码保存时使用ESlint修复代码
    如何在linux上部署vue项目
    Vue 2.x 3.x 配置项目开发环境跟线上环境
    在Vue文件中引入外部URL链接
    博客目录
  • 原文地址:https://www.cnblogs.com/zhiliao112/p/4251221.html
Copyright © 2020-2023  润新知