4

を介してプロセスのメモリを読み書きしたい/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

次に、Linux カーネル モジュールを介して仮想アドレス (VA) を PA に変換できます。たとえば、次のように変換できますVA:0x4000000000000008PA:0x100100c49f8008

第三に、関数は最後のコードでread_phy_memメモリ データを取得できます。PA:0x100100c49f8008

問題: 私の問題は、text segmentPA メモリを読み取るときはすべて問題ありませんが、data segmentPA メモリを読み取る*((long *)mapAddr)と、243 行目でシステムがダウンすることです。また、試してみました

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

それでもシステムはダウンします。

その他の情報: 私のコンピューターは IA64、OS は 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 }

テキストセグメントはうまく機能するが、データセグメントは機能しない理由を誰でも理解できますか?

4

1 に答える 1

1

プロセスが実行されている間(DLLコードではない場合)、コードセクションがメモリに残っているためだと思いますが、データセクションは継続的に出入りします。
スタックセグメントで試してください。そして、それが機能しているかどうかを確認しますか?
独自のテスト プログラムを作成し、メモリを KB 単位で動的に割り当て、そのメモリをループ内で使用し続けます。コードで試して、テストプログラムのメモリセグメントを読み取ってください。うまくいくと思います。
Windows で同様の作業を行って、IVT から BIOS アドレスを置き換えました。
root ユーザーである必要があります。

于 2012-10-09T05:21:25.360 に答える