Наши партнеры

UnixForum





Библиотека сайта rus-linux.net

Руководство по созданию простой UNIX-подобной ОС

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

Оригинал: "1. Environment setup"
Автор: James Molloy
Дата публикации: 2008
Перевод: Н.Ромоданов
Дата перевода: январь 2012 г.

Нам нужна среда, в которой мы будем проектировать и собирать наше ядро. Везде далее предполагается, что вы пользуетесь системой *nix и инструментарием GNU. Если вы хотите использовать систему windows, вы должны либо воспользоваться пакетом cygwin (который является средой, эмулирующей *nix), либо DJGPP. В случае, если используется windows, файлы make и команды, приведенные в настоящем руководстве, могут не работать.

1.1. Структура директориев

Структура моих директориев следующая:
tutorial
 |
 +-- src
 |
 +-- docs 

Все ваши файлы с исходным кодом будут находиться в директории src, а вся ваша документация (вы пишите документацию?) должна быть в директории docs.

1.2. Компиляция

Примеры, приведенные в этом руководстве, должны успешно компилироваться с помощью инструментария GNU (gcc, ld, gas и т.д.). примеры на ассемблере написаны с использованием синтаксиса Intel, который более удобен (мое личное мнение), чем синтаксис, используемый в GNU AS. Чтобы выполнять ассемблирование, вам нужен Расширенный ассемблер.

В этом руководстве не описывается разработка загрузчика. Для загрузки нашего ядра мы будем пользоваться загрузчиком GRUB. Чтобы это делать, нам нужен образ дискеты с предустановленным в нем загрузчиком GRUB. Есть руководства, в которых описывается, как это делать, но, к счастью, я взял стандартный образ, который можно найти здесь. Он должен находиться в вашем директории 'tutorial' (или в главном директории проекта с тем названием, которое вы ему дали).

1.3. Запуск на исполнение

В качестве тестовой системы нет альтернативы чистому аппаратному железу. К сожалению, чистое аппаратное железо не так привлекательно, когда что-то идет не так (но вы, разумеется, собираетесь писать код сразу абсолютно без ошибок, не так ли?). Возьмите эмулятор Bochs. Bochs является эмулятором для платформы x86-64 с открытым исходным кодом. Когда дела пойдут совсем не так, как надо, эмулятор bochs сообщит вам об этом и сохранит состояние процессора в журнальном файле, что чрезвычайно полезно. Кроме того, его можно запустить и перезагрузить гораздо быстрее, чем реальную машину. Мои примеры будут сделаны так, чтобы они хорошо работали под эмулятором bochs.

1.4. Эмулятор Bochs

Для того, чтобы запустить эмулятор bochs, вам нужен конфигурационный файл bochs (bochsrc.txt). Так получилось, что в качестве образца конфигурационного файла можно взять файл, приведенный ниже!

Обратите внимание на то, где находятся файлы bios. Возможно, они используются для переключения между вариантами настройки, и если вы собираете bochs из исходных кодов, то весьма возможно, что их у вас вообще не будет. Поищите их в Google по их названиям, их можно, среди прочего, получить с официального сайта bochs.

megs: 32
romimage: file=/usr/share/bochs/BIOS-bochs-latest, address=0xf0000
vgaromimage: /usr/share/bochs/VGABIOS-elpin-2.40
floppya: 1_44=/dev/loop0, status=inserted
boot: a
log: bochsout.txt
mouse: enabled=0
clock: sync=realtime
cpu: ips=500000 

В этом файле указывается, что bochs эмулирует машину с оперативной памяти объемом в 32 MB и тактовой частотой, эквивалентной компьютеру PentiumII с тактовой частотой 350MHz. Можно увеличить число инструкций, исполняемых в секунду, но я предпочитаю медленную скорость эмуляции, просто так я могу следить за тем, как обрабатываются тексты большого размера.

1.5. Полезные скрипты

Мы собираемся выполнять некоторые действия очень часто - создавать (компилировать и компоновать) наш проект и переносить получившийся в результате двоичный код ядра в наш образ дискеты

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

1.5.1. Скрипт Makefile

# Makefile для руководств по сборке ядра - автор James Molloy.
# Правила обработки C и C++ указаны как используемые по умолчанию.
# Единственное, что нужно изменить, это указать правила обработки 
# ассемблера, поскольку мы используем nasm вместо GNU as.

SOURCES=boot.o

CFLAGS=
LDFLAGS=-Tlink.ld
ASFLAGS=-felf

all: $(SOURCES) link 

clean:
 »  -rm *.o kernel

link:
 »  ld $(LDFLAGS) -o kernel $(SOURCES)

.s.o:
 »  nasm $(ASFLAGS) $< 

С помощью этого файла Makefile все файлы, находящиеся в директории с исходными кодами, будет компилироваться, а затем будут компоноваться вместе в один двоичный файл в формате ELF с названием 'kernel'. Для этого в нем используется скрипт компоновщика 'link.ld':

1.5.2. Скрипт Link.ld

/* Link.ld -- скрипт компоновщика ядра - проследите за тем, чтобы */
/*            это выполнялось в правильном месте.  */
/*            Исходный файл был взят из руководства по разработке ядра Bran's  */
/*            Kernel Development: http://www.osdever.net/bkerndev/index.php. */

ENTRY(start)
SECTIONS
{
  .text 0x100000 :
  {
    code = .; _code = .; __code = .;
    *(.text)
    . = ALIGN(4096);
  }

  .data :
  {
     data = .; _data = .; __data = .;
     *(.data)
     *(.rodata)
     . = ALIGN(4096);
  }

  .bss :
  {
    bss = .; _bss = .; __bss = .;
    *(.bss)
    . = ALIGN(4096);
  }

  end = .; _end = .; __end = .;
} 

В этом скрипте загрузчику LD указывается, как настроить наш образ ядра. Во-первых, в нем с помощью символа 'start' загрузчику LD указывается, что наш двоичный файл располагается в самом начале. Затем в нем загрузчику LD сообщается, что секция .text (где находится весь ваш код), которая должна идти первой, должна начинаться с адреса 0x100000 (1 Мб). Следующими должны быть секции .data (инициализированные статические данные) и .bss (неинициализированные статические данные), причем каждая секция должна быть выровнена относительно начала страницы (ALIGN (4096)). Компилятор Linux GCC также добавляет дополнительную секцию данных .rodata, которая используется для инициализированных данных, таких как константы. Для простоты мы их просто помещаем в секцию .data.

1.5.3. Скрипт update_image.sh

Приятный небольшой скрипт, который будет перемещать новое двоичное ядро в файл образа дискеты (предполагается, что вы это делаете в директории /mnt). Примечание: чтобы использовать команду losetup, вам нужно указать путь к директорию /sbin в переменной среды окружения $PATH.

#!/bin/bash

sudo losetup /dev/loop0 floppy.img
sudo mount /dev/loop0 /mnt
sudo cp src/kernel /mnt/kernel
sudo umount /dev/loop0
sudo losetup -d /dev/loop0 

1.5.4. Скрипт run_bochs.sh

Этот скрипт настройки устройства loopback, запустите на нем эмулятор bochs, а затем отключите это устройство.

#!/bin/bash

# run_bochs.sh
# правильно монтирует устройство loopback, запускает bochs, а затем демонтирует устройство.

sudo /sbin/losetup /dev/loop0 floppy.img
sudo bochs -f bochsrc.txt
sudo /sbin/losetup -d /dev/loop0 

Назад К началу Вперед