LoginSignup
5
6

More than 5 years have passed since last update.

Linuxのデバイスドライバから、仮想メモリ上のユーザプロセスメモリを任意のタイミングで読み書きする

Posted at

ユーザプロセスのメモリをデバイスドライバから任意のタイミングで読み書きする方法のまとめ

Sample code to read/write user process's memory on virtual address from Linux device driver at any given time
https://github.com/mnishz/read_write_user_memory_from_driver

簡単な経緯

仕事で、上に書いたようなことを実現する必要があった。
read(), write(), ioctl() 等でユーザプロセスの仮想アドレスを渡して、その関数内でcopy_to_user(), copy_from_user() から読み書きすることはできたが、ドライバ側でその仮想アドレスを覚えておいて関数を抜けた後に同様に読み書きしようとするとうまくいかなかった。ユーザプロセスの仮想アドレスしか持ち合わせていない状態でどうやって読み書きしているのかまで追えていないが、コンテキストが絡んでいるのかなーと想像する。
以下、どうやればできるかなと試行錯誤した結果のまとめ。

やり方

ユーザプロセス側

  1. ユーザプロセス側からヒープメモリを確保する (スタックでも問題ないかも)
  2. スワップアウトされないように mlock() しておく (多分必要)
  3. 仮想アドレスを物理アドレスに変換する
  4. ioctl() で物理アドレスを渡す

デバイスドライバ側

  1. 受け取った物理アドレスを copy_from_user() でカーネル側にコピーする
  2. ioremap() で物理アドレスをカーネルの仮想アドレスにマッピングする
  3. マッピングした仮想アドレスから任意のタイミングでユーザメモリを読み書きできる

サンプルコードで何をやっているのか

user_proc_A ではメモリを確保して ioctl() で物理アドレスをドライバに渡したあと、値が変わるのをループで待っている。user_proc_B で別の ioctl() を投げるとドライバが user_proc_A のメモリを書き換えて、それにより user_proc_A がループを抜けて終了する。

参考リンク

https://qiita.com/take-iwiw/items/26d5f7f4894ccc4ce227
https://www.ibm.com/developerworks/jp/linux/library/l-kernel-memory-access/index.html
http://mmi.hatenablog.com/entry/2017/03/21/151320

5
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6