Почему любую программу перед выполнением нужно загрузить в оперативную память кратко

Обновлено: 04.07.2024

В статье Тестируем Bootloader в режиме UART были протестированы команды управления UART-загрузчиком,а также запущена программа, записанная в Flash. Команды загрузчика позволяют записать массив байт в ОЗУ и запустить программу с заданного адреса. Этого достаточно, чтобы записать в ОЗУ программу и её запустить. Этому будет посвящена данная статья.

Для запуска в ОЗУ потребуется программа, которая использует только адреса ОЗУ. Такой пример рассматривался в статье - Запуск программы из ОЗУ в среде Keil, программа называется HelloWorld_RAM. В проект нужно внести изменение (см. раздел "Получение bin-файла").

Получение bin-файла

Для начала необходимо получить бинарный файл программы из проекта HelloWorld_RAM. В этом файле нет ничего лишнего - только байты кода программы. Есть различные конвертеры, которые позволяют из hex файла получить bin файл. Можно было бы использовать их. Но можно использовать штатную возможность Keil, описанную здесь - Keil: GENERATING BINARY OUTPUT DURING A BUILD

$K\ARM\ARMCC\bin\fromelf.exe --bin --output=@L.bin !L



Рисунок 1 - Настройки во вкладке Otions for Target -> User для создания bin-файла программы

Теперь необходимо пересобрать проект (Rebuild) HelloWorld_RAM, и в папке проекта появится файл "HelloWorld_RAM.bin". Keil и проект можно закрыть, они больше не потребуются.

Загрузка bin файла в ОЗУ

Далее необходимо узнать размер файла, поскольку для команды LOAD потребуется указать количество байт, записываемых в ОЗУ. Для этого нужно кликнуть правой кнопкой мыши на "HelloWorld_RAM.bin", выбирать свойства и посмотреть точный размер файла в байтах (рисунок 2).



Размер HelloWorld_RAM.bin равен 3116 байт, что в шестнадцатеричной системе равно 0х0С2С. Теперь есть все данные для загрузки программы.

Запустите программу Terminal v1.9b и повторите все действия, описанные в статье Тестируем Bootloader в режиме UART до получения приглашения от микроконтроллера. При желании можно также увеличить скорость обмена по UART, чтобы загрузка прошла быстрее. Например, выставить 19200 бод.

Теперь нужно написать макрос M10. Код команды = 'L', адрес = 0x2000_0000, количество байт = 0x0000_0C2C. Записать программу необходимо с адреса, который был указан в поле IROM1 закладки Options - Target при сборке проекта "HelloWorld_RAM". Там был указан стартовый адрес ОЗУ, поэтому и параметр адрес = 0x2000_0000.

Код макроса М10: L$00$00$00$20$2C$0C$00$00

(2) - После этого придет подтверждение команды загрузки - 'L'.

Теперь можно нажать ОК и файл будет передан в UART (последовательность действий изображена на рисунке 3).



Рисунок 3 - Последовательность действий для загрузки файла HelloWorld_RAM.bin по UART

Спустя несколько секунд, приходит символ 'K' - подтверждение от микроконтроллера об успешном получении 3116 байт. Теперь программа находится в ОЗУ. В терминале это выглядит так:

Запуск

Для запуска программы нужно написать макрос М11, код команды = 'R', стартовый адрес = 0x2000_0000.

Код макроса М11: R$00$00$00$20 >R 00 00 00 20 вот запустил ты программу — как собираешься узнавать — в оперативке она или нет? :-)

тык — это же системный вызов чтоб заарканить для себя участок памяти.



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

Просто примонтируй tmpfs и перенеси туда все нужные данные. Естественно, при перезагрузке или внезапном отключении питания всё пропадёт.



Тогда уж ramfs.
Жалко, только, что не пришёл какой-нибудь хакер и не ответил на оригинальный вопрос.



Понимаешь вопрос? Зачем? Почитай про prelink, preload, read-ahead демоны.
Кстати, как по-твоему происходит загрузка исполняемых файлов в память? Ты ведь знаешь, что после загрузки бинарника его можно удалить?

X10Dead ★★★★★ ( 29.10.14 17:27:29 )
Последнее исправление: X10Dead 29.10.14 17:27:58 (всего исправлений: 1)



