Что управляет оперативной памятью? - PullRequest
5 голосов
/ 03 февраля 2012

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

Ответы [ 2 ]

7 голосов
/ 03 февраля 2012

Как уже говорилось, адрес, по которому ЦП ожидает, что стартовая программа будет, обычно зашит.Это, вероятно, программируется в случае некоторых очень специфических процессоров или тому подобного, но в случае x86 это FFFF0 или, если быть более точным, FFFFFFF0, так что на 16 байт ниже самого верхнего физического адреса ЦП.Материнская плата обычно сопоставляет эти адреса с ПЗУ, которое содержит (скорее всего) переход к коду BIOS, который, в свою очередь, загружает компьютер.

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

4 голосов
/ 03 февраля 2012

Каждый процессор, а иногда и подмножества семейства процессоров имеют свою схему загрузки.обычно это одна из следующих категорий:

1) таблица адресов для различных видов прерываний / событий (сброс, прерывание, nmi и т. д.), часто называемая векторной таблицей, эта таблица находится в жестко заданном месте, аппаратные возможностиup читает адрес в векторе сброса и затем начинает выполнять код по адресу, указанному в векторе сброса.

2) таблица инструкций, адреса для этих инструкций находятся в известном месте, например, ARM используетТаким образом, вы получаете одну инструкцию на вектор / событие, так что одна инструкция должна быть загрузочным ПК или ветвью (или следующие векторы не должны использоваться, и затем вы можете использовать больше инструкций, чтобы выйти из таблицы векторов.

3) позвольте мне подумать о некоторых других

Некоторые компании (архитектуры процессоров) используют высокий адрес, например, 0xFFFE - это вектор сброса, а 0xFFFC - прерывание.msp430 и 6502 я думаю, что это так.Как вы видели в других ответах, 8088/86 и семейство используют 0xFFFxxxFFFF0 в качестве точки входа / адреса сброса.

Другие люди, такие как ARM и Atmel AVR, используют адрес 0x0000 в качестве точки входа.

Если вы заходите на свою машину обратного хода, когда интерфейс памяти процессоров был очень простым, то некоторые адресные биты, биты данных, стробы чтения и записи и, возможно, разрешение выбора или выхода микросхемы или что-то еще.Вы будете использовать внешнюю логику, например, 74LSxx, для декодирования некоторых старших битов адреса, легко декодировать все нули и все единицы, так что вы будете иметь rom по верхним адресам (все верхние биты адреса) и ram по младшимадреса (старшие биты адреса все нули) или наоборот.Даже сегодня в микроконтроллерах и процессорах вообще это облегчает жизнь.Таким образом, ваши ARM и AVR будут склонны считать, что адрес 0 - это rom, а ram - где-то еще.ваш x86, msp430 и другие установят rom наверху, а ram внизу или где-то посередине.

Вам нужно жестко закодировать этот адрес на ассемблере?Ну, не обязательно, обычно вы что-то жестко кодируете для компоновщика, чтобы он помещал векторы в нужное место, но есть ассемблеры, которые все еще поддерживают директивы типа .org, где вы задаете код после того, как эта директива будет размещена по этому адресу впространство памяти.

Каждый процессор имеет какой-то загрузчик, даже ваш компьютер.Это отдельная программа, которая компилируется, зная правило загрузки процессоров, которое является первым битом кода, запускаемого на этом процессоре.Оттуда это может варьироваться, у вас может быть только одна эта программа, и поэтому у вас нет планов менять программы после загрузки, иногда это просто называется прошивкой.Теперь иногда в загрузчике есть какая-то подсказка, может быть, вы используете последовательный порт и тупой терминал для ввода команд или загрузки программы с использованием xmodem и т. Д. (Uboot, redboot и т. Д. Делают подобные вещи).Часто вы хотите загружаться и запускаться без вмешательства человека, поэтому может быть возможность нажать клавишу на терминале / последовательном порту или нажать кнопку на плате при загрузке и т. Д. В противном случае загрузчик имеет набор правилчто делать дальше, и эти правила являются уникальными для автора (ов) загрузчика, это просто программное обеспечение, вы можете делать все, что вы хотите.Например, на вашем компьютере этот загрузчик называется BIOS, и вы, вероятно, можете нажать клавишу F1, F2 или DEL или какую-либо другую клавишу или последовательность клавиш и прервать обычный процесс загрузки, чтобы сделать что-то еще (изменить настройки BIOS и т. Д.).В противном случае BIOS имеет набор правил (иногда / часто, которые вы можете изменить), где он ищет следующую вещь для загрузки и запуска.Обычно пытаются найти какой-нибудь носитель, например, жесткий диск, USB-флешку, дискету или CD / DVD-диск, содержащий загрузочный сектор.Этот загрузочный сектор - это просто код, BIOS применяет правила о том, как должен выглядеть этот код или по какому адресу и т. Д., Для чего он должен компилироваться, он загружает этот код и становится другой формой загрузчика, код может делать все, что захочет,загрузите Linux, загрузите Windows, загрузите DOS, задайте вам несколько вопросов о том, что вы хотите загрузить, запустите программу тестирования памяти, что угодно.

