link もっと前
   2017年 7月 12日 -
      2017年 7月 3日  
link もっと後

link 未来から過去へ表示(*)
link 過去から未来へ表示

日々

link permalink

仮想アドレスから物理アドレスへ

ちょっと用事があって、ユーザプロセスの仮想アドレスから、物理アドレスへの変換を行うプログラムを作りました。名前は v2p(virt2phys)です。何の捻りもありません。ソースコードは GitHub に置いています。

やっていることは /proc/pid/pagemap を読んで、わかりやすい形式で表示しているだけです。言葉で説明するより動いている姿の方がわかりやすいと思います。

実験に使った環境は Debian GNU/Linux Testing amd64 版です。別に Debian じゃなくても最近の Linux なら動くと思います。

このツールの実行には、プロセス ID と仮想アドレスが必要です。まず解析に使うプロセスを作って、プロセス ID を調べます。

cat を実行&中断
$ cat
[Press Ctrl+Z]
[1]+  Stopped                 cat

$ ps
  PID TTY          TIME CMD
 2148 pts/4    00:00:00 bash
14010 pts/4    00:00:00 cat  ★★cat の PID を覚えておく★★
14015 pts/4    00:00:00 ps

プロセス ID がわかったら、物理アドレスに変換したい仮想アドレスを決めます。ここでは例としてヒープ領域の先頭アドレスを変換しましょう。

cat のヒープ領域の仮想アドレス
$ cat /proc/14010/maps
55ff09a4f000-55ff09a57000 r-xp 00000000 08:11 5505114                    /bin/cat
55ff09c56000-55ff09c57000 r--p 00007000 08:11 5505114                    /bin/cat
55ff09c57000-55ff09c58000 rw-p 00008000 08:11 5505114                    /bin/cat
55ff0b2cb000-55ff0b2ec000 rw-p 00000000 00:00 0                          [heap]    ★★これを使う★★
7fdbeb6a3000-7fdbeb838000 r-xp 00000000 08:11 4980859                    /lib/x86_64-linux-gnu/libc-2.24.so
7fdbeb838000-7fdbeba38000 ---p 00195000 08:11 4980859                    /lib/x86_64-linux-gnu/libc-2.24.so
...(snip)...
7ffdde79c000-7ffdde7be000 rw-p 00000000 00:00 0                          [stack]
7ffdde7fb000-7ffdde7fd000 r--p 00000000 00:00 0                          [vvar]
7ffdde7fd000-7ffdde7ff000 r-xp 00000000 00:00 0                          [vdso]

プロセス ID と仮想アドレスがわかったので、物理アドレスに変換します。

仮想アドレスから物理アドレスへ
$ sudo ./src/v2p 14010 0x55ff0b2cb000 0x4000
pid: 14010:
 virt:0x55ff0b2cb000, phys:0x73a42b000
 virt:0x55ff0b2cc000, phys:(not present)
 virt:0x55ff0b2cd000, phys:(not present)
 virt:0x55ff0b2ce000, phys:(not present)

変換できました。特権のない状態で実行すると全て 0x00000000 になってしまいますので、お気をつけください。

表示の意味は特に何の捻りもなく、物理アドレスをそのまま示しています。ちなみに (not present) と表示される場合は、まだカーネルからページが割り当てられておらず、仮想アドレスに対応する物理アドレスが存在しないことを意味しています。

デマンドページング

これだけだと GitHub に書いた Readme そのものだし、へぇー…って感じがするだけで面白くないので、cat に gdb でアタッチしてヒープ領域を触ったらどうなるか見てみます。

gdb でアタッチして 3番目と 5番目のページを read する
$ sudo ./src/v2p 14010 0x55ff0b2cb000 0x6000
pid: 14010:
 virt:0x55ff0b2cb000, phys:0x73a42b000
 virt:0x55ff0b2cc000, phys:(not present)
 virt:0x55ff0b2cd000, phys:(not present) ★これを読む★
 virt:0x55ff0b2ce000, phys:(not present)
 virt:0x55ff0b2cf000, phys:(not present) ★これを読む★
 virt:0x55ff0b2d0000, phys:(not present)


