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를 사용하여 하나의 명령으로 긴 주소 목록을 읽고 데이터를 파일에 저장하거나 다른 프로세스로 파이프하고 싶습니다.

내 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
그런 것.

이 라인 중 하나라도 나에게 세그폴트를 줄 것입니다. 나는 내 메모리 블록을 찾기 위해 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

관련 정보