devmemの代わりにdd if = / dev / memを使用する方法は?

devmemの代わりにdd if = / dev / memを使用する方法は?


root@testbox:~# dd if=/dev/mem bs=1 count=4 skip=2149646336 | hd
ほとんど似ている必要があるようです。
root@testbox:~# devmem 2149646336 32

しかし、devmemうまく機能しますが、呼び出しはddセグフォルトを引き起こします。他の多くのbs、skipの組み合わせ(この問題を解決しようとしている間に偶然見つかった)の場合、ddは正常に返されますが、予想されたものとはまったく異なるデータが返されます。これらすべては、私がddを使用するときに私が解決していると思う問題を実際に解決するわけではないことを示しています。たぶんメモリマッピングの問題ですか?私はハードウェアの専門家なので、物理アドレスのみを考慮します。

いくつかの詳細:

私はオンチップARM A53コアを備えたXilinx FPGAでLinuxが動作する組み込みシステムを構築しています。私はしばしばdevmemを使ってFPGAロジックからメモリマップされたレジスタを読み書きします。 devmemの代わりにddを使用して、1つのコマンドで長いアドレスのリストを読み取り、データをファイルに保存したり、別のプロセスにパイプしたいと思います。

私のFPGA設計には、読み書き可能でバイトアドレスにマッピングされた内部RAMブロックがあります0x80210000

次のようにシェルスクリプトを作成しました。

devmem 0x80210000 32 0x5AB000CD  
devmem 0x80210004 32 0x5AB001CD  
devmem 0x80210008 32 0x5AB002CD  
devmem 0x8021000C 32 0x5AB003CD  
... etc etc <250 more lines> ...  
devmem 0x802103F8 32 0x5AB0FECD  
devmem 0x802103FC 32 0x5AB0FFCD  

私のブロックRAMの最初のKBを見ることができる横説説でいっぱいです。シェルスクリプトを実行した後、devmemを使用してそのメモリから単語を読み取ることができます。

root@testbox:~# devmem 2149646336 32
0x5AB000CD
root@testbox:~# devmem 2149646340 32
0x5AB001CD
root@testbox:~# devmem 2149646344 32
0x5AB002CD
root@testbox:~# devmem 2149646348 32
0x5AB003CD

今まではそんなに良くなった。

注:
0x80210000 = 10進数2149646336
および
0x80210000 / 16 = 134352896 10進数

次に、以下を使用して同じ4ワードのメモリを読み込んでみましたdd

root@testbox:~# dd if=/dev/mem of=/tmp/junk1 bs=1 count=16 skip=2149646336
または
root@testbox:~# dd if=/dev/mem of=/tmp/junk1 bs=16 count=1 skip=134352896
そのようなもの。

これらの行の1つでも私にセグフォルトを与えるでしょう。私は私のメモリブロックを見つけるためにbs、スキップなどの他の多くの組み合わせを試しました。

dd他の「成功した」呼び出し。たとえば、

root@testbox:~# dd if=/dev/mem bs=16 count=1 skip=2149646336 | hd
1+0 records in
1+0 records out
16 bytes copied, 0.00032236 s, 49.6 kB/s
00000000  ff ff fd ba 85 ff 4c ce  ff ff bd df e4 d5 9d ed  |......L.........|
00000010

しかし、私はこのデータを認識しません。私のDRAMがどこにあるかを知っている人の記事を読んだようです。

forのアドレス指定がdd if=/dev/memforのアドレス指定と異なりますかdevmem

答え1

部分的な答え:

devmembusybox出身なら、/dev/memを使用値を読み書きできるのでしなければならない同じ結果を得ました。

つまり、単位はskipブロック(bsバイト)なので、bs=16 count=1 skip=21496463360x80210000から読み取らずに0x802100000から読み込み、0x02100000にラップすることができます。

スキップされたMSBは1なので、ソースコードやコンパイラのどこかに符号付き/符号なしの混乱がある場合でも問題が発生する可能性があります。

だから私がする最初のことはbs=16 skip=134352896/dev/memそれ働く

答え2

これは実際にシンボルエラーです(ビジボックス版の場合):

if (skip) {
    if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
        do {
            ssize_t n = safe_read(ifd, ibuf, ibs);
            if (n < 0)
                goto die_infile;
            if (n == 0)
                break;
        } while (--skip != 0);
    }
}

lseek()ファイルオフセット(2149646336)を負のint32数(-2145320960)に変換して返すため、ddエラーコードと見なされます。次に、基本検索を実装するために、ファイルから指定されたオフセットまですべてのバイトを読み込みます。これは、0からアドレスまでバスのすべてのバイトを読み取ることを意味し、これは問題だけを引き起こします。

dd戻り値が有効なエラーコード(-1から-4095の間)であることを確認することで問題を解決できますが、独自のCプログラムを書くことはbusyboxを再コンパイルするよりも速くなります。

ところで読書devmemには少し違います。mmap()/dev/mem

関連情報