Основной вопрос относительно исполняемого файла на основе ROM - PullRequest
7 голосов
/ 05 июля 2010

У меня есть базовые сомнения относительно исполняемого файла, хранящегося в ПЗУ.

Как я знаю, исполняемый файл с атрибутами text и RO хранится в ПЗУ. Вопрос в том, что ПЗУ предназначено только для постоянной памяти, что будет, если возникнет ситуация, когда код должен быть записан в память?

Я не могу придумать ни одного примера для цитирования здесь (возможно, я не знаю такой ситуации или упускаю основные вещи;), но любой свет на эту тему может сильно помочь мне понять! :)

Последний выход - 1. Есть ли такая ситуация? 2. В таком случае является ли копирование кода из ПЗУ в ОЗУ ответом?

Ответ с некоторым примером может очень помочь ..

Большое спасибо заранее!

/ МС

Ответы [ 4 ]

8 голосов
/ 05 июля 2010

Память только для чтения доступна только для чтения из-за аппаратных ограничений.Программа может находиться в EEPROM , во флэш-памяти, защищенной от записи, на компакт-диске или в любом другом месте, где оборудование физически запрещает запись.Если программное обеспечение выполняет запись в ПЗУ, аппаратное обеспечение не может изменить сохраненные данные, поэтому ничего не происходит.

Так что, если программа из ПЗУ хочет записать в память, она записывает в RAM .Это единственный вариант.Если программа запускается из ПЗУ и хочет изменить себя , она не может этого сделать, потому что не может записать в ПЗУ.Но да, программа может работать из ОЗУ.

На самом деле, запуск из ПЗУ встречается редко, за исключением самых маленьких встроенных систем.Операционные системы перед запуском копируют исполняемый код из ПЗУ в ОЗУ.Иногда код сжимается в ПЗУ и должен быть распакован в ОЗУ перед запуском.Если ОЗУ заполнено, операционная система использует для управления paging .Причина, по которой запуск из ПЗУ настолько редок, состоит в том, что ПЗУ медленнее ОЗУ, и иногда загрузчик должен изменить код перед запуском.

Обратите внимание, что если у вас есть код, который изменяет сам себя,Вы действительно должны знать свою систему.Многие системы используют предотвращение выполнения данных (DEP).Исполняемый код идет в области чтения + выполнения оперативной памяти.Данные идут в области чтения + записи.Поэтому в этих системах код никогда не может измениться в оперативной памяти.

3 голосов
/ 05 июля 2010

Существует несколько законных причин, по которым вы захотите изменить раздел кода во время выполнения.Сам компилятор не будет генерировать код, который требует этого.

У вашего компоновщика будет возможность генерировать файл MAP.Это скажет вам, где находятся все объекты памяти.

Компоновщик выбирает место для размещения на основе сценария компоновщика (который можно настроить для организации памяти в соответствии с вашими потребностями).Обычно на микроконтроллере на основе FLASH код и постоянные данные помещаются в ПЗУ.В ПЗУ также помещены данные инициализации для ненулевых инициализированных статических данных, которые копируются в ОЗУ перед вызовом main ().Инициализированные нулем статические данные просто очищаются до нуля перед main ().

Можно организовать компоновщик, чтобы он находил часть или весь код в ПЗУ и имел код запуска, запускаемый при копировании.в ОЗУ таким же образом, как и ненулевые статические данные, но код должен быть либо перемещаемым, либо располагаться в ОЗУ в первом случае, обычно вы не можете просто скопировать код, предназначенный для запуска из ПЗУ, в ОЗУ и ожидать, что он будет выполняться св нем могут быть ссылки на абсолютные адреса (если, возможно, ваша цель не имеет MMU и не может переназначить адресное пространство).Размещение в ОЗУ на микроконтроллерах обычно выполняется для увеличения скорости выполнения, поскольку ОЗУ обычно быстрее, чем FLASH, когда используются высокие тактовые частоты, создавая меньшее или нулевое состояние ожидания.Он также может использоваться, когда код загружается во время выполнения из файловой системы, а не хранится в ПЗУ.Даже при загрузке в ОЗУ, если процессор имеет MMU, вполне вероятно, что раздел кода в разделе ОЗУ будет помечен только для чтения.