Просто примонтируй tmpfs и перенеси туда все нужные данные. Естественно, при перезагрузке или внезапном отключении питания всё пропадёт.

тыг в реальной системе — уже ведь полно существует уже примонтированных tmpfs

или /tmp/ (но не у всех).

но нам тут гораздо важнее узнать — что именно хочет топикстартер .. зачем ему всё это нужно.. :)

user_id_68054 ★★★★★ ( 29.10.14 17:29:20 )
Последнее исправление: user_id_68054 29.10.14 17:31:21 (всего исправлений: 2)



И что? Чтение/запись кэшируются в памяти. После того как система прочихается - всё будет в памяти.



Чтобы танки не тормозили, это каждый знает



Из приведенного результата видно, что средняя скорость чтения с HDD составляет 70 Мб/с, а скорость чтения с виртуального составляет 1527 Мб/с, что почти в 22 раза больше чем с HDD. Я думаю, комментарии лишние.

неее.. комментарии как раз НЕ излишни. :)

HDD медленный — но зато *имеет* данные.

оперативка быстрая — но зато *не_имеет* нужных данных.

как ты сделаешь так чтобы в оперативке появились данные? будешь копировать данные из HDD в оперативку? но ведь HDD медленный.. выигрыша нет..



чем оно лучше tmpfs?

Ее давно закапали, работы по откапыванию ведутся

синкать данные из озу на диск тебе религия не позволяет. а ведь я такое видел, пиратские игровые сервачки не дадут соврать



А как насчет повторных обращений к этим данным?

В качестве примера можно загрузить базу данных, тоже бессмысленно?



А как насчет повторных обращений к этим данным?

а повторные обращения — они всё равно физически не будут задействовать HDD (ну там по минимум будут, совсем)



В качестве примера можно загрузить базу данных, тоже бессмысленно?

думаю кой какой выигрыш будет. я бы так рисковать не стал бы.

не стоит оно того

а если базу дрючат 10к хомячков, чьи действия навечно остаются в этой базе и действий этих под пол сотни в секунду? (:



синкать данные из озу на диск тебе религия не позволяет. а ведь я такое видел, пиратские игровые сервачки не дадут соврать

думаю узкое горлышко будет в момент этого синка :)



насчет повторных обращений к этим данным?

Смотри, какой фокус:

не, узкое место, это вайп на несколько минут при факапе, но такое бывает редко



а если базу дрючат 10к хомячков, чьи действия навечно остаются в этой базе и действий этих под пол сотни в секунду? (:

сложный вопрос. нужно все нюансы учитывать.

быть может как-то оттюнинговать базу данных — поособому





Ну будет 1902 MB/c, чем это плохо то?



понятие ОЗУ — не совсем конкретное.



А мемристоры по-твоему что? И оперативку с батарейкой куда отнести? Они успешно существуют уже лет 10 по меньшей мере.



Ну будет 1902 MB/c, чем это плохо то?

Как видишь, результат получается хуже. Можно конечно тут попробовать что-нибудь настроить. Но существенно лучше чем кэш всё равно не будет.

Кстати, а почему ты сравниваешь свою скорость с моей? У меня как бы очень не быстрая память и процессор в этом отношении.



а повторные обращения — они всё равно физически не будут задействовать HDD (ну там по минимум будут, совсем)



В качестве примера можно загрузить базу данных, тоже бессмысленно?
я бы так рисковать не стал бы. не стоит оно того

расскажи это орацле.



читая эти единожды запрашиваемые данные так же постоянно забивает ими кеш

А куда она должна их прочитать? ЕМНИП там файлы ммапятся на страницы памяти, которые потом расшариваются и в кэш и в читающую программу. Т.е. дополнительно под кэш ничего не расходуется.



Окей, здесь ты может и прав, а что по поводу новых данных, генерируемых ежесекундно 1кк хомячками?



не работает так ядро Linux ?



у zfs примерно так и работает кэш.



Кеш позволяет не читать файлы с диска, если они уже были прочитаны. И при малой дисковой активности кеш в Linux очень эффективен. Но вот когда начинается разнородное чтение большого числа данных, то кеш перестаёт быть эффективным. В том время, как если бы можно было настроить кеш индивидуально, указав приоритет для определённых каталогов, эффективность работы кеша в таком случае стала бы много-много выше.



а что по поводу новых данных, генерируемых ежесекундно 1кк хомячками?

Они тоже кэшируются, причём параметры настраиваются. Тут есть такая проблема, что если много держать в пямяти, то во время очередного sync этот самый синк будет долгим и подтормозит другие операции с диском. Так что идея держать всё в ОЗУ (хоть на диске, хоть в кэше) не всегда хороша. Поэтому и есть настройки.



Нагуглил тут такую штуку, как проект RapidDisk и его приложение RapidCache. Кажется, оно умеет делать именно то, что нужно. Буду экспериментировать. А не поможет — подумаю на счёт tmpfs, загрузки при старте, выгрузки при выключении и синхронизации через lsyncd :) Велосипед, конечно, и не так эффективно, как при кешировании, но задача решаемая.



