使用crash跟踪linux内核(二)- 页表(虚拟地址到物理地址转换)

一、             页表

Linux 64位内核采用4级页表实现虚拟地址到物理地址的转换,4级页表分别是:PGD -> PUD -> PMD -> PTE

1、PGD、PUD、PMD、PTE分别占9位,page offset占12位,合计48位。

2、页面大小为4KB

3、页表项为8B

4、页表可映射的地址空间为:512*512*512*512*4K=256TB

二、             地址空间

 Linux内核64位地址空间时将0x0000,0000,0000,0000 – 0x0000,7fff,ffff,f000这128T地址用于用户空间,0xffff,8000,0000,0000以上为内核地址空间。内核空间起始存在空洞,真正的系统空间的起始地址,是从0xffff,8800,0000,0000开始。即:#define __PAGE_OFFSET     _AC(0xffff,8800,0000,0000, UL)

物理地址=虚拟地址- __PAGE_OFFSET

注意:一些高版本系统对内核基地址进行随机化处理,放在page_offset_base中,如下:

crash> !uname -a
Linux sword 4.15.0-52-generic #56-Ubuntu SMP Tue Jun 4 22:49:08 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

crash> px page_offset_base
page_offset_base = $9 = 0xffff942d80000000

crash> p -x kcore_text
kcore_text = $2 = {
  list = {
    next = 0xffffffff946e4400,
    prev = 0xffffffff9453b700
  },
  addr = 0xffffffff92c00000,
  size = 0x1b6a000,
  type = 0x0
}
crash> p -x kcore_vmalloc
kcore_vmalloc = $3 = {
  list = {
    next = 0xffffffff946e4380,
    prev = 0xffffffff946e43c0
  },
  addr = 0xffffb1c380000000,
  size = 0x1fffffffffff,
  type = 0x1
}
crash> p -x kcore_modules
kcore_modules = $4 = {
  list = {
    next = 0xffff942f93fcfe00,
    prev = 0xffffffff946e4400
  },
  addr = 0xffffffffc0000000,
  size = 0x3f000000,
  type = 0x1
}

三、             举例

1、  测试程序pagetable_test

#include <stdio.h>

#include <unistd.h>

 

int main(int argc,char **argv)

{

        const char * str = "kongu106";

        printf("%s --- %p\n",str,str);

        pause();

}

2、  编译和运行程序

[root@kongu pagetable_test]# gcc -o pagetable_test main.cpp

[root@kongu pagetable_test]# ./pagetable_test

kongu106 --- 0x4006ac

分析虚拟地址0x4006ac,从低位向高位看

page offset占12位:0x6ac

      PTE占9位:0x00

      PMD占9位:0x02

      PUD占9位:0x00

      PGD占9位:0x00 

3、  跟踪pagetable_test

[root@kongu test]# cd pagetable_test/

[root@kongu pagetable_test]# crash /usr/lib/debug/lib/modules/2.6.32-431.el6.x86_64/vmlinux /boot/System.map-2.6.32-431.el6.x86_64

 

crash 6.1.0-5.el6

Copyright (C) 2002-2012  Red Hat, Inc.

Copyright (C) 2004, 2005, 2006, 2010  IBM Corporation

Copyright (C) 1999-2006  Hewlett-Packard Co

Copyright (C) 2005, 2006, 2011, 2012  Fujitsu Limited

Copyright (C) 2006, 2007  VA Linux Systems Japan K.K.

Copyright (C) 2005, 2011  NEC Corporation

Copyright (C) 1999, 2002, 2007  Silicon Graphics, Inc.

Copyright (C) 1999, 2000, 2001, 2002  Mission Critical Linux, Inc.

This program is free software, covered by the GNU General Public License,

and you are welcome to change it and/or distribute copies of it under

certain conditions.  Enter "help copying" to see the conditions.

This program has absolutely no warranty.  Enter "help warranty" for details.

 

GNU gdb (GDB) 7.3.1

Copyright (C) 2011 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law.  Type "show copying"

and "show warranty" for details.

This GDB was configured as "x86_64-unknown-linux-gnu"...

 

  SYSTEM MAP: /boot/System.map-2.6.32-431.el6.x86_64                  

