web-dev-qa-db-ja.com

/ dev / memとは何ですか?

おそらくそれはメモリに何らかの関係があるのでしょうか?何だろう

Sudo cat /dev/urandom > /dev/mem

行う?すべてのRAMをゴミ箱に捨てますか?カーネル以外のすべての仮想メモリ?上記のどれでもない?

40
Paul

システムの物理メモリへのアクセスを提供します。

mem(4) manページ は、/dev/memです。

はい-それはあらゆる種類の問題を引き起こす可能性があります。再起動すると問題が解決するはずですが、悪いことが簡単に起こります。注意してください! :-)

32
Andrew Flanagan

/ dev/memは、仮想メモリではなく、システムの物理メモリへのアクセスを提供します。カーネルの仮想アドレス空間には、/ dev/kmemを使用してアクセスできます。

これは主に、ビデオアダプターなどの周辺ハードウェアに関連するIOメモリアドレスにアクセスするために使用されます。

18
rags

Sudo cat /dev/urandom > /dev/memは何もしません。Sudoはcatの権限を昇格させますが、リダイレクトの権限は昇格しないためです。 Sudo suを実行してからルートシェルで作業するか、
Sudo dd if=/dev/urandom of=/dev/mem

/dev/memは、物理メモリ、つまりシステム内のすべてのRAMへのアクセスを提供しますが、これはRAMへの完全な読み取り/書き込みアクセスを提供することを意味しません(CONFIG_STRICT_DEVMEMオプションを参照) this ドキュメント)。また、物理メモリの一部の領域には、ビデオカードメモリなどの他のデバイスがマッピングされていることに注意してください。

/dev/memに盲目的に書き込むと、動作が不確実になります here は、同じことを行うyoutubeビデオです。

9
Sahil Singh

busybox devmemでテストしてください

busybox devmemは、/dev/memをmmapする小さなCLIユーティリティです。

あなたはUbuntuでそれを得ることができます:Sudo apt-get install busybox

使用法:物理アドレスから4バイトを読み取る0x12345678

Sudo busybox devmem 0x12345678

そのアドレスに0x9abcdef0を書き込みます。

Sudo busybox devmem 0x12345678 w 0x9abcdef0

ソース: https://github.com/mirror/busybox/blob/1_27_2/miscutils/devmem.c#L85

MAP_SHARED

/dev/memをmmappingするときは、おそらく次のように使用します。

open("/dev/mem", O_RDWR | O_SYNC);
mmap(..., PROT_READ | PROT_WRITE, MAP_SHARED, ...)

MAP_SHAREDを指定すると、書き込みがすぐに物理メモリに書き込まれます。これにより、監視が容易になり、ハードウェアレジスタの書き込みに適しています。

CONFIG_STRICT_DEVMEMおよびnopat

カーネル[v4.9]で/dev/memを使用して通常のRAM=を表示および変更するには、以下の操作を行う必要があります。

  • CONFIG_STRICT_DEVMEMを無効にします(Ubuntu 17.04ではデフォルトで設定されています)
  • x86のnopatカーネルコマンドラインオプションを渡す

IOポートはそれらがなくても機能します。

参照: https://stackoverflow.com/questions/39134990/mmap-of-dev-mem-fails-with-invalid-argument-for-virt-to-phys-address-but-addre/45127582 #45127582

キャッシュフラッシュ

レジスタの代わりにRAMに書き込もうとすると、メモリはCPUによってキャッシュされる可能性があります: https://stackoverflow.com/questions/22701352/how-to- flush-the-cpu-cache-for-a-region-of-address-space-in-linux そして、それをフラッシュしたり、領域をキャッシュ不可としてマークしたりするための非常に移植性のある/簡単な方法はありません:

では、/dev/memを使用してメモリバッファをデバイスに確実に渡すことはできないのでしょうか。

QEMUはキャッシュをシミュレートしないため、残念ながらQEMUでこれを観察することはできません。

テストする方法

楽しい部分です。ここにいくつかのクールなセットアップがあります:

  • ユーザーランドメモリ
    • ユーザーランドプロセスにvolatile変数を割り当てます
    • /proc/<pid>/maps + /proc/<pid>/pagemapで物理アドレスを取得する
    • devmem2を含む物理アドレスと、ユーザーランドプロセスの反応を観察します。
  • カーネルランドメモリ
    • カーネルメモリをkmallocで割り当てます
    • virt_to_physで物理アドレスを取得し、ユーザーランドに返します
    • devmem2で物理アドレスを変更する
    • カーネルモジュールから値を問い合わせる
  • IOメモリとQEMU仮想プラットフォームデバイス
    • 既知の物理レジスタアドレスでプラットフォームデバイスを作成する
    • devmem2を使用してレジスタに書き込みます
    • printfsが応答として仮想デバイスから出てくるのを見る

/ dev/memは従来、物理アドレス空間全体へのアクセスを提供していました。これにはRAMが含まれますが、メモリがマップされたIOデバイスも含まれます。

最新のカーネルの多くは、 "CONFIG_STRICT_DEVMEM"を使用して構成されます。これにより、/ dev/memがメモリマップされたIOデバイスのみに制限されます。

ランダムなゴミを書き込むことは悪い考えですが、正確に何が起こるかを予測することは困難です。ハードウェアはランダムなガベージに対して予期しない方法で応答する可能性があり、カーネルメモリ構造が破損すると、カーネルが予期しない動作をする可能性があります。せいぜい、システムクラッシュが予想されますが、最悪の場合、データの破損やハードウェアのブリックさえも問題にはなりません。

追伸Sudoはリダイレクトではなくcatコマンドのみを送信するため、通常のユーザーとして実行した場合、コマンドは何も実行しないでください。

5
plugwash