busybox devmemコマンドを使用してレジスタを読み書きしようとしています。ソースコードからドライバのベースアドレスを印刷し、次のアドレスを受け取りました:0xffffff800bdd0000
このアドレスは仮想カーネルアドレスであるとします。 busybox devmemを使用できるように、これを物理アドレスに変換するにはどうすればよいですか?プログラミングなしで端末で実行しようとしています。
答え1
これタイトル/dev/kmem
あなたの質問に対する答えは次のとおりです。デバイスノードを読み書きする。 (*1)
しかし...あなたの質問を読んでみてください...これはあなたが探しているものではないようです。
私はあなたがデバイスの特定のレジスタを読み書きしたいと思うことを知っています。
どのハードウェアデバイス(RAMを含む)が特定のバスを介してCPUと通信しているかにかかわらず、デバイスI / Oレジスタの物理アドレスはデバイスが使用するバスにのみ関連します。
つまり、これらのアドレスにアクセスするには厳密で具体的なプロトコルに従う必要があり、他の読み取り/書き込みコマンドも必要になる可能性があります。
幸いなことに、LinuxはすべてのバスとデバイスからIOを抽象化する方法を提供します。メモリマップされたIO。統合(ramおよびio)アドレス空間にアクセスするためのデバイスノード:/dev/メモリ(*2)
何かをする前に最初にすべきことノードが存在することを確認してください。あなたのシステムから。明らかなセキュリティ上の理由から、多くのディストリビューションではこれを有効にしないか、またはアクセスを制限します。したがって、kernel.configファイルを確認して、CONFIG_DEVMEMが設定されており、CONFIG_STRICT_DEVMEMが設定されていないことを確認してください。
そうでない場合は、好みのツールを使用してそれに応じてカーネル構成を調整し、カーネルを再構築します。
もしそうなら、今知っておくべきことレジスタが再マップされるアドレス:
OPが主張するのとは異なり、ドライバのソースコードを読むことを知ってはいけません。これは、デバイスが独立した方法でベースアドレスに論理的に書き込まれるためです。
このコードで実際に理解できるのは、関心のあるレジスタの相対アドレスです。ベースアドレスに基づくそのアドレスのオフセット。記録してください(またはデバイスの仕様で確認してください)。
Linux(成功した場合)がデバイスに関連するIOスペースを再マップするベースアドレスをファイル/proc/iomem
に報告する必要があります。 (*サム)
レジスタ再マッピングアドレスを取得するには、2つ(デフォルトアドレスとオフセット)を追加します。
これで、/dev/memデバイスノードを使用する必要があります。これはとても簡単だからです。使用するのは本当に賢いです。ビジーボックスデバイスメモリ。 (*4)
読みながら使用してください:devmem ADDRESS [WIDTH [VALUE]]
WIDTHパラメータ処理(ビット単位のレジスタサイズ)
1: または多分いつも回答を受けてからリヌス・トバルズ(Linus Torvalds)はそれから抜け出したいと思っています。
2:x86_64アーキテクチャでは、Linuxはデバイスを処理する別の方法(/proc/ioportsからポートアドレスを報告し、/dev/port経由でアクセス)を提供しますが、これはarmを使用するARMアーキテクチャとOPには適用されません。ここで説明した唯一の方法であるIO再マッピングのため、レジスタにアクセスできません。
3:一部のデバイスでは、メモリ再マッピング範囲を複数の場所に分割することがあります。レジスタ参照のベースアドレスを理解するには、仕様(またはドライバコード)を読んでください。
4:太っているという警告:devmemなどの中間ツールを使用しても、不適切な使用により/dev/mem
システムが損傷する可能性があります。