$ gdb -p 14010
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
...
0x00007fdbeb77e690 in __read_nocancel ()
    at ../sysdeps/unix/syscall-template.S:84
84      ../sysdeps/unix/syscall-template.S: そのようなファイルやディレクトリはありません.

(gdb) x/4x 0x55ff0b2cd000
0x55ff0b2cd000: 0x00000000      0x00000000      0x00000000      0x00000000

(gdb) x/4x 0x55ff0b2cf000
0x55ff0b2cf000: 0x00000000      0x00000000      0x00000000      0x00000000


$ sudo ./src/v2p 14010 0x55ff0b2cb000 0x4000
pid: 14010:
 virt:0x55ff0b2cb000, phys:0x73a42b000
 virt:0x55ff0b2cc000, phys:(not present)
 virt:0x55ff0b2cd000, phys:0x1cb695000 ★ゼロページが割り当たる★
 virt:0x55ff0b2ce000, phys:(not present)
 virt:0x55ff0b2cf000, phys:0x1cb695000 ★ゼロページが割り当たる★
 virt:0x55ff0b2d0000, phys:(not present)

試しに 3番目と 5番目の領域からデータを読み出してみました、どちらも 0 データが見えます。読み出したあとは 0x1cb695000(数字は環境によって違います)という同じアドレスが割り当たりました。このアドレスは全て 0 で埋まっている特殊なページを指していて、読み出したときにとにかく 0 データを返せば良い領域に使われるらしいです。

じゃあ今度は書いてみたらどうなるでしょう?

gdb でアタッチして 2番目と 3番目のページを read する
$ sudo ./src/v2p 14010 0x55ff0b2cb000 0x6000
pid: 14010:
 virt:0x55ff0b2cb000, phys:0x73a42b000
 virt:0x55ff0b2cc000, phys:(not present) ★これに書く★
 virt:0x55ff0b2cd000, phys:0x1cb695000   ★これに書く★
 virt:0x55ff0b2ce000, phys:(not present)
 virt:0x55ff0b2cf000, phys:0x1cb695000
 virt:0x55ff0b2d0000, phys:(not present)


(gdb) set *((long *)(0x55ff0b2cc000))=0x89abcdef

(gdb) x/4x 0x55ff0b2cc000
0x55ff0b2cc000: 0x89abcdef      0x00000000      0x00000000      0x00000000

(gdb) set *((long *)(0x55ff0b2cd000))=0x12345678

(gdb) x/4x 0x55ff0b2cd000
0x55ff0b2cd000: 0x12345678      0x00000000      0x00000000      0x00000000


$ sudo ./src/v2p 14010 0x55ff0b2cb000 0x4000
pid: 14010:
 virt:0x55ff0b2cb000, phys:0x73a42b000
 virt:0x55ff0b2cc000, phys:0x73c76a000 ★ページが割り当たる★
 virt:0x55ff0b2cd000, phys:0x72edd0000 ★ゼロページが外され、別のページが割り当たる★
 virt:0x55ff0b2ce000, phys:(not present)
 virt:0x55ff0b2cf000, phys:0x1cb695000
 virt:0x55ff0b2d0000, phys:(not present)

2番目の (not present) な領域にも書けますし、3番目のゼロページが割り当たっている領域にも書けます。読み出してみても、ちゃんと書けていることがわかります。

書き込んだあとの仮想アドレスと物理アドレスの対応を見ると、2番目は read した時とは違ってゼロページではなさそうなアドレスが割当たります。3番目はゼロページが外され、別のページが割り当てられます。

不思議に見えるかも知れませんが、ゼロページは 0 データを返す専門なので、書き込みができません、というかカーネルが書き込みを許しません。ゼロページに書き込もうとした場合はゼロページを外して別のページを割り当て、以降はそのページを使って下さい、という仕組みになっています。

[編集者: すずき]
[更新: 2017年 7月 4日 00:29]
link 編集する

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
   2017年 7月 12日 -
      2017年 7月 3日  
link もっと後

管理用メニュー

link 記事を新規作成

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDF ファイル RSS 1.0
QR コード QR コード

