星期三, 10月 11, 2006

Windows CE Virtual Memory Layout for Debugging

這一篇(Sue Loh's blog ) 的同名筆記:

CE只有32個process,每個process只有32MB的virtual address。
這是因為CE的設計是使用整個virtual memory address space,即使該process並不在執行中,他依然佔有該部份的virtual memory space。

CE將低位址區分成32MB大小的slot:
  • 32M的hex 是 0x02000000
  • Slot 0 = 0x00000000 - 0x01FFFFFF
  • Slot 1 = 0x02000000 - 0x03FFFFFF
  • 最後一個process的最後一個address是0x41FFFFFF
  • 0x42000000 - 0x7FFFFFFF 是"share area",給VirtualAllocs 和 memory-mapped files 使用。所以這一段不會有symbol。
  • 0x80000000以上是"kernel stuff",kernel 佔用,並且在此處執行,同時kernel load的dll(如"Installable Interrupt Routine)也使用此區域。
Slot 0 比較特殊,他的內容就是"目前正在執行的process"。目前正在執行的process除了擁有他自己的slot外,還會被mapping到slot0來。

也就是說,如果你打開一個process,檢查其中一個variable或function的address是0x00012345,而這個process 原來佔有的slot 是0x12000000 - 0x13FFFFFF,那麼在0x12012345也可以找到和0x00012345一樣的資料。

Slot 1 也很特殊,"MODULES" section內的DLL都會load到這一個slot,但是只有DLL的code部份。
如果有兩個process load相同的DLL,他們都會使用到相同的Slot 1 code,但是DLL中的global data還是會放在caller process自己的memory space中(slot 0)。

DLL 可能被load到任何地方(slot0, slot1 和kernel space)。但是Slot1 只會load ROM DLL code。

有關slot0 的load方式,EXE檔會被load到bottom (0x00000000)的地方,DLL被load到top的地方(0x01FFFFFF)中間部份則是給HEAP和STACK用。

以下,可以由address大概分出他的類型:
  • 0x00012345 : 在Slot 0,並且在bottom,所以是在EXE中
  • 0x0056789A : 雖然在Slot 0,但是距離0x00000000和0x01FFFFFF都很遠,應該不會有這麼大的EXE檔,所以大概是EXE或HEAP。
  • 0x03123456 : 在Slot 1,所以是一個DLL,實際的offset是0x02123456
  • 0x3456789A : 在以0x34000000開始的slot中,offset是0x00456789A,和第二點一樣,距離bottom, top都太遠,所以應該是heap或stack。
  • 0x019ABCDE : 離top (0x01FFFFFF)很近,所以可能是DLL。
  • 0x6789ABCD : 不在32 slot中,也不數於kernel ,所以應該是在中間"share memory"處。

原文寫的比較好,很神奇。

2 則留言:

Unknown 提到...

I have 2 question about virtual memory ...

(1). Why driver use VirtualAlloc, VirtualCopy but kernel use OALPAtoVA to map registers?
(2). Could driver direct access virtual address of registers ?

THX~~~

checko 提到...

(1) 大概是因為 CE 5.0 的driver 都是user mode driver。所以沒辦法和kernel space 用一樣的virtual table。
(2) 的話..如果你是說 arm 的 co processor 的話,好像可以 (如果compile 成 full kernel mode的話)。

網誌存檔