ARM cortex_A9_MPCORE プロセッサを搭載した開発ボード (スノーボール) を使用しており、3.0.8 以降のカーネルで Linux を実行しています。デバッグには GDB と openocd を使用します。
ユーザー モード プロセス、特にテキスト セグメントとユーザー モード スタックのアドレス空間を見つける方法を探しています。
最初に /proc/"PID"/maps を調べました。たとえば、実行中のプロセスの 1 つについて次の出力が得られます。
# cat /proc/1124/maps
00008000-000d5000 r-xp 00000000 b3:02 181 /system/bin/lbsd
000d5000-000f8000 rw-p 000cd000 b3:02 181 /system/bin/lbsd
000f8000-0014a000 rw-p 00000000 00:00 0 [heap]
0014a000-0014c000 rw-p 00000000 00:00 0 [heap]
.
.
.
b0001000-b0009000 r-xp 00001000 b3:02 183 /system/bin/linker
b0009000-b000a000 rw-p 00009000 b3:02 183 /system/bin/linker
b000a000-b0015000 rw-p 00000000 00:00 0
bea00000-bea21000 rw-p 00000000 00:00 0 [stack]
ffff0000-ffff1000 r-xp 00000000 00:00 0 [vectors]
次に、GDB を使用して、init_task から始まるボード上で実行されているタスクのリストを解析するスクリプトを作成しました。タスクごとに、task_struct で見つかった mm_struct の値を取得し、start_code、end_code、および start_stack の値を抽出します。最後に、スクリプトは、mmap が指すさまざまなメモリ領域を解析します。ボードがデバッグ状態にある間にスクリプトが実行され、cortex a9 の両方のコアが停止します。
上記と同じプロセスの GDB スクリプトの出力を次に示します。
taskaddr 0xdf29f140
Name: lbsd
mm start text 8000
mm end text d4ba4
mm start stack bee63df0
####MEMORY REGIONS#####
vm_start 0x8000
vm_end 0xd5000
vm_flags 0x8001875
-----------------------
vm_start 0xd5000
vm_end 0xf8000
vm_flags 0x8101873
-----------------------
vm_start 0xf8000
vm_end 0x14a000
vm_flags 0x100073
-----------------------
vm_start 0x14a000
vm_end 0x14c000
vm_flags 0x100073
-----------------------
.
.
.
-----------------------
vm_start 0xb0001000
vm_end 0xb0009000
vm_flags 0x8000875
-----------------------
vm_start 0xb0009000
vm_end 0xb000a000
vm_flags 0x8100873
-----------------------
vm_start 0xb000a000
vm_end 0xb0015000
vm_flags 0x100073
-----------------------
vm_start 0xbee42000
vm_end 0xbee64000
vm_flags 0x100173
-----------------------
vm_start 0xffff0000
vm_end 0xffff1000
vm_flags 0x40c0055
-----------------------
メモリ領域は、スタックを除いて使用される両方のメソッドで一致します。/proc メソッドの出力では、bea00000 から始まりますが、mm_struct の start_stack フィールドでは、bee63df0 にあり、vm_struct が指すメモリ領域は bee42000 を示します。誰かがこれらの値の違いを説明できますか?
2 番目の質問は、プロセスのテキスト セクションに対応する 00008000 と 000d5000 の間の最初のメモリ領域の値についてです。多くのプロセスがこれらのアドレスを共有していることに気付きました。カーネルはどのようにしてテキスト メモリ領域の実際のアドレスを取得するのでしょうか?