3 голосов
/ 05 июля 2010

Обычно в ПЗУ хранятся только программный код, константы и данные инициализации. Отдельная область памяти в ОЗУ используется для стека, кучи и т. Д.

1 голос
/ 13 июля 2010

микроконтроллеры Гарвардской архитектуры

Многие небольшие микроконтроллеры (Microchip PIC, Atmel AVR, Intel 8051, Cypress PSoC и т. Д.) Имеют гарвардскую архитектуру. Они могут выполнять код только из памяти программы (флэш-память или ПЗУ). Можно скопировать любой байт из памяти программы в оперативную память. Однако (2) копирование исполняемых инструкций из ПЗУ в ОЗУ не является ответом - с этими небольшими микроконтроллерами счетчик программ всегда ссылается на некоторый адрес в памяти программ. Невозможно выполнить код в оперативной памяти.

Копирование данных из ПЗУ в ОЗУ встречается довольно часто. При первом включении питания типичное встроенное программное обеспечение обнуляет всю оперативную память, а затем копирует начальные значения неконстантных глобальных и статических переменных из ПЗУ в ОЗУ непосредственно перед запуском main (). Всякий раз, когда приложению необходимо выдвинуть фиксированную строку из последовательного порта, оно считывает эту строку из ПЗУ.

В ранних версиях этих микроконтроллеров внешний «программатор устройств», подключенный к микроконтроллеру, является единственным способом изменить программу. В обычном режиме работы устройства не было рядом с «программатором устройства». Если программное обеспечение, работающее на микроконтроллере, необходимо записать в ПЗУ памяти программы - извините, слишком плохо это было невозможно. Многие встроенные системы имели энергонезависимую ЭСППЗУ, в которую код мог записывать, но это было только для хранения значений данных. Микроконтроллер может выполнять код только в ПЗУ программы, а не в ЭСППЗУ или ОЗУ. Люди могли делать замечательные вещи с этими микроконтроллерами, в том числе с интерпретаторами BASIC и байт-кодами Forth. Так что, очевидно, (1) код никогда не должен записываться в память программы.

С несколькими недавними микроконтроллерами с «самопрограммированием» (от Atmel, Microchip, Cypress и т. Д.), на чипе установлено специальное оборудование, позволяющее программному обеспечению, работающему на микроконтроллере, стирать и перепрограммировать блоки собственной флэш-памяти программ. Некоторые приложения используют эту функцию «самопрограммирования» для чтения и записи данных в «дополнительные» флэш-блоки - данные, которые никогда не выполняются, поэтому они не считаются самоизменяющимся кодом - но это ничего не делает Вы не могли бы сделать с большей EEPROM. До сих пор я видел только два вида программного обеспечения, работающего на микроконтроллерах Гарвардской архитектуры, которые записывают новое исполняемое программное обеспечение для своей собственной программы Flash: загрузчики и компиляторы Forth.

Когда запускается загрузчик Arduino (загрузчик начальной загрузки) и обнаруживает, что доступен новый образ прошивки приложения, он загружает новую прошивку приложения (в ОЗУ) и записывает ее во Flash. В следующий раз, когда вы включите систему, она будет использовать новую версию прошивки приложения 16.98, а не неуклюжую старую версию приложения 16.97. (Блоки Flash, содержащие сам загрузчик, конечно, остаются без изменений). Это было бы невозможно без функции «самопрограммирования» записи в программную память.

Некоторые реализации Forth работают на небольшом микроконтроллере, компилируя новый исполняемый код и используя функцию «самопрограммирования» для сохранения его в программе Flash - процесс, в некоторой степени аналогичный компиляции JVM «точно в срок». (Кажется, что все другие языки требуют слишком большого и сложного компилятора для запуска на небольшом микроконтроллере, и поэтому имеют цикл редактирования-компиляции-загрузки-запуска, который занимает намного больше времени настенных часов).

...