zoukankan      html  css  js  c++  java
  • arm页表在linux中的融合

    参考:arm-linux内存页表创建

    arm的第一级页表条目数为4096个,对于4K页第二级目录条目个数为256个,一级二级条目都是每个条目4字节。

    在linux下二级分页如下:虚拟地址——> PGD转换——> PTE转换——>物理地址。

    arm-linux假装第一级目录只有2048个条目,但其实每个条目是2个ulong大小即8字节,所以最终设置MMU的还是4096个条目,只是每访问1个pgd条目将可以访问到2个pte条目,linux为了实现其内存管理功能又在后面加上2个对应的假pte表,这个假pte表专门给linux内核代码自己用的,不会影响arm硬件(事实上还有一个重要原因是,linux要求pte表长度为4K即一页)。

    #define PTRS_PER_PTE        512
    #define PTRS_PER_PMD        1
    #define PTRS_PER_PGD        2048

    看懂这个就很容易弄懂所有的创建内存映射的内容了,像为什么PTRS_PER_PTE定义为512、为什么PTRS_PER_PGD是2048、为什么PGDIR_SHIFT是21等等

    /*获得addr在dir一级页表描述符指定的二级页表中的二级页表描述符对应的linux_pte的虚拟地址*/
    #define pte_offset_kernel(dir,addr)    (pmd_page_vaddr(*(dir)) + __pte_index(addr))
    
    /*获得二级页表linux pte的虚拟地址*/
    static inline pte_t *pmd_page_vaddr(pmd_t pmd)
    {
        unsigned long ptr;
    
        ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * sizeof(void *) - 1);
        ptr += PTRS_PER_PTE * sizeof(void *);
    
        return __va(ptr);
    }
    /*获得addr对应的pte entry在二级页表中的索引*/
    #define __pte_index(addr)    (((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
    typedef struct { unsigned long pte; } pte_t;
    typedef struct { unsigned long pmd; } pmd_t;
    typedef struct { unsigned long pgd[2]; } pgd_t;
    typedef struct { unsigned long pgprot; } pgprot_t;

  • 相关阅读:
    js基础:关于Boolean() 与 if
    @@cursor_rows变量解析
    SQL Prompt
    google android sdk下载hoosts
    java环境配置
    Linux grep用法整理
    bash调试执行
    Vim常见快捷键汇总
    Linux查看磁盘块大小
    Linux Bash终端快捷键小结
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/8245306.html
Copyright © 2011-2022 走看看