/*************************************************/
crash> task_struct | grep mm_struct
struct mm_struct *mm;
struct mm_struct *active_mm;
crash> mm_struct | grep pgd
pgd_t *pgd;
crash>
crash> ps | grep ">"
> 0 0 1 e6846c00 RU 0.0 0 0 [swapper/1]
> 1190 1 0 e68dcca0 RU 0.1 820 460 sh
内核进程的mm成员为NULL,需要使用active_mm成员。
crash> task_struct.active_mm e6846c00
active_mm = 0xe606b040
crash> mm_struct.pgd 0xe606b040
pgd = 0xe6368000
crash> task_struct.active_mm e68dcca0
active_mm = 0xe63c8d80
crash> task_struct.mm e68dcca0
mm = 0xe63c8d80
crash> mm_struct.pgd 0xe63c8d80
pgd = 0xe6390000
每个进程的pgd的大小应该是 16K 2^32/2^21 = 2^11 = 2K*8 = 16K(每个pgd占8个字节)
每个进程使用16K的pgd,看上去很大,如果是256M的内存,可能的进程个数为2^8*2^20/2^14 = 2^14=16*1024个进程
一万多个,看上去还行。
内核空间的pgd内容应该相同:使用上面的两个进程的 pgd 验证:
内核空间占页表的后1/4:也就是后4K【12-16】
从12K 开始:0x3000(12KB)
crash> rd e6393000 16
e6393000: 8001140e 8011140e 8021140e 8031140e ..........!...1.
e6393010: 8041140e 8051140e 8061140e 8071140e ..A...Q...a...q.
e6393020: 8081140e 8091140e 80a1140e 80b1140e ................
e6393030: 80c1140e 80d1140e 80e1140e 80f1140e ................
crash> rd e636b000 16
e636b000: 8001140e 8011140e 8021140e 8031140e ..........!...1.
e636b010: 8041140e 8051140e 8061140e 8071140e ..A...Q...a...q.
e636b020: 8081140e 8091140e 80a1140e 80b1140e ................
e636b030: 80c1140e 80d1140e 80e1140e 80f1140e ................
从14K开始
crash> rd 0xe636b800 16
e636b800: a001140e a011140e a021140e a031140e ..........!...1.
e636b810: a041140e a051140e a061140e a071140e ..A...Q...a...q.
e636b820: a081140e a091140e a0a1140e a0b1140e ................
e636b830: a0c1140e a0d1140e a0e1140e a0f1140e ................
crash> rd 0xe6393800 16
e6393800: a001140e a011140e a021140e a031140e ..........!...1.
e6393810: a041140e a051140e a061140e a071140e ..A...Q...a...q.
e6393820: a081140e a091140e a0a1140e a0b1140e ................
e6393830: a0c1140e a0d1140e a0e1140e a0f1140e ................
从15K开始:
有些数据段是不同,页表和没有同步。当代码段和常量数据段肯定是相同的。
不同的进程的 mm_struct是一样的,这也许就是所说的线程?
1599 1 0 e68f8140 IN 0.5 58692 3516 Binder_1
1600 1 0 e6ba1cc0 IN 0.5 58692 3516 Binder_2
crash> task_struct.mm e68f8140
mm = 0xe606b040
crash> task_struct.mm e6ba1cc0
mm = 0xe606b040
现在看一下主内核页表:
crash> eval (0xc0004000+0x3000) 【+12K 内核线性地址开始的地方】
crash> rd c0007000 16
c0007000: 8201140e 8211140e 8221140e 8231140e ..........!...1.
c0007010: 8241140e 8251140e 8261140e 8271140e ..A...Q...a...q.
c0007020: 8281140e 8291140e 82a1140e 82b1140e ................
c0007030: 82c1140e 82d1140e 82e1140e 82f1140e ................
用户空间的线性地址范围前3G:对应的pgd entry 都是0.
crash> eval (c0007000-0x40)
hexadecimal: c0006fc0
crash> rd c0006fc0 16
c0006fc0: 00000000 00000000 00000000 00000000 ................
c0006fd0: 00000000 00000000 00000000 00000000 ................
c0006fe0: 00000000 00000000 00000000 00000000 ................
c0006ff0: 00000000 00000000 b07ef811 b07efc11 ..........~...~.
后面两个2是什么内容,为什么不是0?干什么用的?,以后也许会知道。
/*所有的内核线程包括idle都共享同一个地址空间:pgd = 0xc0004000*/
> 5 2 0 ee073c00 RU 0.0 0 0 [kworker/u:0]
crash> task_struct ee073c00 | grep "mm"
mm = 0x0,
active_mm = 0xc0751ca0 <init_mm>,
comm = "kworker/u:0\000\000\000\000",
crash> mm_struct | grep "pgd"
pgd_t *pgd;
crash> mm_struct.pgd 0xc0751ca0
pgd = 0xc0004000