Введение

В этой серии статей в блоге объясняется, как я разработал свою первую маленькую операционную систему. Поскольку это сложная задача, я загрузил их в виде нескольких глав. В этой статье я расскажу, как мы можем настроить нашу среду разработки и как загрузить маленькую операционную систему.

Инструменты, которые я использовал

Прежде чем начать, позвольте мне поделиться инструментами, которые я использовал для написания своей первой ОС.

  1. Основная операционная система. В качестве основной операционной системы я использую 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