¿Por qué las palabras están en orden inverso cuando se leen desde un flash?

0

Descargué el contenido de un chip flash NAND, y no entiendo por qué cada una de las palabras en la imagen está en orden inverso. Este flash compatible con CFI está conectado a un SoC TI AR7 que integra un núcleo MIPS 4K.

Estoy descargando el flash usando OpenOCD conectado al puerto EJTAG de la placa. He hecho esto antes con tableros muy similares con AR7 y nunca he visto esto.

Solo para aclarar, no estoy hablando de endianness, cada secuencia de 4 bytes parece estar invertida, incluidas las cadenas, es decir: 'CTAWGODHRAW GNIN' en lugar de 'WATCHDOG WARNING' . ( '0123' se convierte en '3210' )

¿Hay razones para invertir los datos de esta manera? ¿Cómo puede el procesador arrancar desde estos datos si el flash, para lectura, se asigna en una dirección?

    
pregunta istepaniuk

3 respuestas

2

Respuesta corta:

Está utilizando OpenOCD en modo LE cuando su CPU se ejecuta en BE (o viceversa).

Debe especificar el cambio -endian correcto para el comando target en su configuración de OpenOCD.

Respuesta más larga:

¿Dónde está el desajuste de endianness?

Independientemente de la endianidad, los datos se leen de la memoria flash one chip_bus_width bit a la vez, en este caso 16bits. El orden y el ancho (aparentemente 32) en el que los nibbles se envían en serie a través del bus JTAG depende de la capacidad de la CPU y OpenOCD no tiene forma (sin interferencia) de adivinar esto si la CPU en particular puede ejecutarse cualquiera de los modos (como pueden hacerlo los núcleos MIPS o ARM).

Es la propia CPU la que realiza la operación de lectura real, ordenada por el controlador TAP. Este no sería el caso si se pinchara el flash utilizando el escaneo de límites.

Para ambos comandos mdw o dump_image OpenOCD, sus 4 bytes se revertirán si su OpenOCD tiene una configuración de endianness no coincidente ( -endian ).

Endianness y secuencias de bytes, o cadenas

Como se indica en algunos comentarios, las cadenas C y los arreglos de bytes siempre aparecerán en orden al inspeccionar la memoria en incrementos de 1 por 1, y por lo tanto deberían aparecer en orden si volcamos esa memoria en un archivo. Eso es parte del estándar ANSI C, y está escrito en piedra por el funcionamiento de la aritmética de punteros:

  

Cuando una expresión que tiene un tipo integral se agrega o se resta de un puntero, el resultado tiene el tipo del operando del puntero. Si el operando puntero apunta a un elemento de un objeto de matriz, y la matriz es lo suficientemente grande, el resultado apunta a un elemento desplazado con respecto al elemento original, de modo que la diferencia de los subíndices de los elementos de la matriz resultante y original sea igual a la expresión integral.

Al aumentar la dirección en uno , siempre obtenemos el siguiente byte en secuencia (o char en una cadena), independientemente de la endianidad. No se puede decir más claramente: El endianismo NO afecta la forma en que se almacenan las cadenas de estilo C .

Volcado hexadecimal en la dirección 0x000000e0 de printf("Hello, world!"); :

Código de objeto C, compilado para big endian ( mips-gcc -EB ): 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 00 00 00 |Hello, world!...|

Código de objeto C, compilado para little endian ( mips-gcc -EL ): 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 00 00 00 |Hello, world!...|

Los enteros (y los números más grandes), por otro lado, se almacenan en el orden de bytes del endianness en particular, y examinan un número entero en la RAM o en el flash (o en un archivo de volcado, etc.) byte a byte, producirá diferentes secuencias para BE o LE, muy poco relacionadas con el problema real.

    
respondido por el istepaniuk
2

Es un problema endiano. La memoria está funcionando bien. Simplemente tiene que ver con que el software lea las palabras de 32 bits y la asignación de los caracteres individuales (bytes individuales) a su posición en la palabra de 32 bits.

Pude predecir el resultado y comparar lo que predije con lo que realmente se leyó.

Una palabra de 32 bits almacena 4 bytes = 4 caracteres ASCII únicos.

Tomemos una parte del texto original: WATCHDOG

Toma los primeros 4 caracteres de izquierda a derecha: WATC Esos 4 se pueden almacenar en una palabra de 32 bits. Los siguientes 4 se pueden almacenar en una palabra de 32 bits: HDOG

Invertir el orden de cada grupo:   CTAW   DIOS

Texto de salida: CTAW GODH Que luego coincide con la secuencia de letras que realmente salen.

Ahora, la pregunta es ¿cómo está organizada la memoria flash, como bytes o palabras de 32 bits? ¿Y qué lee el procesador? ¿Lee bytes y lee 4 de ellos? ¿O lee 32 bits en una sola operación?

Si está escribiendo código para manipular cadenas de texto, necesita saber exactamente cómo se almacenan y cómo las lee el procesador.

Produce una tabla como esta:

MemoryAddress ...... Posición del carácter en la cadena

n ......... 4

n + 1 ......... 3

n + 2 ......... 2

n + 3 ......... 1

n + 4 ......... 4

n + 5 ......... 3

...

En los viejos tiempos de los microprocesadores de 8 bits y la memoria de 8 bits de ancho, estos problemas no existían. Sin duda, es algo que debe entenderse cuando se trata de procesadores de 16 bits o más y donde la memoria se organiza en anchos de más de 8 bits.

    
respondido por el Dean
1

De hecho, esto parece ser un problema de endianidad. Desafortunadamente esa palabra (endian) se usa mucho y crea una confusión innecesaria, miedo, etc.

Para que esto funcione, en algún lugar debe haber un intercambio de bytes y es probable que exista, si de hecho, este chip funciona. Y en ese caso, cambiaría todo suponiendo que el flash está en esa capa a la que se accede solo en cantidades de 32 bits. (podría ser fácilmente que el dispositivo periférico acceda a los 8 bits del flash a la vez, siempre haga lecturas de 32 bits y la forma en que se desplaza hace un intercambio de endian cuando pasa los datos al bus de los procesadores).

Por lo tanto, debe intentar hacer lecturas simples desde el lado del procesador, no jtag para ver lo que ve, si aún se intercambia, es un misterio cómo funciona esto. Debería haber hardware o software intercambiando todo antes de usar / ejecutar.

    
respondido por el old_timer

Lea otras preguntas en las etiquetas