Como usar o dd if = / dev / mem no lugar do devmem?

2

Parece que root@testbox:~# dd if=/dev/mem bs=1 count=4 skip=2149646336 | hd
deve ser quase equivalente a root@testbox:~# devmem 2149646336 32

Mas, enquanto devmem funciona muito bem, essa dd invocação me dá um segfault. Para muitos outros bs, pule combinações (encontradas acidentalmente durante minha tentativa de descobrir isso) dd retorna com sucesso, mas os dados não são nada como o que estou esperando. Tudo isso sugere que não estou realmente abordando onde acho que estou falando, quando uso o dd. Algum problema de mapeamento de memória, talvez? Eu sou um cara de hardware, então eu só penso em endereços físicos.

Alguns detalhes:

Estou construindo um sistema embarcado com o linux rodando em um FPGA da Xilinx com núcleos ARM A53 no chip. Eu uso rotineiramente o devmem para ler ou gravar registros mapeados na memória na minha lógica FPGA. Eu gostaria de usar o dd em vez de devmem para ler um longo bloco de endereços com um comando e salvar os dados em um arquivo ou canalizá-los para outro processo.

Meu projeto de FPGA tem um bloco de RAM interno, leitura-gravável, mapeado para o endereço de byte 0x80210000 .

Eu escrevi um script de shell assim:

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  

Ele preenche o primeiro kbyte do meu bloco de memória RAM com algum conteúdo reconhecível. Depois de executar esse script de shell, posso usar o devmem para ler palavras dessa memória.

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

Até aí tudo bem.

Note que:
0x80210000 = 2149646336 decimal
e
0x80210000 / 16 = 134352896 decimal

Em seguida, tento ler as mesmas 4 palavras de memória usando dd :

root@testbox:~# dd if=/dev/mem of=/tmp/junk1 bs=1 count=16 skip=2149646336
ou root@testbox:~# dd if=/dev/mem of=/tmp/junk1 bs=16 count=1 skip=134352896
ou algo parecido.

Qualquer uma dessas linhas me dá um segfault. Eu tentei muitas outras combinações de bs, pular, etc, tentando encontrar meu bloco de memória.

Outras invocações de dd "são bem-sucedidas". por exemplo. :

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

mas não reconheço esses dados. Eu acho que só estou lendo quem sabe onde na minha DRAM.

O endereçamento para dd if=/dev/mem é diferente de devmem ?

    
por Gaylon 25.08.2018 / 03:52

1 resposta

0

Resposta parcial:

Se o seu devmem for do busybox, ele usa / dev / mem para ler e escreva valores, então você deve obter os mesmos resultados.

Dito isso, observe que a unidade de skip é blocos ( bs bytes), portanto, bs=16 count=1 skip=2149646336 não leu em 0x80210000, mas em 0x802100000, o que provavelmente significa 0x02100000.

Como o MSB dos seus skips é um, se houver uma confusão assinada / não assinada em algum lugar na fonte e / ou no compilador, isso também pode estragar as coisas.

Então, a primeira coisa que eu faria seria testar a leitura em 0x80210000 usando algo como bs=16 skip=134352896 . Se isso ainda falhar, a segunda coisa que faço é escrever um pequeno programa em C que leia diretamente /dev/mem e verifique se isso funciona.

    
por 25.08.2018 / 14:39