Ambos lados, revisión anterior
Revisión previa
Próxima revisión
|
Revisión previa
|
inicializacion_de_procesador_cortex-a8 [2023/04/25 19:56] cnigri exception set parte final |
inicializacion_de_procesador_cortex-a8 [2024/05/17 11:16] (actual) cnigri Correccion de descripcion |
|[[https://developer.arm.com/documentation/dui0417/d/hardware-description/northbridge?lang=en | Northbridge]]| 0x70000000-0x8FFFFFFF| [[https://developer.arm.com/documentation/dui0417/d/programmer-s-reference/dynamic-memory-controller--dmc?lang=en | Dinamic Memory Controller]]| 512MB | | |[[https://developer.arm.com/documentation/dui0417/d/hardware-description/northbridge?lang=en | Northbridge]]| 0x70000000-0x8FFFFFFF| [[https://developer.arm.com/documentation/dui0417/d/programmer-s-reference/dynamic-memory-controller--dmc?lang=en | Dinamic Memory Controller]]| 512MB | |
| |
De la tabla se desprende que la memoria RAM se direcciona en el rango 0x70000000-0x8FFFFFFF, y que la parte superior del mismo (256MB) se encuentra espejado en 0x00000000-0x0FFFFFFF. Sin embargo se debe recordar que al estar en la etapa //Inicialización del SoC//, el DMC no se encuentra configurado por lo que no es posible emplear dicha memoria y por ende cualquier rango asociado a la misma. | De la tabla se desprende que la memoria RAM se direcciona en el rango 0x70000000-0x8FFFFFFF, y que el rango de direcciones numéricamente inferiores del mismo (256MB) se encuentra espejado en 0x00000000-0x0FFFFFFF. Sin embargo se debe recordar que al estar en la etapa //Inicialización del SoC//, el DMC no se encuentra configurado por lo que no es posible emplear dicha memoria y por ende cualquier rango asociado a la misma. |
| |
Por su parte la ROM se direcciona en el rango 0x40000000- 0x5FFFFFFF y el controlador de este tipo de memorias no requiere inicialización, justamente para poder leer el código que permita satisfacer los requerimientos de la etapa //Inicialización del SoC//. Al parecer ya se encuentra resuelto el dilema sobre donde leer el código, pero al lector astuto seguramente le surgirá interrogante ¿Cómo puede ser esto posible, si la [[https://developer.arm.com/documentation/ddi0406/b/System-Level-Architecture/The-System-Level-Programmers--Model/Exceptions/Reset | Reset Vector Address]] es 0x00000000 o 0xFFFF0000?\\ | Por su parte la ROM se direcciona en el rango 0x40000000- 0x5FFFFFFF y el controlador de este tipo de memorias no requiere inicialización, justamente para poder leer el código que permita satisfacer los requerimientos de la etapa //Inicialización del SoC//. Al parecer ya se encuentra resuelto el dilema sobre donde leer el código, pero al lector astuto seguramente le surgirá interrogante ¿Cómo puede ser esto posible, si la [[https://developer.arm.com/documentation/ddi0406/b/System-Level-Architecture/The-System-Level-Programmers--Model/Exceptions/Reset | Reset Vector Address]] es 0x00000000 o 0xFFFF0000?\\ |
Para resolver esta duda perfectamente válida apelamos a la //"magia"// del [[https://developer.arm.com/documentation/dui0417/d/hardware-description/northbridge?lang=en | Northbridge]], este ASIC específico de esta placa se encarga de [[https://developer.arm.com/documentation/dui0417/d/programmer-s-reference/configuration-and-initialization/remapping-of-boot-memory?lang=en | remapear]] la NOR de 0x40000000- 0x40FFFFFF a 0x00000000-0x00FFFFFF. Si bien esto ya brinda cierta claridad sobre donde debe situarse el código, es importante observar que el rango remapeado es tan solo de 16MB, frente a los 512MB disponibles en el mapa de memoria, esto significa que si bien la placa puede disponer de una NOR de hasta 512MB el código de arranque en la misma solo puede estar alojado en los primeros 16MB, quedando el restante espacio para disponible para el código complementario. Esto es importante tenerlo presente al momento de generar el mapa de memoria del código por lo general mediante el [[guiasupervivenciald|linker script]] | Para resolver esta duda perfectamente válida apelamos a la //"magia"// del [[https://developer.arm.com/documentation/dui0417/d/hardware-description/northbridge?lang=en | Northbridge]], este ASIC específico de esta placa se encarga de [[https://developer.arm.com/documentation/dui0417/d/programmer-s-reference/configuration-and-initialization/remapping-of-boot-memory?lang=en | remapear]] la NOR de 0x40000000- 0x40FFFFFF a 0x00000000-0x00FFFFFF. Si bien esto ya brinda cierta claridad sobre donde debe situarse el código, es importante observar que el rango remapeado es tan solo de 16MB, frente a los 512MB disponibles en el mapa de memoria, esto significa que si bien la placa puede disponer de una NOR de hasta 512MB el código de arranque en la misma solo puede estar alojado en los primeros 16MB, quedando el restante espacio para disponible para el código complementario. Esto es importante tenerlo presente al momento de generar el mapa de memoria del código por lo general mediante el [[guiasupervivenciald_arm|linker script]] |
| |
| |
| |
La primer acción que se debe realizar es garantizar que el procesador se encuentra en el modo y privilegio de operación que permita el acceso a los recursos del mismo.\\ | La primer acción que se debe realizar es garantizar que el procesador se encuentra en el modo y privilegio de operación que permita el acceso a los recursos del mismo.\\ |
En ARMv7 este modo se denomina //Supervisor// normalmente se referencia como //svc//. Si bien por [[https://developer.arm.com/documentation/ddi0406/c/System-Level-Architecture/The-System-Level-Programmers--Model/Exception-descriptions/Reset | manual se especifica]] que este es el modo que el procesador arranca luego de un reinicio, se debe asegurarlo, para lo cual se emplean los 5 bits menos significativos del [[https://developer.arm.com/documentation/ddi0601/2022-12/AArch32-Registers/CPSR--Current-Program-Status-Register?lang=en | Current Program Status Register]], denominados campo de modo (CPSR.M -> CPSR[4:0]). | En ARMv7 este modo se denomina //Supervisor// normalmente se referencia como //svc//. Si bien por [[https://developer.arm.com/documentation/ddi0406/c/System-Level-Architecture/The-System-Level-Programmers--Model/Exception-descriptions/Reset | manual se especifica]] que este es el modo en el que el procesador arranca luego de un reinicio, se debe asegurarlo, para lo cual se emplean los 5 bits menos significativos del [[https://developer.arm.com/documentation/ddi0601/2022-12/AArch32-Registers/CPSR--Current-Program-Status-Register?lang=en | Current Program Status Register]], denominados campo de modo (CPSR.M -> CPSR[4:0]). |
Dado que el estado del SoC y sobre todo de los periféricos de la placa no es conocido, se debe evitar que algún estimulo externo perturbe la secuencia de inicialización, es decir se deben deshabilitar las interrupciones, que en el caso de ARMv7 son IRQ y FIQ.\ | Dado que el estado del SoC y sobre todo de los periféricos de la placa no es conocido, se debe evitar que algún estimulo externo perturbe la secuencia de inicialización, es decir se deben deshabilitar las interrupciones, que en el caso de ARMv7 son IRQ y FIQ.\ |
En el caso de ARMv7 la deshabilitación de las interrupciones se realiza con el mismo registro (CPSR.I -> CPSR[7], CPSR.F -> CPSR[6]) que se emplea para configurar el modo de operación por lo cual en un paso se realizan dos subetapas | En el caso de ARMv7 la deshabilitación de las interrupciones se realiza con el mismo registro (CPSR.I -> CPSR[7], CPSR.F -> CPSR[6]) que se emplea para configurar el modo de operación por lo cual en un paso se realizan dos subetapas |
mov pc, lr | mov pc, lr |
</code> | </code> |
| Empleando [[https://keleshev.com/ldm-my-favorite-arm-instruction/ | loadmultiple]] y [[https://azeria-labs.com/load-and-store-multiple-part-5/ | storemultiple]] |
<code asm> | <code asm> |
ldr r0, _direccion_origen | ldr r0, _direccion_origen |
bl mem_cpy | bl mem_cpy |
| |
@ Opcion B con incremento de a 7 double word veces (r3 a r10 | @ Opcion B con incremento de a 8 double word veces (r3 a r10 |
mem_cpy: | mem_cpy: |
add r2, r2, r0 | add r2, r2, r0 |
stack_setup: | stack_setup: |
ldr r0, #CONFIG_PILA_LIMITE_DIRECCION | ldr r0, #CONFIG_PILA_LIMITE_DIRECCION |
sub r0, r0, #(CONFIG_PILA_IRQ_LARGO + CONFIG_PILA_FIQ_LARGO) | sub r0, r0, #(CONFIG_PILA_SVC_LARGO + CONFIG_PILA_IRQ_LARGO + CONFIG_PILA_FIQ_LARGO) |
sub sp, r0, #12 @ 3 words para abort-stack | sub sp, r0, #12 @ 3 words para abort-stack |
bic sp, sp, #7 @ 8-byte ajuste para satisfacer alineacion requerida por ABI | bic sp, sp, #7 @ 8-byte ajuste para satisfacer alineacion requerida por ABI |
| |
<code asm> | <code asm> |
ldr r0, #(CONFIG_PILA_LIMITE_DIRECCION - CONFIG_PILA_IRQ_LARGO - CONFIG_PILA_FIQ_LARGO - 12) | ldr r0, #(CONFIG_PILA_LIMITE_DIRECCION - CONFIG_PILA_SVC_LARGO - CONFIG_PILA_IRQ_LARGO - CONFIG_PILA_FIQ_LARGO - 12) |
bl stack_validate | bl stack_validate |
| |
stack_validate: | stack_validate: |
ldr r2, 0xA5A5A5A5 | ldr r2, =0xA5A5A5A5 |
ldr r3, 0xA5A5A5A5 | ldr r3, =0xA5A5A5A5 |
ldr r4, 0xA5A5A5A5 | ldr r4, =0xA5A5A5A5 |
ldr r5, 0xA5A5A5A5 | ldr r5, =0xA5A5A5A5 |
ldr r6, 0xA5A5A5A5 | ldr r6, =0xA5A5A5A5 |
ldr r7, 0xA5A5A5A5 | ldr r7, =0xA5A5A5A5 |
ldr r8, 0xA5A5A5A5 | ldr r8, =0xA5A5A5A5 |
ldr r9, 0xA5A5A5A5 | ldr r9, =0xA5A5A5A5 |
ldr r10, 0xA5A5A5A5 | ldr r10, =0xA5A5A5A5 |
stack_write_fast: | stack_write_fast: |
sub r1, sp, #(CONFIG_PILA_LIMITE_DIRECCION - 36) | sub r1, sp, #(CONFIG_PILA_LIMITE_DIRECCION - 36) |
* **ldr pc**: bifurfaciones sin restricciones de rango por fuera de la propia arquitectura | * **ldr pc**: bifurfaciones sin restricciones de rango por fuera de la propia arquitectura |
<code asm> | <code asm> |
.globl _start_generic | .global _start_generic |
_start:_generic: @ Etiqueta para referencia punto de entrada y tabla | _start_generic: @ Etiqueta para referencia punto de entrada y tabla |
b reset @ Configuracion de modo y deshabilitacion de interrupciones | b reset @ Configuracion de modo y deshabilitacion de interrupciones |
ldr pc, _undefined_instruction | ldr pc, _undefined_instruction |
</code> | </code> |
| |
--- //[[cnigri@frba.utn.edu.ar|ChristiaN]] 2023/04/25 19:55// | --- //[[cnigri@frba.utn.edu.ar|ChristiaN]] 2024/05/17 11:17// |
| |
| |