• 通过crash了解linux页表


    目的:

     通过一个c语言实例,了解linux页表的组织结果和mmu的工作原理。

    通过页表找到一个物理地址, 对比物理地址与虚拟地址的内容是否一致。

    运行环境:

    $ uname -r
    3.15.6-200.fc20.x86_64

    准备工作

    1. 安装crash

    $ sudo yum install crash

    熟悉crash

    help:

    http://people.redhat.com/anderson/help.html

    White Paper:

    http://people.redhat.com/anderson/crash_whitepaper/

    1. 安装debuginfo

    $ sudo debuginfo-install kernel

    or

    $ sudo yum install kernel-debuginfo

    2. 下载一个linux源代码

    可选

    $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

    3. 准备一个C语言代码

    熟悉linux页表使用。
    hello.c

    1 #include <stdio.h>
    2 
    3 void main()
    4 {
    5     char *str = "hello world";
    6     printf("%s @ %p
    ", str, str);
    7     pause();
    8 }

    编译:

    $ gcc -o  hello hello.c

    基本概念:

    内核空间:

    32位系统, linux将最上的1G用于内核虚拟地址。空间 0xc0000000 - 0xffffffff
    linux将物理内存完全一一映射到内核空间,这样很方便管理内存,任何页面的(0M-896M的线性区)虚拟地址减去一个0xc0000000的偏移就可以得到物理地址。

    有关64位的内核线性地址起始位置:
    arch/x86/include/asm/page_64_types.h:#define __PAGE_OFFSET           _AC(0xffff880000000000, UL)

    分页原理:

    虚拟地址转化为物理地址过程。

    MMU干的事情,就是 通过 PML + PUD +  PMD  + PTE 得出虚拟地址对应的真正的内存物理地址。 

    在64位系统, 虚拟地址才用4级分页(9+9+9+12)。 PML, PUD, PMD, PTE不是1024个项(因为每项是64位)是512。

    不清楚PML是什么缩写,按照《内核》这本书的说法,应该是PGD (page directory)。

    PUD(page upper directory) PMD(page middle directory) PTE(page table entry)


    假如我们的线性地址(虚拟地址)为0x400650(例子中的地址确实是400650),得到物理地址的过程如下:

    每级页表(目录)索引值:

    PML中的目录项:  (0x400650>>(9+ 9 + 9 + 12)) & 0x1ff  = 0
    PUD中的目录项: (0x400650>>(9 + 9 + 12)) & 0x1ff  = 0
    PMD中的目录项: (0x400650>>(9 + 12)) & 0x1ff  = 0x2
    PTE中的目表项: (0x400650>>(12)) & 0x1ff  = 0

    在页中的偏移量(4K的页)

    (0x400650>>(0)) & 0xfff  = 0x650

    图示转化过程:

    cr3  包含页目录指针表, 假设为0x5427a000, 这是个物理地址。
    每级页表包含下一级页表的信息。

    下图,对于4K的页, PML的第0个目录项,0000000064e39067 为目录项中的内容,高(64-12)位(红色)是下一级页表的物理地址, 低位 12位是各种标志位(PRESENT|RW|USER|ACCESSED|DIRTY )。

     

    实践:

    1. 运行 hello

    $ ./hello
    hello world @ 0x400650

    2. 启动 crash

    crash> ps |grep hello
      24458  24204   0  ffff8801573b09e0  IN   0.0    4152    632  hello
    crash> set 24458
        PID: 24458
    COMMAND: "hello"
       TASK: ffff8801573b09e0  [THREAD_INFO: ffff880090794000]
        CPU: 0
      STATE: TASK_INTERRUPTIBLE 
    crash> px ((struct task_struct *)0xffff8801573b09e0)->mm->pgd
    $1 = (pgd_t *) 0xffff88005427a000
    crash> px (0xffff88005427a000 - 0xffff880000000000)
    $2 = 0x5427a000                                           # 相当CR3中的内容, PML的首地址
    crash> px $2 + 0x0                                        #  PML的第0项
    $3 = 0x5427a000
    crash> rd -p 0x5427a000                             #
            5427a000:  0000000064e39067                    g..d....
    crash> pte 0000000064e39067
      PTE     PHYSICAL  FLAGS
    64e39067  64e39000  (PRESENT|RW|USER|ACCESSED|DIRTY)         # 64e39000 PUD的首地址
    crash> px (0x400650>>30) & 0x1ff
    $4 = 0x0

    crash> px 0x64e39000 + 0x0                                                      #  PUD 的第0项
    $5 = 0x64e39000
    crash> rd -p 0x64e39000
            64e39000:  000000000b052067                    g ......
    crash> pte 000000000b052067
      PTE    PHYSICAL  FLAGS
    b052067   b052000  (PRESENT|RW|USER|ACCESSED|DIRTY)       # b052000 PMD的首地址
    crash> px (0x400650>>21) & 0x1ff
    $6 = 0x2
    crash> px 0xb052000 + 0x2 * 8                                                  #  PMD 的第2项
    $7 = 0xb052010
    crash> rd -p 0xb052010
             b052010:  00000000ba5a6067                    g`Z.....
    crash> pte 00000000ba5a6067
      PTE     PHYSICAL  FLAGS
    ba5a6067  ba5a6000  (PRESENT|RW|USER|ACCESSED|DIRTY)    # ba5a6000 PTE的首地址
    crash> px (0x400650>>12) & 0x1ff
    $8 = 0x0
    crash> px 0xba5a6000 + 0x0                                  #  PTE 的第0项
    $9 = 0xba5a6000
    crash> rd -p 0xba5a6000
            ba5a6000:  000000001cdc5025                    %P......
    crash> pte 000000001cdc5025
      PTE     PHYSICAL  FLAGS
    1cdc5025  1cdc5000  (PRESENT|USER|ACCESSED)            # 进程, 线性页对应的 真正的物理页框地址
    crash> px 0x400650 & 0xfff
    $10 = 0x650
    crash> px 0x1cdc5000 + 0x650                                            # “hello world.%s” 所在 的物理地址。
    $11 = 0x1cdc5650
    crash> rd -p 0x1cdc5650 2
            1cdc5650:  6f77206f6c6c6568 4020732500646c72   hello world.%s @
    crash> vtop 0x400650        # 以上步骤可以一步搞定。
    VIRTUAL     PHYSICAL        
    400650      1cdc5650        

       PML: 5427a000 => 64e39067
       PUD: 64e39000 => b052067
       PMD: b052010 => ba5a6067
       PTE: ba5a6000 => 1cdc5025
      PAGE: 1cdc5000

      PTE     PHYSICAL  FLAGS
    1cdc5025  1cdc5000  (PRESENT|USER|ACCESSED)

          VMA           START       END     FLAGS FILE
    ffff8800541f2228     400000     401000 8000875 /home/shhfeng/work/workdir/ccode/hello

          PAGE        PHYSICAL      MAPPING       INDEX CNT FLAGS
    ffffea0000737140  1cdc5000 ffff88003fc40200        0  2 3ffff800020068 uptodate,lru,active,mappedtodisk

     图示:

    0x5427a000                               0x0000000064e39000                       0x000000000b052000            0x00000000ba5a6000                      0x000000001cdc5000
         +  0                                             + 0                                                     +0x2 * 8 (64位)                       + 0                                                     +0x650
      = 0x5427a000                              =0x64e39000                                   = 0xb052010                          = 0xba5a6000                                   =  0x1cdc5650
                                                                                                                                                                                                                                                                    
     0   |0000000064e39067 |  ---->   0  |000000000b052067 | --->              |                                 |  ----> 0  |000000001cdc5025 |-->                    |                                 |
          |                                 |                |                                 |     |               |                                 |              |                                 |      |                 |                                 |
          |                                 |                |                                 |     |---> 0x2   |00000000ba5a6067|               |                                 |      .                 |                                 |
          |                                 |                |                                 |                     |                                 |              |                                 |      .                 |                                 |
          |                                 |                |                                 |                     |                                 |              |                                 |      . -->0x650  |hello world.%s @      |
          |                                 |                |                                 |                     |                                 |              |                                 |                        |                                 |
          |                                 |                |                                 |                     |                                 |              |                                 |                        |                                 |
          |                                 |                |                                 |                     |                                 |              |                                 |                        |                                 |
          |                                 |                |                                 |                     |                                 |              |                                 |                        |                                 |

         PML                                            PUD                                                 PMD                                         PTE                                                    4K的page

     

  • 相关阅读:
    BorderContainer 背景透明一不小心就解决了!
    C#编程应用线程与委托
    第二次SQL RAP要点
    最近的学习
    BW中传输的问题
    7月总结Dotnetnuke的研究总结
    EP学习要点记忆
    盲人摸象SAP PS模块的介绍与讨论
    如何跨Client删除数据
    如何修改Portal与BW系统的链接域名
  • 原文地址:https://www.cnblogs.com/shaohef/p/3887261.html
Copyright © 2020-2023  润新知