В будущем вы можете загрузить другую программу, операционную систему, одну программуу него есть свои собственные правила, которым он следует, и если он разрешает загружать другие программы, эти программы должны жить по правилам.Иногда, когда у вас есть MMU, вы можете заставить программу думать, что она работает по одному адресу, а на самом деле - по другому, но это позволяет вам заставить все программы предполагать, что они работают с определенного адреса, а затем просто скомпилировать их.для этого адреса (большинство программ, которые вы пишете для windows / linux и т. д., выглядят так).но если у вас нет mmu, тогда могут быть разные правила, например, что вся программа должна быть позиционно-независимым кодом (нигде не должно быть жестко закодированных адресов), мне говорят, что uclinux похож на это.

Микроконтроллеры - это хорошее место дляизучите этот тип вещей, поскольку у вас уже может быть установлен загрузчик (arduinos идут таким образом, чипы lpc и st часто имеют загрузчик, последовательный или usb, или оба).Иногда, как и AVR, загрузчик находится во флэш-памяти, которую вы можете изменить, разделяя флэш-загрузчик и флэш-память приложения, иногда загрузчик находится во флэш-памяти, но только производитель чипа знает, как изменить / изменить его, чтобы вы застряли с их загрузчиком навсегда.В любом случае вы все равно можете создать свой собственный загрузчик, который работает поверх этого, где вы можете создать способ загрузки других программ, правила выхода этих программ обратно в загрузчик, чтобы другие программы могли работать, и т. Д. У меня есть некоторые инструкцииустановить симуляторы (на разных этапах отладки использовался какой-то использованный имитатор, как и pcemu, который я разбудил у кого-то другого), чтобы вы могли обернуть тупой терминал и создать собственное окружение без необходимостикупить что угодно (можно сделать это с помощью qemu и gdb, но не так просто).

Если вы посмотрите на эти микроконтроллеры в частности, но это проблема со всеми процессорами, как правило, загрузочный код, включая векторы, находится в rom, когда вы работаете, хотя вы не всегда хотите, чтобы эти векторы были жестко запрограммированы вrom, вы должны либо создать какую-то схему, чтобы код rom как-то разветвлялся в ram, либо есть аппаратная схема, где после загрузки вы можете где-то щелкнуть переключателем (записать немного в байт где-нибудь в регистре) иизмените, какая память декодируется по этому адресу, что позволит вам переключиться в оперативную память и заменить таблицу векторов чем-то мягким.некоторые из этих микроконтроллеров имеют для этого слишком сложные схемы.Здесь снова вы должны посмотреть на документы для этого процессора и / или чипа, чтобы выяснить, как он работает.Иногда это что-то вне чипа на плате, которое вызывает изменение адресного пространства, поэтому вы должны прочитать об этом.

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

переменные и данные управляются вами и компилятором.язык, который вы используете, и используемый вами компилятор, например, создадут сегменты .text, .data, .bss, а через компилятор или компоновщик вы должны дать инструментам конкретные адреса, где разместить каждую из этих вещей для этого двоичного файла.И в этом глубоко укоренившемся случае это означает переход к документам для системы (микросхема плюс плата), чтобы выяснить, где должна быть каждая часть для правильной загрузки и работы.И вы должны как-то разместить эту информацию там.например, если вы пишете код, который создает сегмент .data (я обычно этого не делаю), и вы загружаетесь с флэш-памяти, у вас должна быть какая-то схема компиляции компилятора, чтобы сегмент .data находился в оперативной памяти, но при загрузкеЕсли вы не находитесь в ram, у вас должна быть копия сегмента .data где-то в rom, затем вы должны скопировать ее в ram, прежде чем попадете в основную часть кода.Точно так же вы должны установить указатели стека и, если необходимо, изменить таблицу векторов и т. Д. Если вы используете dram, вам нужно инициализировать память с кодом, который, возможно, придется запускать без памяти, чтобы получить dram up, затем скопируйте .data, zero .bss, setуказатель (и) стека затем переходят к main ().

...