Как сегмент .data загружается в отдельную область памяти, чем сегмент .code в x86? - PullRequest
1 голос
/ 26 октября 2019

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

Скажем, у меня есть простое ядро:

.data
var dw 123

.code
mov eax ebx

Как загрузчик или что-то еще обрабатывает, фактически загружает код ядра в отдельную область для данных? И скажем, у меня есть 5 различных файлов сборки, все с сегментами .data, все переменные загружены одна за другой в одну и ту же область?

1 Ответ

3 голосов
/ 26 октября 2019

Это зависит от загрузчика, так что в конечном итоге это зависит от того, что делает загрузчик, но обычно загрузчики загружают стандартные исполняемые образы в стандартных форматах, таких как PECOFF или ELF. Они загружают ядро ​​так же, как операционные системы загружают исполняемые файлы программы.

Разделы существуют, так что содержимое разделов с одинаковыми именами будет последовательно сгруппировано в исполняемом файле. Компоновщик возьмет содержимое всех разделов .text во всех входных объектных файлах и объединит их в один раздел .text в выходном исполняемом файле. Точно так же он будет делать то же самое для .data и других именованных разделов.

Компоновщик берет все эти объединенные разделы и помещает их один за другим в исполняемый файл, создавая одно непрерывное изображение, которое можно загрузить в память. В операционной системе исполняемый файл будет загружен в память одним непрерывным фрагментом. При необходимости перемещения будут применяться для учета загрузки исполняемого файла по адресу, отличному от того, куда он был предназначен для загрузки, и неинициализированные сегменты данных (.bss) будут инициализироваться нулями. Наконец, права доступа к каждой странице исполняемого файла в памяти будут изменены в соответствии с сегментами, к которым они принадлежат. Например, страницы в разделах .text будут помечены как доступные только для чтения и исполняемые, в то время как в разделах .data они будут помечены как доступные для чтения и записи, а не как исполняемые.

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

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

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

...