Тут есть такая проблема, что если много держать в пямяти, то во время очередного sync этот самый синк будет долгим и подтормозит другие операции с диском

Само по себе это не проблема. Есть же всякие lsyncd, которые синхронизируются при изменениях в файлах.

Тут фигово другое — открытые и дописываемые большие файлы. Например, гигабайтный лог веб-сервера. При каждой синхронизации эти гигабайты будут писаться целиком. Так что тут такой подход не подойдёт. Но вот когда файлы меняются мало и они мелкие — может быть эффективно.

ОЗУ, или оперативная память, используется для более быстрой загрузки программ и выполнения задач за долю времени, которое потребовалось бы, если бы программа загружалась с вашего жесткого диска. RAM жизненно важна для производительности в любой программе, которой требуется доступ к огромному объему данных.

Например, программа обработки текста не будет сильно полагаться на оперативную память из-за низких требований к производительности. Однако для подробной электронной таблицы Excel или Photoshop требуется столько оперативной памяти, сколько вы можете сэкономить. И игры тоже. Во многих случаях вам необходимо выделить дополнительную оперативную память для игр, особенно если вы используете много модов.



Это верно в таких играх, как Minecraft, а также в таких играх, как Shadow of Mordor, которым нужны колоссальные 8,3 ГБ видеопамяти. Хорошей новостью является то, что вы можете выделить больше оперативной памяти для определенных приложений, чтобы улучшить их производительность.

Что такое оперативная память?

Думайте об оперативной памяти как об оперативной памяти вашего компьютера. Это позволяет вашей системе получать доступ к данным намного быстрее, чем даже через SSD. Если у вас одновременно работает несколько приложений, вам понадобится больше оперативной памяти, чем если бы вы использовали только несколько одновременно.

Разрешить Windows 10 выделить больше оперативной памяти



После этого нажмите Применить. Изменения вступят в силу после перезагрузки компьютера. Этот параметр позволяет Windows выделять оперативную память по мере необходимости, чтобы программы работали как можно более плавно.

Приоритет использования ОЗУ



Назначьте использование ОЗУ в определенных программах



Если вы ищете более подробное объяснение, вот еще одна статья, которая может помочь.

У каждой игры и программы будет свой метод выделения дополнительной оперативной памяти, если это вообще возможно. Многие приложения запрограммированы на использование определенного количества ОЗУ в зависимости от вашей операционной системы, независимо от того, сколько у вас доступно. Например, Microsoft Excel в 32-разрядных операционных системах ограничен 2 ГБ ОЗУ.

Управление памятью – одна из главных задач ОС. Она критична как для программирования, так и для системного администрирования. Я постараюсь объяснить, как ОС работает с памятью. Концепции будут общего характера, а примеры я возьму из Linux и Windows на 32-bit x86. Сначала я опишу, как программы располагаются в памяти.

image

image

Это не значит, что ядро использует так много физической памяти – просто у него в распоряжении находится часть адресного пространства, которое можно поставить в соответствие необходимому количеству физической памяти. Пространство памяти для ядра отмечено в таблицах страниц как эксклюзивно используемое привилегированным кодом, поэтому если какая-то программа пытается получить в него доступ, случается page fault. В Linux пространство памяти для ядра присутствует постоянно, и ставит в соответствие одну и ту же часть физической памяти у всех процессов. Код ядра и данные всегда имеют адреса, и готовы обрабатывать прерывания и системные вызовы в любой момент. Для пользовательских программ, напротив, соответствие виртуальных адресов реальной памяти меняется, когда происходит переключение процессов:

