ос и с. ОСиС. 1. Классификация программного обеспечения
Скачать 2.7 Mb.
|
6. Загрузчик ОС Основные понятия Дадим определение загрузчику (ГОСТ): Загрузчик - программа, которая подготавливает объектную программу к выполнению и инициирует ее выполнение. Более детально функции Загрузчика следующие: выделение места для программ в памяти (распределение); фактическое размещение команд и данных в памяти (загрузка); разрешение символических ссылок между объектами (связывание); настройка всех величин в модуле, зависящих от физических адресов в соответствии с выделенной памятью (перемещение); передача управления на входную точку программы (инициализация). Не обязательно функции Загрузчика должны выполняться именно в той последовательности, в какой они описаны. Опишем эти функции более подробно. Функция распределения, по-видимому понятна из ее названия. Для размещения программы в оперативной памяти должно быть найдено и выделено свободное место в памяти. Для выполнения этой функции Загрузчик обычно обращается к операционной системы, которая выполняет его запрос на выделение памяти в рамках общего механизма управления памятью. Функция загрузки сводится к считыванию образа программы с диска (или другого внешнего носителя) в оперативную память. Функция связывания состоит в компоновки программы из многих объектных модулей. Поскольку каждый из объектных модулей в составе программы был получен в результате отдельного процесса трансляции, который работает только с одним конкретным модулем, обращения к процедурам и данным, расположенным в других модулях, в объектных модулях не содержат актуальных адресов. Загрузчик же "видит" все объектные модули, входящие в состав программы, и он может вставить в обращения к внешним точкам правильные адреса. Загрузчики, которые выполняют функцию связывания вместе с другими функциями, называются Связывающими Загрузчиками. Выполнение функции связывания может быть переложено на отдельную программу, называемую Редактором связей или Компоновщиком. Редактор связей выполняет только функцию связывания - сборки программы из многих объектных модулей и формирование адресов в обращениях к внешним точкам. На выходе Редактора связей мы получаем загрузочный модуль. Функция перемещения необходимо потому, что программа на любом языке разрабатывается в некотором виртуальном адресном пространстве, в котором адресация ведется относительно начала программной секции. При написании программы и при ее трансляции, как правило, неизвестно, по какому адресу памяти будет размещена программа (где система найдет свободный участок памяти для ее размещения). Поэтому в большинстве случаев в командах используется именно адреса меток и данных. Однако, в некоторых случаях в программе возникает необходимость использовать реальные адреса, которые определяться только после загрузки. Все величины в программе, которые должны быть привязаны к реальным адресам, должны быть настроены с учетом адреса, по которому программа загружена. Существуют программы, которые при написании рассчитываются на размещение в определенных адресах памяти, так называемые, абсолютные программы. Подготовка таких программ к выполнению значительно проще и выполняется она Абсолютным Загрузчиком. Функции такого Загрузчика гораздо проще: функция распределения не выполняется, так как реальное адресное пространство, в котором размещается программа предполагается свободным; функция загрузки, конечно, выполняется, но она предельно проста; функция связывания может быть исключена из Абсолютного Загрузчика: поскольку все адреса программы известны заранее, адреса, по которым происходят обращения к внешним точкам, могут быть определены заранее; функция перемещения исключается; функция инициализации остается. Доля абсолютных программ в общей массе программного обеспечения ничтожно мала. Абсолютными могут быть системные программы самого низкого уровня, программы, записываемые в ПЗУ, программы для встраиваемых устройств и т.п. Подавляющее же большинство системных и все прикладные программы являются перемещаемыми, то есть, они могут загружаться для выполнения в любую область памяти, и Загрузчик для таких программ выполняет перечисленные функции в полном объеме. При рассмотрении Ассемблеров мы оставили без внимания обработку обращений к внешним точкам и формат объектного модуля. Эти вопросы непосредственно относятся к функциям Загрузчика, и мы их рассмотрим здесь. Типы загрузчиков. Основные типы Загрузчиков - настраивающие и непосредственно связывающие. Настраивающие Загрузчики Настраивающий Загрузчик является первым шагом в сторону усложнения от Абсолютного Загрузчика. Функции связывания и перемещения решаются в нем не самым эффективным, но простейшим способом. Связывание в Настраивающем Загрузчике. Проблема связывания в Настраивающем Загрузчике решается при помощи Вектора Переходов. Вектор Переходов включается в состав объектного модуля и содержит список всех внешних имен, к которым есть обращение в модуле с полем адреса для каждого имени. Вектор Переходов заполняется при обработке директив типа EXT (перечисления внешних имен). В команды программы, обращающиеся к внешним именам вставляется обращение к адресному полю соответствующего элемента Вектора Переходов с признаком косвенного обращение. (Косвенное обращение означает, что обращение идет не по адресу, который задан в команде, а по адресу, который записан в ячейке, адрес которой задан в команде.) При загрузке в оперативную память Вектор Переходов загружается вместе с кодами программы и остается в памяти все время выполнения программы. Когда Загрузчик компонует программу из нескольких объектных модулей, он "узнает" все фактические адреса входных точек и в Вектора Переходов тех модулей, которые обращаются к данной входной точке вставляет эти адреса. Обращение к внешней точке, таким образом, производится косвенное через Вектор Переходов. Перемещенне в Настраивающем Загрузчике. Принятые в Настраивающих Загрузчиках методы позволяют легко реализовать настройку реальных адресов, заданных относительно начала программы. Сущность метода перемещения состоит в том, что с каждым словом кода программы (размер слова обычно равен размеру реального адреса) связывается "бит перемещения". Значение этого бита 0/1 является признаком неперемещаемого/перемещаемого слова. Если слово является неперемещаемым, оно оставляется Загрузчиком без изменений. Если слово является перемещаемым, то к значению в слове прибавляется стартовый адрес модуля в оперативной памяти. Биты перемещения могут упаковываться - например, описание 8 слов в одном байте. Непосредственно Связывающие Загрузчики Эти Загрузчики называются непосредственно связывающими потому, что они обеспечивают обращение к внешней точке непосредственно, а не через косвенную адресацию. Эти Загрузчики обеспечивают более высокую эффективность кода и более гибкие возможности связывания. Такие возможности достигаются за счет того, что в объектном модуле содержится вся необходимая для Загрузчика информация. Формат объектного модуля Объектный модуль, поступающий на вход Загрузчика должен в той или иной форме содержать: размер модуля; машинные коды; входные точки (те адреса в модуле, к которым возможны обращения извне); внешние точки (те имена во внешних модулях, к которым есть обращения в данном модуле); информация о размещении в модуле перемещаемых данных. Один из вариантов организации объектного модуля описывается ниже. Объектный модуль состоит из записей четырех типов. В каждой записи первый байт содержит идентификатор типа записи, следующие 2 байта - размер записи. Количество и формат следующих байтов записи определяется ее типом. Кодовая запись содержит адрес относительно начала модулей и коды программы. Кодовые записи строятся Ассемблером при генерации объектного кода - кодов команд и директив типа DC. Каждая кодовая запись начинается с адреса (относительно начала модуля), с которого начинается размещение ее содержимого. Разрывы в линейном пространстве адресов могут быть обусловлены директивами выделения памяти без записи в нее значений (директивы типа BSS) или разрывами, управляемыми программистом (директивы типа ORG). Запись связываний содержит один или несколько элементов Таблицы внешних символов. Элемент Таблицы внешних символов имеет следующий формат: Ассемблер формирует новые элементы Таблицы перемещений при обработке директив типа SEGMENT, ENT, EXT. Запись перемещений содержит один или несколько элементов Таблицы перемещений. Каждый элемент этой таблицы описывает один элемент кода программы, требующий настройки, зависящей от адреса загрузки программы в память и имеет следующий формат: Относительный адрес и длина - адрес и длина того кода, который должен быть модифицирован. Имя символа - имя из Таблицы внешних символов, которое прибавляется к значению кода или вычитается из него. Бит операции - признак операции сложения или вычитания. Ассемблер генерирует элемент Таблицы перемещений, когда обрабатывает адресные выражения. Адресное выражение может быть абсолютным (независящими от адреса загрузки) или перемещаемым (зависящими от адреса загрузки) . Элементы Таблицы перемещений генерируются только для перемещаемых выражений. Рассмотрим адресное выражение: ADDR1 - ADDR2 Если ADDR1 и ADDR2 являются именами, перемещаемыми внутри одного и того же сегмента SEGM (их адресные значения определяются относительно начала сегмента), то адресное выражение является абсолютным, так как его значение: SEGM+ADDR1 - (SEGM+ADDR2) не зависит от адреса сегмента. Для такого выражения элемент Таблицы перемещений не строится. Если ADDR1 является именем, перемещаемым внутри сегмента SEGM, а ADDR2 - абсолютный адрес, то выражение является простым перемещаемым. В кодовое представление этого выражения записывается разность между относительным адресом в сегменте ADDR1 и абсолютным значением ADDR2. Для такого выражения строится элемент Таблицы перемещений: адрес SEGN + длина Загрузчик прибавит к содержимому кода адрес сегмента SEGM. Если ADDR1 является внешним именем, а ADDR2 - абсолютный адрес, то выражение также является простым перемещаемым. В кодовое представление этого выражения абсолютное значение ADDR2. Элемент Таблицы перемещений для такого выражения содержит: адрес ADDR1 + длина Если ADDR1 и ADDR2 являются внешним именем, то выражение является сложным перемещаемым. В кодовое представление этого выражения записывается 0. Для такого выражения строятся два элемента Таблицы перемещений: адрес ADDR1 + длина адрес ADDR2 - длина При загрузке к нулевому значению записанному по адресу адрес будет прибавлен адрес внешней точки ADDR1, а затем вычтен адрес внешней точки ADDR2. Запись окончания формируется Ассемблером при обработке директивы END, она содержит стартовый адрес программы. Естественно, эта запись должна быть заполнена только в одном из объектных модулей, составляющих программу. Алгоритм работы Непосредственно Связывающего Загрузчика Наиболее простой алгоритм работы Загрузчика - двухпроходный. На вход Загрузчика обязательно подается список объектных модулей, из которых составляется программа. Этот список может быть параметром программы-Загрузчика или находиться в отдельном файле. На первом проходе Загрузчик просматривает все объектные модули по списку и решает 2 задачи: определяет общий объем области памяти, необходимый для программы и размещение объектных модулей в этой области; составляет Глобальную таблицу внешних имен программы. Структура элемента Глобальной таблицы - такая же, как и Таблицы внешних символов каждого модуля. В нее заносятся только входные точки всех модулей. Поскольку Загрузчик уже знает, в каком месте области памяти, выделяемой для программы, будет размещаться тот или иной модуль, он заносит в Глобальную таблицу адреса входных точек относительно начала всей программы. В конце 1-го прохода Загрузчик выделяет память и, уже зная фактический начальный адрес программы в памяти, корректирует все адреса в Глобальной таблице внешних символов. На 2-ом проходе Загрузчик снова читает все объектные модули по списку. При этом он уже размещает коды модуля в памяти и формирует для каждого модуля Таблицу внешних символов (локальную для модуля) и Таблицу перемещений. Адресные поля в этих таблицах он заполняет или корректирует с учетом фактического адреса модуля в памяти и содержимого Глобальной таблицы внешних символов. Затем он выполняет обработку Таблицы перемещений, используя для коррекции адресных кодов в программе значения из Локальной Таблицы внешних символов. Алгоритм выполнения 1-го прохода - следующий:
Алгоритм выполнения 2-го прохода - следующий:
Этапы загрузки ОС Первый этап загрузки ОС. В системном блоке компьютера находится постоянное запоминающее устройство (ПЗУ, постоянная память, ROM-Read Only Memory - память с доступом только для чтения), в котором содержатся программы тестирования блоков компьютера и первого этапа загрузки ОС. Они начинают выполнятся с первым импульсом тока при включении компьютера. На этом этапе процессор обращаются к диску и проверяет наличие на определенном месте (в начале диска) очень небольшой программы - загрузчика. Если эта программа обнаружена, то она считывается в ОЗУ и ей передается управление. Второй этап загрузки ОС. Программа - загрузчик, в свою очередь, ищет на диске базовый модуль ОС, переписывает его память и передает ему управление. Третий этап загрузки ОС. В состав базового модуля входит основной загрузчик, который ищет остальные модули ОС и считывает их в ОЗУ. После окончания загрузки ОС управление передается командному процессору и на экране появляется приглашение системы к вводу команды пользователя. Заметим, что в оперативной памяти во время работы компьютера обязательно должны находится базовый модуль ОС и командный процессор. Следовательно, нет необходимости загружать в оперативную память все файлы ОС одновременно. Драйверы устройств и утилиты могут подгружаться в ОЗУ по мере необходимости, что позволяет уменьшать обязательный объем оперативной памяти, отводимый под системное программное обеспечение. |