Secuencia de arranque Arco de Harvard. Arco Vs Von Neumenn.

De https://electronics.stackexchange.com/a/224160/150597 es necesario que el código y los datos se carguen en la RAM antes de la ejecución para la arquitectura Von neumenn. Mientras que en el arco de Harward. ¿el código se puede ejecutar desde la ROM y los datos se pueden cargar desde la RAM?

¿Qué pasa si solo los autobuses se basan en harvard archi? (ARM) y el espacio de direcciones aún está unificado (similar a von neumenn excepto los buses)? En von neumenn, ¿no podemos ejecutar código desde el espacio ROM?

La respuesta corta es sí, para la arquitectura de Von Neumann con un espacio de direcciones unificado, la RAM y cualquier ROM aparecen en diferentes direcciones y el código se puede ejecutar desde la ROM. Tenga en cuenta que, a veces, la ROM es mucho más lenta que la DRAM, por lo que el cargador de arranque puede copiar el código a la RAM al principio de su ejecución.
@ pjc50 sé que RAM RoM aparecerá en diferentes direcciones en el mapa de memoria unificado. Mi pregunta es si tanto el código como los datos deben cargarse en la RAM en el arco von-neumenn. como se menciona en el enlace de respuesta mencionado en mi pregunta? Simplificando más la pregunta, explique amablemente la respuesta cuyo enlace se proporciona en la pregunta.
En Von Neumann puede ejecutar código desde el espacio ROM sin cargarlo en la RAM.
Estimado @pjc50, Y en arquitectura harvard??
En harvard "puro" no se puede, el código y los datos están completamente separados. No hay muchos de estos, PIC es el que realmente podría encontrar.
Puede que le resulte útil mirar los dispositivos reales que usan Cortex-M0 y Cortex-M3. Puede encontrar que estos se ven diferentes a lo que espera.

Respuestas (1)

Guau. ¡En realidad no leí todo ese intercambio de EESE! Demasiado para tener que procesar aparte de concentrarse en lo poco que pediste. Así que me centraré en eso.

En las arquitecturas de von Neumann, en términos generales, un programa tiene la siguiente apariencia:

        Section Description     Access          Non-Volatile     Size
        -----------------------------------------------------------------------
        Code                    Execute              Yes         Fixed/static
        Constants               Read                 Yes         Fixed/static
        Initialized Data        Read/Write           Yes         Fixed/static
        Uninitialized Data      Read/Write           No          Fixed/static
        Heap                    Read/Write           No          Variable, up
        Stack                   Read/Write           No          Variable, down

La sección de código puede ser de solo ejecución, como ocurre a menudo con la familia x86. Pero (obviamente) el sistema operativo debe escribirlo, de alguna manera, antes de iniciar el programa. Si se trata de un objetivo integrado e independiente sin un sistema operativo involucrado, generalmente se almacena en la memoria no volátil o se obtiene de la memoria no volátil secundaria (que a menudo se hace sin ningún software adicional utilizando el integrado). en el cargador de arranque ROM que se encuentra en el DSP ADSP-21xx de Analog Devices). Durante la ejecución, puede ser no volátil (si no hay necesidad de modificarlo en tiempo de ejecución) o puede ser volátil (si se requieren modificaciones, como lo que puede suceder con el enlace tardío ).

Como puede ver, es posible que un compilador organice todo el código , las constantes y los datos inicializados para residir en alguna parte de la memoria no volátil. Sin embargo, no es necesario almacenar ninguna de las últimas tres secciones mencionadas en la tabla anterior en la memoria no volátil.

La tabla anterior es casi correcta. Sin embargo, tenga en cuenta que la sección de datos inicializados requiere acceso de lectura y escritura. Dado que casi toda la memoria no volátil no se puede escribir fácilmente, a excepción de FeRAM (o FRAM), casi siempre se almacena en la RAM que se transfiere del almacenamiento no volátil (primario o secundario) a la RAM justo antes de iniciar el código (aparte del código de inicio que normalmente no ve ni escribe). Esto significa que la tabla anterior probablemente debería ser:

        Section Description     Access          Non-Volatile     Size
        -----------------------------------------------------------------------
        Code                    Execute              Yes         Fixed/static
        Constants               Read                 Yes         Fixed/static
        Initialized Data Copy   Read                 Yes         Fixed/static
        Initialized Data        Read/Write           No          Fixed/static
        Uninitialized Data      Read/Write           No          Fixed/static
        Heap                    Read/Write           No          Variable, up
        Stack                   Read/Write           No          Variable, down

La tabla anterior ahora destaca el hecho de que la sección de datos inicializados debe residir en dos lugares: memoria no volátil (como flash) y memoria volátil (SRAM) y que debe haber un código de inicio que transfiera datos desde el sección de copia de datos a la sección de datos inicializados . Pero recuerde que algunos procesadores, como ciertos MSP430 que están construidos con FRAM, pueden mantener los datos inicializados en su memoria no volátil. Así que cualquiera de las tablas podría ser correcta.