最終更新: 11/14 02:08

カレンダー

<2017>
<<<07>>>
------1
2345678
9101112131415
16171819202122
23242526272829
3031-----

最近のコメント 5件

  • link 18年10月12日
    すずき 「なるほど!\n京急、京成はヤバそうですね...」
    (更新:10/15 23:02)
  • link 18年10月12日
    ちかふみ 「閉会式直後の出国ラッシュ対策のためだそう...」
    (更新:10/15 20:43)
  • link 18年10月12日
    すずき 「あー、なるほど!閉会式の次にくっつけたん...」
    (更新:10/14 15:44)
  • link 18年10月12日
    hdk 「2020年の東京オリンピックが8月9日ま...」
    (更新:10/14 10:45)
  • link 18年09月07日
    すずき 「ありがとう!\nこちらこそ、楽しみにして...」
    (更新:09/11 19:30)

最近の記事 20件

link もっとみる
  • link 18年11月13日
    すずき 「[お気に入りのマンガ] Kindle Fire HD は大量の本を...」
    (更新:11/14 02:08)
  • link 18年11月10日
    すずき 「[ROCK64 の I2S が動かない] 先日(2018年 7月 ...」
    (更新:11/14 01:53)
  • link 18年11月11日
    すずき 「[linux-next で動かない ROCK64 の I2S] 昨...」
    (更新:11/14 01:52)
  • link 18年11月09日
    すずき 「[遠くに映せ] LAN ケーブルで HDMI 伝送できる世界初の ...」
    (更新:11/09 15:03)
  • link 18年11月12日
    すずき 「[Kindle のシステムアップデート] Kindle fire ...」
    (更新:11/09 14:53)
  • link 18年11月08日
    すずき 「[家にたくさんマウスとキーボードがある] 引っ越し荷物を開梱してい...」
    (更新:11/09 14:43)
  • link 18年11月06日
    すずき 「[職業ダブってた] 先日(2018年 10月 15日の日記参照)気...」
    (更新:11/09 14:42)
  • link 18年10月15日
    すずき 「[ダブル職業] Facebook って、職業の「現在も働いています...」
    (更新:11/09 14:38)
  • link 18年10月14日
    すずき 「[ROCK64 の I2S とクロック] また忘れてしまいそうなの...」
    (更新:10/16 01:37)
  • link 18年10月13日
    すずき 「[Welcome back ROCK64] やっと ROCK64 ...」
    (更新:10/15 23:20)
  • link 18年10月11日
    すずき 「[俺たちの引っ越しはまだ終わらない] 引っ越しの荷物は、終盤にヤケ...」
    (更新:10/15 23:19)
  • link 18年10月12日
    すずき 「[時代の移り変わりと休日] ちょっと古いニュースですが、皇位継承前...」
    (更新:10/14 02:02)
  • link 18年09月29日
    すずき 「[Facebook と東京都大田区] 引っ越したので Facebo...」
    (更新:10/07 18:12)
  • link 18年09月15日
    すずき 「[TigerVNC のエラーメッセージ] TigerVNC Jav...」
    (更新:09/20 11:22)
  • link 18年09月16日
    すずき 「[音が出なくなったよ Windows 10] 昨日まで元気に動作し...」
    (更新:09/20 11:10)
  • link 18年09月13日
    すずき 「[府民から都民へ] 家が決まりました。今月末から東京都民です。さよ...」
    (更新:09/17 20:03)
  • link 18年09月11日
    すずき 「[エアコン浄化] 今年の 7月に(2018年 7月 17日の日記参...」
    (更新:09/17 19:38)
  • link 18年09月10日
    すずき 「[引っ越し準備] 引っ越し用の新品の段ボールが 50箱以上届き、家...」
    (更新:09/17 19:32)
  • link 18年09月07日
    すずき 「[最終勤務日] 今日は Socionext の最終勤務日でした。9...」
    (更新:09/09 01:21)
  • link 18年09月06日
    すずき 「[さくらのメールサーバーと git send-email] 自宅か...」
    (更新:09/07 01:24)

こんてんつ

open/close wiki
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報