Портирование мини-ОС
Процесс портирования мини-ОС осуществляется модуль за модулем, то есть для каждого модуля реализуется его платформенно-зависимая часть, затем модуль тестируется с помощью соответствующей тестовой программы, и после этого портируется следующий модуль. Такой подход позволяет значительно сократить время локализации ошибок, возникающих при портировании операционной системы.
Далее мы рассмотрим набор платформенно-зависимых макросов для каждого из модулей, перечисленных в разд. 3. Заметим, что реализация любого макроса требуется только в том случае, если модуль, использущий данный макрос, применяется в требуемой конфигурации.
Платформенно-зависимая часть модуля управления потоками включает в себя следующие макросы:
- сохранение контекста,
- восстановление контекста,
- сохранение указателя контекста
- загрузка указателя контекста.
Для реализации данных макросов необходима следующая информация:
- Структура контекста, т.е. список регисров, которые отражают состояние процесса в момент прерывания потока.
- Указатель контекста – регистр, содержащий адрес, по которому сохраняется контекст.
Очевидно, что указанные параметры уникальны для каждого конкретного процессора. Поэтому упомянутые макросы должны быть реализованы для каждого нового процессора, на который портируется ОС.
Для портирования модуля динамического распределения памяти требуется определение следующих констант:
- MMU_START_ADDR – начальный адрес динамической памяти
- MMU_WORD_SIZE – размер ячейки памяти, соответствующей единичному адресу в байтах
- MMU_PAGE_SIZE – размер страницы памяти в байтах
- MMU_NUM_PAGES – число страниц памяти, изначально доступных для динамического выделения.
Данные константы определяют адресное пространство блока динамически распределяемой памяти. Начальный адрес и размер блока определяется с учетом доступной памяти процессора, не занятой под хранение глобальных данных ОС или приложений, или памяти программ.
Для портирования модуля управления прерываниями на новую платформу необходимо реализовать следующие макросы:
- DISABLE_ALL_IRQS() – запрещает обработку всех маскируемых прерываний.
- ENABLE_ALL_IRQS() – разрешает обработку маскируемых прерываний.
- ENABLE_IRQ_N()/DISABLE_IRQ_N() – запрещает/разрешает обработку прерывания N.
- SET_PRIOR_IRQ_N(prior) – устанавливает приоритет прерывания N, если имеется программируемая система приоритетов.
Для реализации этих макросов требуется следующая информация:
- флаг «запретить все прерывания», запрещающий все прерывания в системе;
- таблица векторов прерываний;
- таблица приоритетов прерываний;
- для каждого прерывания:
- флаг, запрещающий прерывание;
- приоритет прерывания или адрес ячейки, содержащий приоритет прерывания.
Для портирования модуля синхронизационных примитивов для многопроцессорной системы требуется реализации макроса SYNC_SWAP(addr, read_val, send_val), который считывает из ячейки памяти по адресу addr значение переменной read_val и записывает значение send_val в ту же ячейку. Ключевым моментом, зависящим от особенностей целевой аппаратной платформы, является то, что в течение всего цикла чтения/записи никакой другой процессор или периферийное устройство не должны получить доступ к данной ячейке. Кроме того, требуется определение следующих констант:
- START_SYNC_RAM – стартовый адрес синхронизационной памяти.
- SIZE_SYNC_RAM – размер синхронизационной памяти (в байтах)
Заметим, что реализация макроса модуля синхронизации требуется только тогда, когда требуется поддержка межпросцессорных взаимодействий через синхронизационную память.