Изучаем архитектуру Intel x86-64 при помощи ассемблера (Часть 2 — Настройка проекта osdevlearning)

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

  1. Я создал удаленный репозиторий под названием osdevlearning. О том, как создать репозиторий, я рассказывал здесь.
  2. В папке своего локального репозитория osdevlearning я создаю папку HelloWorld_RealMode. В эту папку я помещу файлы программы HelloWorld, описанной в предыдущей заметке. В дальнейшем для каждой новой программы я буду создавать отдельную папку в папке osdevlearning.
  3. В папке osdevlearning я создаю файл .gitignore, в который записываю расширения тех файлов, которые не хочу добавлять в систему управления версиями — это двоичные файлы, генерируемые ассемблером FASM и утилитой dd. Они имеют расширения .bin и .img соответственно.

Что за файлы я собираюсь добавить в папку HelloWorld_RealMode? Вот они (такое вот красивое дерево генерирует программа tree в среде Cygwin):

osdevlearning
├── HelloWorld_RealMode
│   ├── bochsrc.bxrc
│   ├── boot_sector.asm
│   └── makefile
└── README.txt
  • boot_sector.asm — исходный код программы HelloWorld. Я обозвал его так потому, что он представляет собой содержимое загрузочного сектора дискеты, с которой будет грузиться наша виртуальная машина.
  • bochsrc.bxrc — файл настроек виртуальной машины Bochs, который содержит информацию о том, что в системе есть дисковод гибких дисков, и что в этот дисковод вставлена дискета, и где на находится образ этой дискеты. Каждая новая программа, которую я буду писать будет иметь такой вот файл bochsrc.bxrc. Двойным щелчком по этому файлу я смогу запускать программу на выполнение. Файл bochsrc.bxrc содержит помимо прочего одну важную строку:

    floppya: type=1_44, 1_44="floppy.img", status=inserted, write_protected=0

    floppy.img — это имя файла образа загрузочной дискеты, который находится в той же папке, что и bochsrc.bxrc. Это важно, что в той же папке, так как путь к файлу floppy.img здесь указан относительно той папки, где находится bochsrc.bxrc.

  • makefile — текстовый файл, который содержит инструкции, которые запускают ассемблер FASM и утилиту dd.

О файле makefile стоит поговорить подробнее. Это специальный файл, который содержит инструкции по построению нашего проекта. Выполняет эти инструкции утилита make, которая входит в состав среды Cygwin. Существует аналогичная утилита от Microsoft, которая входит в состав Windows SDK и называется nmake. Когда вы запускаете утилиту make, она ищет в текущей папке файл под названием makefile. Найдя его, она начинает выполнять записанные в нем инструкции. Содержимое файла makefile имеет специальный формат. Дело в том, что в проекте файлы зависят друг от друга. Поясню на примере. Вначале у меня есть файл исходного кода boot_sector.asm — я создаю его сам. Затем при помощи ассемблера FASM я генерирую из файла boot_sector.asm файл boot_sector.bin. Затем при помощи утилиты dd я генерирую из файла boot_sector.bin файл floppy.img. Таким образом, файл floppy.img зависит от файла boot_sector.bin, а файл boot_sector.bin зависит от файла boot_sector.asm. Если изменился исходный код в файле boot_sector.asm, то нужно обновить (путем запуска программ FASM и dd) файлы boot_sector.bin и floppy.img. Если же, допустим, изменился файл boot_sector.bin, то надо обновить только файл floppy.img (путем запуска программы dd). Структура файла makefile отражает эти зависимости между отдельными файлами:

файл1 : файл2 файл3
    инструкция1
    инструкция2
    инструкция3

файл2 : файл4 файл5 файл6
    инструкция4
    инструкция5
    инструкция6

В приведенном примере файл 1 зависит от файлов 2 и 3, а файл 2 зависит от файлов 4, 5 и 6. Если изменится файл 3, то утилита make запустит инструкции 1, 2 и 3, а если изменится, скажем, файл 6, то make запустит инструкции 4, 5, 6, а потом 1, 2 и 3.
makefile в папке HelloWorld_RealMode выглядит вот так:

floppy.img : boot_sector.bin
    dd if="/dev/zero" of="floppy.img" bs=1024 count=1440
    dd if=boot_sector.bin of=floppy.img conv=notrunc

boot_sector.bin : boot_sector.asm
    fasm boot_sector.asm boot_sector.bin

Всё. В следующей заметке переведем процессор в защищенный режим и выведем на экран сообщение «Hello World!» уже из защищенного режима.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *