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/mem
forのアドレス指定と異なりますかdevmem
?
答え1
部分的な答え:
devmem
busybox出身なら、/dev/memを使用値を読み書きできるのでしなければならない同じ結果を得ました。
つまり、単位はskip
ブロック(bs
バイト)なので、bs=16 count=1 skip=2149646336
0x80210000から読み取らずに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