Голубым отмечены виртуальные адреса, соответствующие физической памяти. Белым – пространство, которому не назначены адреса. В нашем примере Firefox использует гораздо больше места в виртуальной памяти из-за своей легендарной прожорливости. Полоски в адресном пространстве соответствуют сегментам памяти таким, как куча, стек и проч. Эти сегменты – всего лишь интервалы адресов памяти, и не имеют ничего общего с сегментами от Intel. Вот стандартная схема сегментов у процесса под Linux:

image

Когда программирование было белым и пушистым, начальные виртуальные адреса сегментов были одинаковыми для всех процессов. Это позволяло легко удалённо эксплуатировать уязвимости в безопасности. Зловредной программе часто необходимо обращаться к памяти по абсолютным адресам – адресу стека, адресу библиотечной функции, и т.п. Удаленные атаки приходилось делать вслепую, рассчитывая на то, что все адресные пространства остаются на постоянных адресах. В связи с этим получила популярность система выбора случайных адресов. Linux делает случайными стек, сегмент отображения в память и кучу, добавляя смещения к их начальным адресам. К сожалению, в 32-битном адресном пространстве особо не развернёшься, и для назначения случайных адресов остаётся мало места, что делает эту систему не слишком эффективной.

Самый верхний сегмент в адресном пространстве процесса – это стек, в большинстве языков хранящий локальные переменные и аргументы функций. Вызов метода или функции добавляет новый кадр стека (stack frame) к существующему стеку. После возврата из функции кадр уничтожается. Эта простая схема приводит к тому, что для отслеживания содержимого стека не требуется никакой сложной структуры – достаточно всего лишь указателя на начало стека. Добавление и удаление данных становится простым и однозначным процессом. Постоянное повторное использование районов памяти для стека приводит к кэшированию этих частей в CPU, что добавляет скорости. Каждый поток выполнения (thread) в процессе получает свой собственный стек.

Можно прийти к такой ситуации, в которой память, отведённая под стек, заканчивается. Это приводит к ошибке page fault, которая в Linux обрабатывается функцией expand_stack(), которая, в свою очередь, вызывает acct_stack_growth(), чтобы проверить, можно ли ещё нарастить стек. Если его размер не превышает RLIMIT_STACK (обычно это 8 Мб), то стек увеличивается и программа продолжает исполнение, как ни в чём не бывало. Но если максимальный размер стека достигнут, мы получаем переполнение стека (stack overflow) и программе приходит ошибка Segmentation Fault (ошибка сегментации). При этом стек умеет только увеличиваться – подобно государственному бюджету, он не уменьшается обратно.

Динамический рост стека – единственная ситуация, в которой может осуществляться доступ к свободной памяти, которая показана белым на схеме. Все другие попытки доступа к этой памяти вызывают ошибку page fault, приводящую к Segmentation Fault. А некоторые занятые области памяти служат только для чтения, поэтому попытки записи в эти области также приводят к Segmentation Fault.

Если в куче оказывается недостаточно места для выполнения запроса, эту проблему может обработать сама программа без вмешательства ядра. В ином случае куча увеличивается системным вызовом brk(). Управление кучей – дело сложное, оно требует хитроумных алгоритмов, которые стремятся работать быстро и эффективно, чтобы угодить хаотичному методу размещению данных, которым пользуется программа. Время на обработку запроса к куче может варьироваться в широких пределах. В системах реального времени есть специальные инструменты для работы с ней. Кучи тоже бывают фрагментированными:

image

И вот мы добрались до самой нижней части схемы – BSS, данные и текст программы. BSS и данные хранят статичные (глобальные) переменные в С. Разница в том, что BSS хранит содержимое непроинициализированных статичных переменных, чьи значения не были заданы программистом. Кроме этого, область BSS анонимна, она не соответствует никакому файлу. Если вы пишете static int cntActiveUsers , то содержимое cntActiveUsers живёт в BSS.