La sección del montón no es estática en tiempo de ejecución. Normalmente, esta sección se configura con un tamaño cero para comenzar y luego crece y se reduce durante la ejecución. Esta es el área utilizada por rutinas como malloc(), por ejemplo. Un diseño simple para el montón lo hace crecer hacia arriba y lejos de la última ubicación de memoria requerida por todas las áreas de datos estáticos y hacia la pila.

La sección de pila tampoco es estática en tiempo de ejecución. Normalmente, esta sección también comienza con un tamaño cero y crece y se reduce durante la ejecución. Esto suele ser donde residen los parámetros de función y las variables "automáticas" locales. El compilador de C también lo utiliza para el almacenamiento temporal, el derrame de registros, etc. Y, por lo general, crece hacia abajo y se aleja de la última ubicación de memoria posible para el programa y hacia el extremo creciente de la sección del montón. De esta manera, hay un área única e invisible de memoria de lectura y escritura, una "tierra de nadie", por así decirlo, entre el montón y la pila, en la que cada sección "se convierte" como una vela encendida en ambos extremos. Si, durante la ejecución, el montón crece en la pila (o viceversa), es probable que el programa no funcione correctamente.


En las arquitecturas de Harvard, existen al menos dos sistemas de memoria diferentes: uno para el acceso al código y otro para el acceso a los datos. Por lo general, existen instrucciones especializadas que permiten leer desde el sistema de memoria de código, tratándolo como datos. Aquí, los detalles se vuelven un poco más complejos que los anteriores.

Cuando se inicia el sistema, el código, las constantes y los datos inicializados deben estar disponibles. Dado que están involucrados diferentes sistemas de memoria, y dado que se debe acceder a todos los datos a través del sistema de memoria de datos, el código de inicio generalmente copia los valores requeridos para la sección de datos inicializados y para la sección de constantes en la SRAM de datos, donde puede tratarse como normal. datos.

Entonces, la tabla de Harvard podría verse así:

        Section Description     Access          Non-Volatile     Size
        -----------------------------------------------------------------------
        Code                    Execute              Yes         Fixed/static
        Constants Copy          Read                 Yes         Fixed/static
        Initialized Data Copy   Read                 Yes         Fixed/static
        Constants               Read/Write           No          Fixed/static
        Initialized Data        Read/Write           No          Fixed/static
        Uninitialized Data      Read/Write           No          Fixed/static
        Heap                    Read/Write           No          Variable, up
        Stack                   Read/Write           No          Variable, down

Aquí, el código de inicio debe transferir la sección de copia de constantes a la sección de constantes y luego también transferir la sección de copia de datos inicializados a la sección de datos inicializados , antes de permitir que el programa continúe.


Para responder directamente a su pregunta sobre poder ejecutar código directamente desde ROM con von Neumann, puede. De hecho, a menudo se hace de esa manera. Simplemente graba el código en flash. Eso funciona para ambos tipos, muy bien.

(Y el multiprocesamiento y los subprocesos complican aún más las tablas anteriores).

gracias, muy bien explicaste el diseño de la memoria, pero esa buena explicación no eliminó mis dudas. Todavía estoy confundido, ¿DEBEMOS mantener tanto el código como los datos en una memoria en el arco de von Neumenn ya que hay un bus? "Sí, podemos" parece ser una especie de excepción. La pregunta es ¿tenemos que hacerlo? En palabras simples, ¿existe alguna diferencia en el proceso de arranque de los arcos harvard y von-neumenn?
La palabra "Excepción" en el comentario anterior puede considerarse o leerse como "Posibilidad".
@Aimal No entiendo tu confusión. Tu escritura es difícil para mí de analizar. von Neumann es, por definición, una sola dirección y, por lo tanto, un solo bus. No hay conflicto en mezclar varios tipos de memoria en un solo bus.
@ pjc50 quizás da una pista: en el arranque, en la arquitectura pura de Harvard, no puede combinar código y datos, siempre están en espacios de memoria separados. Y en von neumenn se puede combinar en un solo espacio de memoria a través de un gestor de arranque como lo hacemos durante la depuración... es decir, cargamos todo en la memoria RAM ya que cambiamos el código con frecuencia y lo cargamos una y otra vez.
@Aimal Creo que mencioné explícitamente los diferentes espacios de memoria. Acabo de resaltar (en negrita) el lugar donde lo señalé. Debido a que puede haber dos (o más) buses de direcciones en Harvard, debe haber instrucciones especiales o hardware de mapeo de memoria complejo (la memoria segmentada, como en Multics/x86, podría ser un ejemplo si luego se mapeara en múltiples espacios de direcciones) para desviar una solicitud al bus apropiado.
Gracias @jonk, ya marqué tu respuesta como "RESPONDIDA".