3.2 Интерфейс системного загрузчика

Предыдущая  Содержание  Следующая V*D*V

Загрузчик представляет собой часть программного обеспечения, которая начинает выполняться сразу после включения питания системы. Загрузчик является важной частью процесса разработки, а также одной из самых сложных. Большинство вопросов загрузки, зависящих от процессора и платы, вынесены за рамки обсуждения. Многие процессоры, такие как ARM, x86 и MIPS, при сбросе начинают выполнение с определённых векторов. Некоторые другие, такие как M68K, читают стартовый адрес из загрузочного ПЗУ. Таким образом, возникает такой вопрос, как может ли первым и единственным загруженным образом быть сам Linux, что исключает использование загрузчика. Устранение загрузчика и запись в ПЗУ ядра, которое загружает само себя, является подходом, предоставляемым многими RTOS, в том числе VxWorks, которая предоставляет процедуры инициализации загрузки, чтобы выполнить POST (Power-On Self-Test, самотестирование при включении питания), настроить сигналы выбора микросхем, проинициализировать память и кэши памяти, и переместить образ из ПЗУ в ОЗУ.

 

Большинство настроек при сбросе зависимы от платы и обычно производители плат предоставляют на плате PROM, которая выполняет всё вышеописанное. Лучше использовать для загрузки образа ядра или временного загрузчика PROM и таким образом спасти разработчиков от работы по программированию платы. Даже если PROM не доступна, лучше отделить процесс загрузки, чтобы затем загрузчик позволил ядру загрузиться. Преимущества такого подхода приведены ниже.

 

Кроме загрузок из ROM, могут быть реализованы несколько методов загрузки ядра, такие как через последовательный порт (Kermit) или через сеть (TFTP).

Это обеспечивает защиту от небезопасных перезаписей образа ядра в случае, когда образ ядра хранится во флеш-памяти. Предположим, что когда ядро обновлялось, было отключение электроэнергии; после этого плата находится в подвешенном состоянии. Безопасным способом будет поместить загрузчик в какие-то защищённые секторы флеш-памяти (обычно называемые загрузочными секторами) и оставить его неприкасаемым, чтобы всегда был доступен путь для восстановления.

 

По опыту, Linux всегда предполагает, что он выполняется из памяти (некоторые патчи для выполнения на месте [eXecute In Place, XIP] позволяют Linux выполняться непосредственно из ПЗУ; это обсуждается позже). Загрузчики являются независимыми частями программного обеспечения, которые должны быть собраны независимо от ядра Linux. Если ваша плата поддерживает PROM, загрузчик выполнит инициализацию процессора и платы. Поэтому загрузчик является сильно зависимым от платы и процессора. Функциональность загрузчика можно разделить на две части: обязательную и необязательную. Дополнительная функциональность загрузчика разнообразна и зависит от потребностей потребителя. Обязательными функциями загрузчика являются:

 

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

2.Загрузка ядра: необходимое программное обеспечение для загрузки ядра и копирование его в соответствующие ячейки памяти.

 

Ниже приведён список шагов, которым обычно следует любой загрузчик; это общие шаги и в зависимости от использования могут быть исключения. Обратите внимание, что процессоры x86 обычно поставляются с находящейся на плате BIOS, которая помогает с базовым включением и загрузкой вторичного загрузчика для загрузки операционной системы; так что следующий набор шагов предназначен для не x86 процессоров, таких как MIPS и ARM.

 

1.Загрузка: большинство загрузчиков стартуют из флеш-памяти. Они выполняют начальную инициализацию процессора, такую как конфигурирование кэша, настройку некоторых основных регистров, и проверяют находящееся на плате ОЗУ. Также они запускают процедуры POST, чтобы сделать проверку оборудования, необходимую для процедуры загрузки, такую как проверка памяти, флеш-памяти, шин, и так далее.

2.Перемещение в памяти: загрузчики перемещают себя в ОЗУ. Это выполняется, потому что оперативная память быстрее, чем флеш-память. Также шаг перемещения может включать в себя распаковку, так как загрузчики могут храниться в сжатом формате, чтобы сохранить дорогостоящее место для хранения.

3.Инициализация устройств: затем загрузчик инициализирует основные устройства, необходимые для взаимодействия с пользователем. Это обычно означает настройку консоли, чтобы предоставить пользователю интерфейс. Он также инициализирует устройства, необходимые для запуска ядра (и, может быть, корневую файловую систему). Это может включать флеш-память, сетевую карту, USB, и так далее.

4.Пользовательский интерфейс: после этого пользователю предоставляется интерфейс, чтобы он выбрал образ ядра для загрузки на плату. Здесь может быть указано время, предоставляемое пользователю для ввода своего выбора; в случае его превышения может быть загружен образ по умолчанию.

