Введение
В этой серии статей в блоге объясняется, как я разработал свою первую маленькую операционную систему. Поскольку это сложная задача, я загрузил их в виде нескольких глав. В этой статье я расскажу, как мы можем настроить нашу среду разработки и как загрузить маленькую операционную систему.
Инструменты, которые я использовал
Прежде чем начать, позвольте мне поделиться инструментами, которые я использовал для написания своей первой ОС.
- Основная операционная система. В качестве основной операционной системы я использую Ubuntu (20.04.5). Всегда рекомендуется устанавливать хост-ОС на виртуальную машину, например VirtualBox, чтобы протестировать вашу ОС.
2. Пакеты. После установки и запуска ОС Ubuntu следующие пакеты необходимо установить с помощью терминала. (Используйте команду ниже)
sudo apt-get install build-essential nasm genisoimage bochs bochs-sdl
3. Языки программирования. Я использовал язык программирования C с компилятором gcc для разработки своей ОС.
И использование NASM в качестве ассемблера для написания ассемблерных кодов.
В качестве языка сценариев будет использоваться Bash.
Процесс загрузки
Чтобы создать операционную систему, важно понять, как она загружается. Давайте посмотрим на процесс загрузки ОС.
Процесс загрузки операционной системы включает в себя передачу управления через ряд небольших программ, каждая из которых более мощная, чем предыдущая. Основные программы в этом процессе включают BIOS, Bootloader и ОС. Операционная система является последней и самой мощной.
BIOS — когда компьютер включается, запускается небольшая программа, соответствующая стандарту базовой системы ввода-вывода (BIOS). Эта программа обычно хранится на материнской плате ПК в микросхеме постоянной памяти. Прежде чем передать управление загрузчику, BIOS прежде всего выполняет раннюю диагностику.
Загрузчик —программа BIOS передает управление компьютером программе загрузчика. Задача загрузчика — передать управление операционной системе. Однако из-за аппаратных и других ограничений загрузчик обычно делится на две части. В этом случае первая часть загрузчика передаст управление второй части, которая в конечном итоге передаст управление ОС.
ОС.Переходя к ячейке памяти, GRUB передает управление операционной системе. GRUB будет искать магическое число перед переходом, чтобы гарантировать, что он переходит к ОС, а не к какому-то произвольному коду. Спецификация мультизагрузки, которой соответствует GRUB, включает это магическое число. Как только GRUB завершит переход, ОС получает полный контроль над компьютером.
Теперь давайте приступим к разработке самой простой из возможных операционных систем. Единственное, что будет делать эта ОС, — это записывать 0xCAFEBABE в регистр EAX.
Написание и компиляция
Этот раздел ОС должен быть разработан на языке ассемблера. Мы не можем использовать язык C, так как для этого требуется стек, которого нет.
Сначала создайте каталог (папку) с именем «JA-OS» и сохраните все свои успехи в этом каталоге.
Откройте текстовый редактор и сохраните приведенный ниже код и сохраните его как «loader.s».
Единственное, что будет делать эта ОС, — это записывать очень конкретное число 0xCAFEBABE в регистр EAX. Мы можем проверить, был ли номер успешно записан в реестр, после загрузки ОС.
Теперь откройте терминал внутри вашего каталога «ОС».
Затем используйте следующую команду, чтобы скомпилировать loader.s в 32-битный объектный файл ELF. (Используйте следующую команду).
nasm -f elf32 loader.s
Связывание
После компиляции кода его необходимо слинковать для создания исполняемого файла. Поскольку адреса менее 1 мегабайта (МБ) используются GRUB, BIOS и вводом-выводом с отображением памяти, мы хотим, чтобы GRUB загружал ядро по адресу памяти, большему или равному 0x00100000 (1 МБ). Мы можем использовать следующий скрипт в качестве компоновщика.
Создайте текстовый файл с именем «link.ld» с помощью приведенного выше скрипта компоновщика. Используя следующую команду, теперь вы можете связать исполняемый файл:
ld -T link.ld -melf_i386 loader.o -o kernel.elf
Теперь вы должны увидеть файл с именем «kernel.elf», который является окончательным исполняемым файлом.
Получение GRUB
Мы будем использовать GRUB Legacy stage2_eltorito в качестве загрузчика для реализации. Бинарный файл для вышеупомянутого загрузчика можно скачать по следующей ссылке.
https://github.com/SeyonSuriya/JA-OS/blob/main/phase_1/stage2_eltorito
Скопируйте файл stage2_eltorito в свой рабочий каталог.
Создание образа ISO
Исполняемый файл должен храниться на носителе, который может прочитать виртуальная или физическая машина. Для этого мы будем использовать файлы образов ISO в нашем проекте. Мы можем использовать программу genisoimage для создания образа.
Должна быть создана папка, содержащая файлы, которые будут в образе ISO. Используйте следующие команды, чтобы создать папку и скопировать файлы
в нужные места:
mkdir -p iso/boot/grub # create the folder structure cp stage2_eltorito iso/boot/grub/ # copy the bootloader cp kernel.elf iso/boot/ # copy the kernel
Затем создайте файл конфигурации GRUB с именем ‘menu.lst’. Этот файл должен указать GRUB, где найти ядро и установить различные параметры. Используйте следующую конфигурацию файла:
Поместите файл ‘menu.lst’в папку ‘iso/boot/grub/’. Теперь папка‘iso’должна иметь следующую структуру:
Затем используйте следующую команду для создания iso-файла.
genisoimage -R \ -b boot/grub/stage2_eltorito \ -no-emul-boot \ -boot-load-size 4 \ -A os \ -input-charset utf8 \ -quiet \ -boot-info-table \ -o os.iso \ iso
Будет создан файл с именем os.iso. Он содержит исполняемый файл ядра, загрузчик GRUB и файл конфигурации.
Запускаем нашу ОС с помощью Bochs
Теперь, используя ISO-образ os.iso, мы можем загрузить нашу ОС в эмуляторе Bochs. Чтобы начать работу с Bochs, вам понадобится файл конфигурации. Ниже приведен простой файл конфигурации.
В зависимости от того, как вы установили Bochs, вам может потребоваться изменить путь к romimage и vgaromimage. Вы можете обратиться к официальному веб-сайту Boch, чтобы узнать больше о конфигурации Boch. Сохраните файл конфигурации как ‘bochsrc.txt’ и запустите Bochs с помощью следующей команды:
bochs -f bochsrc.txt -q
Тогда вы можете видеть, как это,
Дайтепродолжить на терминале (нажмите Enter)
После этого вы можете видеть,
Теперь Bochs должен работать и отображать консоль с некоторой информацией о ней. Выйдите из Bochs и отобразите журнал, созданный Bochs, с помощью следующей команды:
cat bochslog.txt
Содержимое регистров ЦП, реплицированных Bochs, теперь должно появиться где-то в выводе. Ваша ОС успешно загрузилась, если в выводе вы видите RAX=00000000CAFEBABE или EAX=CAFEBABE.
Поздравляем! Мы только что создали простую операционную систему. На следующей неделе мы увидим, как мы можем получить помощь языка программирования C для дальнейшей разработки нашей ОС.
Проверьте мой Репозиторий GitHub для получения исходного кода.
Ссылки:
Маленькая книга по ОС: https://littleosbook.github.io/book.pdf