• 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;

  • 相关阅读:
    Eclipse安装python注意事项
    C# 计算文件MD5
    C# 为私有方法添加单元测试(反射)
    .net 操作sftp服务器
    在ASP.NET MVC中使用Unity进行依赖注入的三种方式
    ASP.NET Web API 安全筛选器
    Token Based Authentication in Web API 2
    IIS中查看W3P.exe进程对应的应用程序池的方法
    WCF自定义Header
    sqlserver 用 RowNumber 分组
  • 原文地址:https://www.cnblogs.com/yangjiguang/p/8245306.html
Copyright © 2020-2023  润新知