5.Загрузка образа: загружается образ ядра. В случае, если пользователю был дан выбор для загрузки корневой файловой системы с помощью механизма initrd, в память также загружается образ initrd.

6.Подготовка загрузки ядра: далее, в случае, если ядру должны быть переданы аргументы, заполняются аргументы командной строки и помещаются в известные для ядра Linux места.

7.Загрузка ядра: наконец, выполняется перемещение ядра. Как только запускается ядро Linux, загрузчик становится больше не нужен. Обычно память, занимаемая им, забирается ядром; настройке карты памяти ядра необходимо позаботиться об этом.

 

Общую последовательности работы загрузчика показывает Рисунок 3.2.

 

Рисунок 3.2 Последовательность запуска загрузчика.

Рисунок 3.2 Последовательность запуска загрузчика.

 

Есть много загрузчиков для Linux в свободном доступе; системный архитектор может оценить существующие, прежде чем принять решение написать с нуля новый загрузчик. Каковы критерии при выборе загрузчика для данной встраиваемой платформы?

 

Поддержка встроенного оборудования: это должно быть главным критерием. Есть много загрузчиков для настольных компьютеров, таких как LILO, которые не могут быть использованы во встраиваемых системах из-за их зависимости от BIOS ПК. Тем не менее есть и доступны некоторые универсальные встраиваемые загрузчики: в частности, U-Boot и Redboot. Ниже показаны некоторые из неуниверсальных загрузчиков, доступных для наиболее часто используемых встраиваемых процессоров:
– MIPS – PMON2000, YAMON
– ARM – Blob, Angel boot, Compaq bootldr
– X86 – LILO, GRUB, Etherboot
– PowerPC – PMON2000

Вопросы лицензирования: они подробно рассмотрены в Приложении Б.

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

Поддержка сетевой загрузки: загрузка по сети может быть необходима, особенно для отладочных сборок. Большинство популярных загрузчиков поддерживают загрузку по сети и могут поддерживать популярные сетевые протоколы, связанные с загрузкой, такие как BOOTP, DHCP и TFTP.

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

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

Доступность обновления решений: обновление решения требует наличия в загрузчике стирания флеш-памяти и программного обеспечения записи во флеш-память.

 

Ещё одной важной областью обсуждения загрузчиков является интерфейс от загрузчика к ядру, который включает в себя следующие компоненты:

 

Передача аргументов от загрузчика ядру Linux: ядру Linux, как и любому приложению, могут быть переданы аргументы в хорошо описанной форме, которые ядро анализирует, и либо само их обрабатывает, либо передаёт соответствующим драйверам или приложениям. Это очень мощное средство и оно может быть использовано для реализации обходных путей для некоторых аппаратных проблем. После того, как система полностью загрузилась, список аргументов ядра Linux во время загрузки может быть проверен чтением proc файла /proc/cmdline.
– Передача аргументов команды загрузки: аргумент команды загрузки может иметь несколько значений, разделённых запятыми. Несколько аргументов должны быть разделены пробелами. Как только весь набор построен, загрузчик должен поместить его в известные ядру Linux адреса памяти.
– Разбор аргументов команды загрузки: команда загрузки типа foo требует, чтобы в ядре была зарегистрирована функция foo_setup(). Ядро при инициализации перебирает каждый аргумент команды и вызывает соответствующую зарегистрированную функцию. Если функция не зарегистрирована, то аргумент используется как переменная окружения или передаётся задаче init.

Некоторыми важными параметрами загрузки являются:
root: определяет имя устройства, которое будет использоваться в качестве корневой файловой системы.
nfsroot: Указывает сервер NFS, каталог и параметры, которые будут использоваться в качестве корневой файловой системы. (NFS является очень мощным шагом при сборке системы Linux на начальных стадиях.)
mem: задаёт объём памяти, доступный для ядра Linux.
debug: задаёт уровень отладки для печати сообщений на консоль.

Карта памяти: на многих платформах, особенно Intel и PowerPC, загрузчики создают карту памяти, которая может быть подхвачена ОС. Это позволяет легко переносить ОС на разные платформы. Подробнее карта памяти обсуждается в следующем разделе.

Вызов из ядра подпрограмм в PROM: на многих платформах загрузчик, который выполняется из PROM, можно рассматривать как библиотеку, так что могут быть сделаны вызовы из PROM. Например, на станции DEC на основе MIPS находящиеся в PROM процедуры ввода-вывода используются для реализации консоли.

 

Предыдущая  Содержание  Следующая