Rambler's
Top100

Итак, вы хотите разработать собственную ОС?

Автор: Patrick Mahoney
Дата: .03.2003
Раздел: Низкоуровневое программирование в Linux

Вступление

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

Несколько статей связанные с этой темой появились в недавних выпусках Linux Gazette. Я планирую подойти к проблеме с менее "программистки-ориентированной" стороны, предоставляя читателю только инструменты и советы, в которых он нуждается. Предполагается, что ознакомившись со статьей, заинтересовавшийся читатель сумеет начать придумывать и воплощать свои идеи разработки ОС в программный код, будучи ознакомленным с тем, какую именно информацию ему нужно будет искать.

Вы можете не знать этого, но разработка операционной системы начинается не в начале (!!). Разработка приличного загрузчика - проект сам по себе очень сложный, и я бы не советовал вам начинать разработку с написания загрузчика. Множество очень хороших и надежных загрузчиков свободно доступно (Grub, lilo, ppcboot, etc...). Если вы все таки планируете написать собственный, я советую вам повременить с этим. В этой статье я буду использовать GNU Grub, Grand Unified Bootloader.

Описание разработки

Дабы облегчить трудности разработки ОС, вам понадобится:
- Возможность *быстро* тестировать ядро
- Возможность *НЕ* перезагружать компьютер, на котором будет происходить разработка
- Возможность *НЕ* использовать дискеты при тестировании системы

Эта статья познакомит вас с одним из возможных вариантов рзаработки, который соотвествует всем вышестоящим требованиям. Этот вариант состоит из компьютера, на котором будет происходить разработка и "подопытного" компьютера, на котором будет происходить тестирования. Эти компьютеры должны находиться в одной сети.

2.1 Компьютер разработчика

Как и следовало ожидать, эта машина должна иметь хороший комплект средств разработки: ассемблер, компилятор Си, компоновщик и утилита "Make" - необходимый минимум.

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

Еще вам понадобится сервер TFTP. Он позволит подопытной машине загружать ядро с компьютера разработчика по сети.

2.2 Подопытный компьютер

Все что ему нужно - сетевая карта и загрузчик, который поддерживает протокол TFTP.

3. Настройка среды разработки

3.1 Компьютер разработчика

Выбранные мною инструменты:

- gcc 2.95.4
- ld 2.13.90.0.10
Bochs версии 1.4.1 выбран как эмулятор. Важно скомпилировать с поддержкой режима отладки. Это можно сделать командами:
$ ./configure --enable-x86-debugger
$ make

Для того, чтобы использовать Bochs, вам понадобится образ диска. Он должен иметь загрузчик и файловую систему. Это можно сделать используя скрипт mkbimage. В качестве TFTP сервера я выбрал atftpd. Это легкий в использовании сервер для linux.

3.2 Подопытный компьютер

Выбранный загрузчик - GNU Grub 0.92. Важно скомпилировать его с поддержкой tftp для вашей сетевой карты. Обязательно внимательно прочитайте инструкции в файлах netboot и README.netboot. У меня стоит дешевый клон NE2000 ISA и я использовал вот эти команды:
$ ./configure --enable-ne --enable-ne-scan=0x220
$ make

Примечание: сконфигурировать нормальную PnP PCI карту будет проще. Теперь вы можете либо установить образы дисков Grub на MBR машины либо на дискету, с которой она будет грузиться. Я предпочел второй вариант, т.к. мой компьютер используются также и для других целей и я не рискнул играться с жестким диском.
$ cat ./stage1/stage1 ./stage2/stage2 > /dev/fd0
Теперь попробуйте загрузиться с дискеты, чтобы проверить распозналась ли сетевая карта. Вы можете либо сконфигурировать ее вручную либо использовать dhcp сервер (если таковой имеется в сети).
grub> dhcp
Probing... [NE*000]
NE2000 base 0x220, addr 00:C0:A8:4E:5A:76
Address: 192.168.22.14
Netmask: 255.255.255.0
Server: 192.168.22.1
Gateway: 192.168.22.1

Примечание: необязательно каждый раз при загрузке конфигурировать эти параметры. Смотрите документацию GNU Grub и скрипт 'grub-install'.
Все готово для того, чтобы протестировать установку!

4. Тестирование среды разработки...

Как я указал раньше, я оставил собственно программирование ОС экспертам. Так что для того, чтобы протестировать Grub, я использовал примерное ядро из его поставки, расположенное в директории /docs. Оно собирается из трех файлов: boot.S, kernel.c и multiboot.h. То есть собрать его можно командами:
$ gcc -I. -c ./boot.S
$ gcc -I. -c ./kernel.c
$ ld ./kernel.o ./boot.o -o kernel -Ttext 100000

Вот быстрое и неполное разъяснение: Multiboot - стандарт, который определяет путь передачи информации от загрузчика к загружаемому ядру. boot.S принимает эту информацию, устанавливает стек и вызывает функцию 'cmain'. Эта функция настраивает VGA, читает переданную ей информацию выводит на экран текст и завершается. После этого boot.S получает управление обратно, выводит строку 'Halted.' и входит в бесконечный цикл. Весьма просто? Читателю предлагается самостоятельно исследовать этот код для выяснения деталей

4.1 Bochs

План таков: примонтировать образ диска как loopback устройство, скопировать ядро на него, отмонтировать и запустить Bochs. Конечно, вам понадобиться добавить смещение на начало ФС. Но вы знаете его, не так ли?
# /sbin/losetup -o 32256 /dev/loop1 ./c.img
# /bin/mount -t ext2 /dev/loop1 /mnt/osdev/
# cp /docs/kernel /mnt/osdev
# umount /mnt/osdev/
# /sbin/losetup /dev/loop1 -d
$ bochs
Конечно, ваш Makefile может это автоматизировать. Как только вы окажетесь в Grubпросто наберите: grub> kernel (hd0,0)/kernel
grub> boot

4.2 Подопытный компьютер

Сперва установите TFTP сервер, так что клиент сможет получать с него ядро.
# /usr/sbin/atftpd --daemon /home/bono/src/grub-0.92/docs
Запускайте подопытную машину. Сконфигурируйте сеть как показано выше. Затем, укажете IP адрес основного компьютера и местонахождение образа ядра. Примечание: эта информация может быть установлена dhcp сервером. И наконец, запустите процесс загрузки:
(...)

grub> tftpserver 192.168.22.36
Address: 192.168.22.14
Netmask: 255.255.255.0
Server: 192.168.22.36
Gateway: 192.168.22.1

grub> kernel (nd)/kernel
[Multiboot-elf, <0x100000:0x807:0x0>, <0x101808:0x0:0x4018>,
shtab=0x106190, entry=0x100568]

grub> boot

Что дальше?

Вы уже достаточно далеко продвинулись и настроены начать разработку собственной ОС? Ищите в интернете, спрашивайте, думайте... Монолитное или микроядро? Сегментация или страничная адресация? ...

Если возможности отладки, предоставляемые эмулятором и функцией printk недостаточны, вы можете использовать последовательный отладчик, который подключается через COM-порт. Это достаточно часто используется при разработке ОС.

6. Ресурсы

7. Thanks

Большое спасибо тем, кто терпеливо отвечал на мои непрекращающие вопросы на #osdev:: pavloskii, geist, oink, byrdkernel, air.

Перевод © 2003 Lonesome


Copyright © 2002, Patrick Mahoney. Copying license http://www.linuxgazette.com/copying.html
Published in Issue 85 of Linux Gazette, December 2002


Rambler's Top100