2012-05-24 27 views
4

我想通過/dev/mem來讀取和寫入進程的內存。通過/ dev/mem讀取和寫入進程內存,文本段工作但數據段不能,爲什麼?

首先,我通過一個Linux內核模塊通過自己編碼獲得進程的內存映射,輸出是這樣的:

start_code_segment  4000000000000000 
end_code_segment  4000000000019c38 
start_data_segment  6000000000009c38 
end_data_segment  600000000000b21d 
start_brk    6000000000010000 
brk      6000000000034000 
start_stack    60000fffffde7b00 

,我可以將虛擬地址(VA)轉換爲PA徹底Linux內核模塊,例如,我可以轉換VA:0x4000000000000008PA:0x100100c49f8008

,功能read_phy_mem可以獲取內存數據,代碼在最後。

問題:我的問題是,當我讀到text segment PA內存,一切都OK了,但如果我讀data segment PA內存,*((long *)mapAddr)在行243會導致系統下去。此外,我試過

memcpy(&data, (void *)mapAddr, sizeof(long)) 

但它仍然使系統停機。

其他信息:我的電腦是IA64,操作系統是Linux的2.6.18,當系統關閉,我可以從這樣的控制檯中看到的輸出信息,則系統將重新啓動。功能

Entered OS MCA handler. PSP=20010000fff21320 cpu=0 monarch=1 
cpu 0, MCA occurred in user space, original stack not modified 
All OS MCA slaves have reached rendezvous 
MCA: global MCA 
mlogbuf_finish: printing switched to urgent mode, MCA/INIT might be dodgy or fail. 
Delaying for 5 seconds... 

代碼read_phy_mem

/* 
    * pa: physical address 
    * data: memory data in pa 
    * 
    * return int: success or failed 
    */ 
188 int read_phy_mem(unsigned long pa,long *data) 
189 { 
190  int memfd; 
191  int pageSize; 
192  int shift; 
193  int do_mlock; 
194  void volatile *mapStart; 
195  void volatile *mapAddr; 
196  unsigned long pa_base; 
197  unsigned long pa_offset; 
198 
199  memfd = open("/dev/mem", O_RDWR | O_SYNC); 
200  if(memfd == -1) 
201  { 
202   perror("Failed to open /dev/mem"); 
203   return FAIL; 
204  } 
205 
206  shift = 0; 
207  pageSize = PAGE_SIZE; //#define PAGE_SIZE 16384 
208  while(pageSize > 0) 
209  { 
210   pageSize = pageSize >> 1; 
211   shift ++; 
212  } 
213  shift --; 
214  pa_base = (pa >> shift) << shift; 
215  pa_offset = pa - pa_base; 
224  mapStart = (void volatile *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_LOCKED, memfd, pa_base); 
226  if(mapStart == MAP_FAILED) 
227  { 
228   perror("Failed to mmap /dev/mem"); 
229   close(memfd); 
230   return FAIL; 
231  } 
232  if(mlock((void *)mapStart, PAGE_SIZE) == -1) 
233  { 
234   perror("Failed to mlock mmaped space"); 
235   do_mlock = 0; 
236  } 
237  do_mlock = 1; 
238 
239  mapAddr = (void volatile *)((unsigned long)mapStart + pa_offset); 
243  printf("mapAddr %p %d\n", mapAddr, *((long *)mapAddr)); 
256  if(munmap((void *)mapStart, PAGE_SIZE) != 0) 
257  { 
258   perror("Failed to munmap /dev/mem"); 
259  } 
260  close(memfd); 
269  return OK; 
270 } 

誰能明白爲什麼文本片段效果很好,但數據段不?

+0

MCA處理程序正在調用說有些事情是錯的。見[this] [1]和[this] [2]。還有一些關於[IA64上的MCA]的內核文檔[3]。 [1]:http://en.wikipedia.org/wiki/Machine_check_architecture [2]:http://en.wikipedia.org/wiki/Machine_Check_Exception [3]:HTTP://www.kernel .ORG/DOC /文檔/ IA64/mca.txt –

回答

1

我猜想,它的發生是因爲代碼段在進程執行時仍保留在內存中(如果不是DLL代碼),而數據段連續保留在&之外。
嘗試使用堆棧段。並檢查它的工作?
編寫您自己的測試程序,並以KB爲單位動態分配內存,並在循環中保持該內存的使用。比用你的代碼嘗試讀取測試程序的內存段。我認爲它會起作用。
我已經做了類似的工作在Windows中取代IVT的BIOS地址。
應該是root用戶。

相關問題