Сегмент данных, наоборот, содержит те переменные, которые были проинициализированы в коде. Эта часть памяти соответствует бинарному образу программы, содержащему начальные статические значения, заданные в коде. Если вы пишете static int cntWorkerBees = 10 , то содержимое cntWorkerBees живёт в сегменте данных, и начинает свою жизнь как 10. Но, хотя сегмент данных соответствует файлу программы, это приватное отображение в память (private memory mapping) – а это значит, что обновления памяти не отражаются в соответствующем файле. Иначе изменения значения переменных отражались бы в файле, хранящемся на диске.

Пример данных на диаграмме будет немного сложнее, поскольку он использует указатель. В этом случае содержимое указателя, 4-байтный адрес памяти, живёт в сегменте данных. А строка, на которую он показывает, живёт в сегменте текста, который предназначен только для чтения. Там хранится весь код и разные другие детали, включая строковые литералы. Также он хранит ваш бинарник в памяти. Попытки записи в этот сегмент оканчиваются ошибкой Segmentation Fault. Это предотвращает ошибки, связанные с указателями (хотя не так эффективно, как если бы вы вообще не использовали язык С). На диаграмме показаны эти сегменты и примеры переменных:

image

Как было сказано в предыдущей статье, главную роль в компьютере выполняет процессор.

Во время обработки наших заданий у процессора возникает необходимость запоминать некоторую информацию.

Это похоже на то, как человек, готовя какое-то блюдо по рецепту запоминает сколько грамм сахара или соли нужно добавить. Посмотрел в рецепт - запомнил сколько нужно сахара - достал сахар - насыпал. Посмотрел в рецепт - запомнил сколько нужно соли - достал соль - насыпал. Приготовил - всё забыл.

Такую информацию процессору нужно запомнить очень быстро, можно сказать оперативно, и только на короткий срок . И для хранения такой информации у процессора есть оперативная память (ОЗУ, RAM, оперативка).

Вот так она может выглядеть:

Чем больше в распоряжении процессора оперативной памяти - тем лучше, тем быстрее запускаются и работают программы.

Особенность оперативной памяти в том, что информация в ней храниться столько, сколько это нужно процессору, а затем удаляется. Как в примере с рецептом - человек приготовил блюдо и всё забыл, так и после выполнения задания процессором вся информация из оперативной памяти стирается.

Помните " Все несохранённые данные будут утеряны "? Это как раз об этом - значит, что в оперативной памяти есть какие-то данные, которые ещё не сохранены и при закрытии программы будут стёрты.

Помимо этого, оперативная память "энергозависимая", это значит, что при выключении компьютера все данные из оперативной памяти стираются. Поэтому внезапное отключение электричества тоже приводит к потере данных - те данные, которые находились в оперативной памяти и не были сохранены, пропадают.

А вот куда сохраняются данные, которые должны быть сохранены будет рассказано в следующей статье ( подписывайтесь, если интересно)

Задавайте вопросы, оставляйте комментарии и ставьте лайки. Большое спасибо за прочтение!

Скорее всего вопрос немного не к теме раздела, но всё же. Почему необходимо загружать программы перед началом выполнения в оперативную память? Возможно ли выполнять программы без загрузки в оперативную память с жёсткого диска и память выделять для процессов на жёстком диске?

Возможно ли расширить оперативную память?
Если в описании ноутбука указано что 4 максимум. если поставить 8 вместо 4, заведётся ли машина.

Возможно ли совместить оперативную память с видухой?
Возможно ли совместить оперативную память с видухой?


Возможно ли серверную оперативную память использовать на рабочей станции?
Есть рабочая станция на матери ASUS H61M-D. И камень i7-3770 3.4GHz. Мать имеет 2 гнезда.


Как узнать насколько возможно увеличить оперативную память asus x54c sx019d
Я смотрел оф сайт Asus, смотрел поиск на форуме, ничего не понял. В ноутбуке - 3 GB RAM, еще давно.

Вот вообще почему возник такой вопрос. Виртуальная память, насколько мне известна, была изобретена для того, чтобы можно было выполнять программы, размер которых превышает физический объём оперативной памяти. При это часть страниц виртуальной памяти располагается на HDD. Ну с другой стороны можно же было программы выделять непосредственной на жёстком диске, а защиту процессов реализовывать на основе адресных пространств. Или такой способ работы был бы слишком медленным?

Читайте также: