Автор: lonesome
TSH/Digital Daemons
Дата: 24.03.2003
Раздел:
HAL в переводе на великий и могучий означает "cлой абстракции от аппаратуры". То
есть предназначен он для того, чтобы свежеразработанную ОС можно было без особых
проблем портировать на другие архитектуры при этом лишь замененив HAL и
перекомпилировав исходные коды. К примеру в HAL можно (нужно!) разместить
низкоуровневый менеджер памяти, с помощью которого осуществляется постраничное
выделение физической памяти и организация виртуального адресного пространства. В таком
случае ядру разрабатываемой ОС совершенно не нужно будет знать об аспектах организации
страничной адресации на конкретной архитектуре (будь то x86, M68000 или MIPS32), все
что будет ему известно - это абстрактные функции вроде alloc_page(),
free_page() и подобные. Эта абстрактность позволит нам без
изменений использовать ядро ОС на любых архитектурах.
Возникает идея: если само ядро не привязано к конкретной архитектуре, а взаимодействует с аппаратурой через набор функций HAL, то можно создать так называемый host-based HAL, который будет выполняться в виде приложения в какой-либо операционной системе. По сути своей, виртуальные машины вроде Bochs или VMWare Workstation представляют собой именно host-based HAL, правда сильно усложненный (они выполняют не какие-то функции ОС, а весь набор операций процессора).
Сейчас мы в качестве примера рассмотрим мини-ОС и два HAL'а к ней - один host-based, а второй - аппаратный для архитектуры x86. Вы увидите, как с легкостью одни и те же исходные коды можно скомпилировать и как для выполнения в некой виртуальной машине, и как для выполнения на "голом" процессоре.
Для начала определимся, какие функции будет выполнять наша мини-ОС. Поскольку
усложнить структуру ОС мы успеем всегда, для начала дадим ей две простых и в
большинстве случаев необходимых функции:
1. Вывод на экран
2. Обработка прерываний
Исходя из функций ОС, интерфейс ядра ОС с HAL будет осуществляться через следующие
функции:
kputchar(char c) - вывод символа на экран
kclear() - очистка экрана
register_handler(int vector, void *func) - регистрация функции func() в качестве обработчика прерывания под
номером vector
register_irq_keyboard(void *func) - регистрация функции func(char
c) в качестве обработчика прерывания клавиатуры (эта функция принимает параметр
- нажатый символ)
raise_interrupt(int vector) - программный вызов прерывания под номером
vector
enable_interrupts() - разрешение обработки прерываний
disable_interrupts() - запрещение обработки прерываний
Перечисленные выше функции находятся в HAL и, следовательно, именно их реализация
меняется в каждом конкретном случае и для каждой конкретной архитектуры.
Само мини-ядро может выглядеть вот таким образом:
void receive_keypress(char c);
void irq_timer(void);
//HAL вызывает эту функцию после инициализации аппаратной части
void system_main()
{
kclear();
kputs("Hello from HAL based OS Demo\n");
register_handler(0x20, irq_timer);
register_irq_keyboard(receive_keypress);
enable_interrupts();
}
//Вывод строки
void kputs(char *string)
{
while(*string){
kputchar(*string);
string++;
}
}
void receive_keypress(char c)
{
kputs("You have pressed: ");
kputchar(c);
kputchar('\n');
}
void irq_timer()
{
}
Исходники host-based HAL'а для этой ОС находятся здесь: host_based_hal.tar.gz.
В качестве хостовой ОС для него используется Linux, ибо, по выражению одного человека,
остальное все от лукавого :). Полученные объектные файлы HAL'а необходимо слинковать с
получившимся из вышеприведенного листинга объектным файлом ядра kernel.o и после
требуемой инициализации HAL передаст управление ядру системы (а конкретно функции
system_main())