DEBUG KERNEL: /usr/lib/debug/lib/modules/2.6.32-431.el6.x86_64/vmlinux (2.6.32-431.el6.x86_64)

    DUMPFILE: /dev/crash

        CPUS: 2

        DATE: Wed Jul 12 01:58:37 2017

      UPTIME: 04:09:00

LOAD AVERAGE: 0.14, 0.03, 0.01

       TASKS: 287

    NODENAME: kongu

     RELEASE: 2.6.32-431.el6.x86_64

     VERSION: #1 SMP Sun Nov 10 22:19:54 EST 2013

     MACHINE: x86_64  (2294 Mhz)

      MEMORY: 2 GB

         PID: 21054

     COMMAND: "crash"

        TASK: ffff880037555500  [THREAD_INFO: ffff880016996000]

         CPU: 1

       STATE: TASK_RUNNING (ACTIVE)

 

crash> !ps -ef | grep pagetable

root     21017  9721  0 01:52 pts/2    00:00:00 ./pagetable_test

root     21066 21054  0 01:59 pts/0    00:00:00 sh -c ps -ef | grep pagetable

root     21068 21066  0 01:59 pts/0    00:00:00 grep pagetable

crash> set 21017

    PID: 21017

COMMAND: "pagetable_test"

   TASK: ffff8800168be040  [THREAD_INFO: ffff88007cd12000]

    CPU: 0

  STATE: TASK_INTERRUPTIBLE

crash> px ((struct task_struct*)0xffff8800168be040)->mm->pgd   //PGD虚拟地址

$3 = (pgd_t *) 0xffff88003a1e2000

crash> px 0xffff88003a1e2000-0xffff880000000000    //虚拟地址转为物理地址

$4 = 0x3a1e2000                                //物理地址,运行时放在CR3

crash> rd -p 0x3a1e2000                 //PGD中第0项

        3a1e2000:  0000000016946067                    g`......

crash> pte 0000000016946067

  PTE     PHYSICAL  FLAGS

16946067  16946000  (PRESENT|RW|USER|ACCESSED|DIRTY)

crash> px 0x16946000

$5 = 0x16946000

crash> rd -p 0x16946000              //PUD中第0项

        16946000:  00000000169c3067                    g0......

crash> pte 00000000169c3067

  PTE     PHYSICAL  FLAGS

169c3067  169c3000  (PRESENT|RW|USER|ACCESSED|DIRTY)

crash> px 0x169c3000+0x2*8         //PMD中第2项

$6 = 0x169c3010

crash> rd -p 0x169c3010            

        169c3010:  000000007c0bc067                    g..|....

crash> pte 000000007c0bc067       

  PTE     PHYSICAL  FLAGS

7c0bc067  7c0bc000  (PRESENT|RW|USER|ACCESSED|DIRTY)

crash> rd -p 7c0bc000              //PTE中第0项

        7c0bc000:  000000003acc9025                    %..:....

crash> pte 000000003acc9025

  PTE     PHYSICAL  FLAGS

3acc9025  3acc9000  (PRESENT|USER|ACCESSED)

crash> px 0x3acc9000+0x6ac        //page中加偏移0x6ac

$7 = 0x3acc96ac

crash> rd -p 0x3acc96ac 4          //显示字符串

        3acc96ac:  36303175676e6f6b 202d2d2d20732500   kongu106.%s ---

        3acc96bc:  3b031b01000a7025 000000040000002c   %p.....;,.......

crash> vtop 0x4006ac             //单条命令实现转换

VIRTUAL     PHYSICAL       

4006ac      3acc96ac       

 

   PML: 3a1e2000 => 16946067

   PUD: 16946000 => 169c3067

   PMD: 169c3010 => 7c0bc067

   PTE: 7c0bc000 => 3acc9025

  PAGE: 3acc9000

 

  PTE     PHYSICAL  FLAGS

3acc9025  3acc9000  (PRESENT|USER|ACCESSED)

 

      VMA           START       END     FLAGS FILE

ffff88007c6cf850     400000     401000 8001875 /test/pagetable_test/pagetable_test

 

      PAGE       PHYSICAL      MAPPING       INDEX CNT FLAGS

ffffea0000cdcbf8 3acc9000 ffff88006a5905d8        0  3 2000000000086c

 

posted @ 2017-07-12 17:19  已秋  阅读(137)  评论(0)    收藏  举报