私が理解したのは、ユーザー空間プログラムは非権利モードで実行されるため、メモリやI / Oに直接アクセスできないことです。
それでは、ユーザー空間プログラムで/dev/memをmmapするときに、どのようにメモリまたはI/Oの場所に直接アクセスできますか?
たとえば、
int fd = 0;
u8 leds = 0;
fd = open("/dev/mem", O_RDWR|O_SYNC);
leds = (u8 *)mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0x80840000);
これは組み込みデバイスで非常に一般的な技術です。
この変数をleds
すぐに使用して、0x80840000に存在できるすべてのデバイスにアクセスできるようになりました。
我々はもはやこのアドレスにアクセスするためにシステムコールを使用しません。
でも好き
leds[0x20] = val;
動作します。
ただし、I / Oアドレスからの直接読み取り/書き込みなどの特権操作は、システムコールを介してプロセッサを特権モードにすることによってのみ達成できます。
源泉。
答え1
権限のないプロセスへのアクセスを許可することは/dev/mem
実際にはセキュリティ上の問題であるため、許可しないでください。
私のシステムでは、ls -l /dev/mem
次のようになります。
crw-r----- 1 root kmem 1, 1 Sep 8 10:12 /dev/mem
したがってroot
、読んで書くことができ、kmem
グループメンバー(誰もいない)を読むことはできますが、書くことはできず、他の人はまったく開くことができません。だからこれは安全でなければなりません。
あなたの/dev/mem
ものが私のようなものであれば、あなたの権限を持たないプロセスは、ファイルはどこでも開けられないはずですmmap
。
システムの権限が安全である/dev/mem
ことを確認してください!
答え2
ルートとして実行するか、権限のないユーザーとして実行する場合でも、ユーザープロセスに表示されるアドレスは、ページテーブルを介してMMUによって物理アドレスにマッピングされる仮想アドレスです。ページテーブルの設定は特権操作であり、カーネルコードでのみ実行できます。ただし、ページテーブルが設定されると、ユーザーモードでメモリへのアクセスが許可されます。
具体的には、コードは、カーネルに特定のmmap
範囲の物理メモリへのアクセスを許可するようにページテーブルを設定するように要求するために使用されます。カーネルはプロセスの権限(読み取り/書き込みアクセス権を持つ/dev/mem
)を確認し、物理メモリにアクセスできるようにページテーブルを設定します。
答え3
値はleds
仮想アドレスです。現在のプロセスのユーザースペースにある限り、プロセスは仮想アドレスがleds[0] = val
RAM上のどの場所にマップされていても、特権モードにせずにコマンドを介して直接アクセスできます。