目的:

通过一个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

 #include <stdio.h>

 void main()
{
char *str = "hello world";
printf("%s @ %p\n", str, str);
pause();
}

编译:

$ 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

通过crash了解linux页表的更多相关文章

  1. 【原创】ARMv8 MMU及Linux页表映射

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  2. linux页表机制

    每个进程都拥有一个自己的页表,在linux中,有一个页目录数组,这是分页机制的最高层,每个进程的页表对应其中的一个页目录项,通过cr3寄存器可以访问. 一个进程的页表,对应的页表项中对应页的物理地址. ...

  3. Linux内存管理 (2)页表的映射过程

    专题:Linux内存管理专题 关键词:swapper_pd_dir.ARM PGD/PTE.Linux PGD/PTE.pgd_offset_k. Linux下的页表映射分为两种,一是Linux自身的 ...

  4. Process Kill Technology && Process Protection Against In Linux

    目录 . 引言 . Kill Process By Kill Command && SIGNAL . Kill Process By Resource Limits . Kill Pr ...

  5. linux处理闰秒

    闰秒的介绍可以参考维基百科 https://zh.wikipedia.org/wiki/闰秒 linux处理闰秒 Linux使用UTC时钟,并通过NTP (Network time protocol) ...

  6. Android平台抓取native crash log

    Android开发中,在Java层可以方便的捕获crashlog,但对于 Native 层的 crashlog 通常无法直接获取,只能通过系统的logcat来分析crash日志. 做过 Linux 和 ...

  7. Linux 虚存的性能问题

    虚存子系统是所有 UNIX 系统的核心组件.下面讨论虚存系统的实现及其对操作系统中几乎其他所有子系统的作用和影响.首先详细说明一些基本的内存管理问题:然后具体分析 Linux 操作系统如何实施虚存管理 ...

  8. Linux内存管理 (1)物理内存初始化

    专题:Linux内存管理专题 关键词:用户内核空间划分.Node/Zone/Page.memblock.PGD/PUD/PMD/PTE.lowmem/highmem.ZONE_DMA/ZONE_NOR ...

  9. Linux 驱动开发

    linux驱动开发总结(一) 基础性总结 1, linux驱动一般分为3大类: * 字符设备 * 块设备 * 网络设备 2, 开发环境构建: * 交叉工具链构建 * NFS和tftp服务器安装 3, ...

随机推荐

  1. Python 自带IDLE中调试程序

    在vs2013下调试过Python,今天试了下使用自带IDLE调试,相比而言后者效果不好. 记录一下 http://q.cnblogs.com/q/35869/ 在“Python Shell”窗口中单 ...

  2. Http Analyzer 数据抓包

    一.工具简介 这是一款实时分析 HTTP/HTTPS 数据流的工具.它可以实时捕捉HTTP/HTTPS 协议数据,可以显示许多信息(包括:文件头.内容.Cookie.查询字符窜.提交的数据.重定向的U ...

  3. oracle的常见问题与解决

    刚接触oracle,在学习过程中遇到了很多的问题,本文章将会收藏我遇到的问题及如何解决. 错误一:ORA-28009:connection as sys should be as sysdba解决方法 ...

  4. Robotium双client測试框架

    互联网的本质就是信息交换.移动互联网更是如此, 所以很多移动互联网的服务类应用中有着身份地位不同的两种用户(比如:交易中的买家和卖家, 教学中的老师和学生, 打车中的车主和乘客).近期的工作是给公司的 ...

  5. UINavigationController技巧<一>——修改返回按钮的标题

    UINavigationController 一般push到另一界面后,返回按钮标题便是上一页面的title,但是对于push的第一页或者是上一页面没有title的,返回按钮标题便是默认back,如图 ...

  6. Swift 设置navigation左右两侧按钮

    我们以设置右侧按钮为例,左侧方法类似 方法一,直接自定义文字 let item=UIBarButtonItem(title: "分享", style: UIBarButtonIte ...

  7. android捕获程序异常退出

    今天看到迅雷动漫里面一个CrashHandler 的类,我猜是崩溃处理类.进去一看.果然.顺便学习一下. Android系统的"程序异常退出",给应用的用户体验造成不良影响.为了捕 ...

  8. 传iWatch 将在7月投入生产,10月出货,支持无线充电、触控、測量脉搏

    今天又有关于 iWatch 的传言传出.据路透社的线人消息称,台湾的广达电脑(Quanta Computer Inc.)将于 7 月開始生产 iWatch.10 月出货,估计推出后首年的出货量为 50 ...

  9. 使用IIS建立自己的网站、使用C#编写IIS模拟器,更好的理解Client和Server的relation

    如何在IIS服务器上搭建自己的网站呢,今天带着这问题进行简单的实践一下,并且准备模拟一下IIS服务器工作方式,把这个工作方式搞清楚有利于发展. 1.首先应该进入控制面板=>程序=>添加或删 ...

  10. mac nodejs&npm 安装

    https://www.baidu.com/link?url=Ekv7EzWuMOXjIqFL_ewddWzdahU7jMAsWY4gOGOjMtC&ie=UTF-8&wd=nodej ...