§ Введение

Привет! Я создаю операционные системы еще с пелёнок и так до сих пор ни одной путной не создал. Ближе к делу. Я хочу создать небольшой так называемый monitor, чтобы запускать на реальной машине программы из реального режима работы процессора. Почему не из защищенного? Можно и из защищенного, но оттуда не будет доступен диск, а он мне нужен. К тому же это проще создать. Возможно, когда-нибудь я и буду делать цикл статей по созданию ОС в защищенном режиме, но он мне сейчас вообще никак не сдался, ибо цель простая - написать попроще, и чтобы оно хотя бы как-то работало. Программировать конечно же, буду на ассемблере fasm.

§ Установка bochs

Мне, в принципе, нравится постоянно ставить bochs. Все это надо делать в linux, на винде я без понятия как собрать bochs из исходников. Конечно, можно пользоваться и тем, что в винде дается, но мне неудобно командной строкой там во встроенном странном отладчике ковыряться, тем более я в linux сижу.
Исходные коды bochs 2.6.11 можно скачать по этой ссылке.
Чтобы bochs удачно установился, обязательно нужно установить следующие пакеты
1apt install gcc g++ libsdl1.2-dev gtk2.0-dev libgtk2.0-dev libx11-dev libxrandr-dev make
Переходим в папку с кодами bochs и вводим следующую команду
1./configure --enable-x86-64 --enable-debugger --enable-disasm --enable-readline --with-all-libs --with-x11 && \
2make && \
3sudo make install
Если ошибки не вышло, все в порядке и можно пользоваться bochs.

§ Установка через Dockerfile

Можно еще даже попробовать поставить bochs через docker. Dockerfile такой:
1FROM ubuntu:latest
2ENV DEBIAN_FRONTEND=noninteractive
3ADD 'bochs-2.6.11.tar.gz' /bochs/
4RUN apt-get update && \
5    apt-get install -y mc gcc g++ libsdl1.2-dev gtk2.0-dev libgtk2.0-dev \
6    libx11-dev libxrandr-dev make && \
7    useradd -ms /bin/bash [user]
8
9RUN cd '/bochs/bochs-2.6.11' && \
10    ./configure --enable-x86-64 --enable-debugger --enable-disasm --enable-readline --with-all-libs --with-x11 && \
11    make
12
13RUN cd '/bochs/bochs-2.6.11' && make install
Но это какое-то реальное извращение. А вот и скрипт для создания временного контейнера.
1# Создать образ
2	docker build -t bochs .
3
4# Создать контейнер
5	docker run --rm --user ${USER} --name bochs-cont -h hostbochs \
6	--net host \
7	-w /home/{$USER} \
8	-e DISPLAY=${DISPLAY} \
9	-v /tmp/.X11-unix:/tmp/.X11-unix \
10	-v ${PWD}/home:/home/${USER} \
11	-ti bochs bochs

§ Конфигурационный файл

После всех перипетии надо настроить конфигурационные файлы. Можно воспользоваться тем, что у меня есть:
1# configuration file generated by Bochs
2plugin_ctrl: unmapped=1, biosdev=1, speaker=1, extfpuirq=1, parallel=1, serial=1, iodebug=1
3config_interface: textconfig
4display_library: x, options="gui_debug"
5memory: host=32, guest=32
6romimage: file="/usr/local/share/bochs/BIOS-bochs-latest", address=0x0, options=none
7vgaromimage: file="/usr/local/share/bochs/VGABIOS-lgpl-latest"
8boot: disk
9floppy_bootsig_check: disabled=0
10# no floppya
11# no floppyb
12ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
13ata0-master: type=disk, path="disk.img", mode=flat, cylinders=0, heads=0, spt=0, model="Generic 1234", biosdetect=auto, translation=auto
14ata0-slave: type=none
15ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15
16ata1-master: type=none
17ata1-slave: type=none
18ata2: enabled=0
19ata3: enabled=0
20optromimage1: file=none
21optromimage2: file=none
22optromimage3: file=none
23optromimage4: file=none
24optramimage1: file=none
25optramimage2: file=none
26optramimage3: file=none
27optramimage4: file=none
28pci: enabled=1, chipset=i440fx
29vga: extension=vbe, update_freq=5, realtime=1
30cpu: count=1, ips=4000000, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0
31cpuid: level=6, stepping=3, model=3, family=6, vendor_string="GenuineIntel", brand_string="Intel(R) Pentium(R) 4 CPU"
32cpuid: mmx=1, apic=xapic, simd=sse2, sse4a=0, misaligned_sse=0, sep=1, movbe=0, adx=0
33cpuid: aes=0, sha=0, xsave=0, xsaveopt=0, x86_64=1, 1g_pages=0, pcid=0, fsgsbase=0
34cpuid: smep=0, smap=0, mwait=1
35print_timestamps: enabled=0
36debugger_log: -
37magic_break: enabled=1
38port_e9_hack: enabled=0
39private_colormap: enabled=0
40clock: sync=none, time0=local, rtc_sync=0
41# no cmosimage
42# no loader
43log: -
44logprefix: %t%e%d
45debug: action=ignore
46info: action=report
47error: action=report
48panic: action=ask
49keyboard: type=mf, serial_delay=250, paste_delay=100000, user_shortcut=none
50mouse: type=ps2, enabled=0, toggle=ctrl+mbutton
51speaker: enabled=1, mode=system
52parport1: enabled=1, file=none
53parport2: enabled=0
54com1: enabled=1, mode=null
55com2: enabled=0
56com3: enabled=0
57com4: enabled=0
В этом файле много настроек, но главные из них вот такие:
  • display_library: x, options="gui_debug" - позволяет пользоваться нормальным отладчиков
  • ata0-master: type=disk, path="disk.img" - подключает диск disk.img
  • boot: disk - делает его запускным
  • magic_break: enabled=1 - возможность остановки на инструкции XCHG BX, BX
Этот файл можно скачать c.bxrc.
Теперь же можно легко запускать вот таким вот образом:
1bochs -f c.bxrc -q
Но только без образа диска будет выдавать ошибку.

§ Разметка диска

Первым делом, надо создать диск размером к примеру 256 мегабайт
1dd if=/dev/zero of=disk.img bs=1024 count=262144
Потом зайти в утилиту разметки дисков
1fdisk disk.img
И там внести следующие изменения, выполнить последовательность операции
Команда (m для справки): n
Partition type:

  p   primary (0 primary, 0 extended, 4 free)
  e   расширенный

Select (default p): p
Номер раздела (1-4, по умолчанию 1): 1
Первый сектор (2048-524287, по умолчанию 2048): 2048
Последний сектор, +секторы or +size{K,M,G} (2048-524287, по умолчанию 524287): 524287
Сменить тип раздела "t" (по умолчанию "1" - номер раздела), ввести "0B" - W95 FAT32
Сохранить и выйти - "w"
Смонтировать раздел 1 (здесь 1048576 = 512 * 2048)
sudo losetup -o 1048576 /dev/loopX disk.img
Создать файловую систему FAT32 на 1-м разделе (-F16 для FAT16)
sudo mkfs.fat -F32 /dev/loopX
Размонтировать
sudo losetup -d /dev/loopX
Создать виртуальный путь к диску, если нет (если что, путь к диску можно поменять)
mkdir disk
Смонтировать диск к определенному каталогу
sudo mount disk.img -t vfat -o loop,rw,uid="`whoami`",sync,offset=$[1048576] disk/
Там где whoami - вместо этого вписать имя пользователя, для которого этот диск должен быть доступен. А также loopX - номер свободного loop-device, можно посмотреть через df -h
Если всё пройдёт успешно, то диск будет нормально создан, и готов к записи.

§ Создание floppy.img

Создать диск
1dd if=/dev/zero of=floppy.img bs=512 count=2880
Присоединить
1losetup -o 0 /dev/loopX floppy.img
Создать FAT12
1mkfs.fat -F12 /dev/loopX
Отсоединить
1losetup -d /dev/loopX
Присоединить как loop-device:
1sudo mount floppy.img -t vfat -o loop,rw,uid="`whoami`",sync,offset=$[0] floppy
Вот теперь можно пользоваться и флоппи-диском, и жестким диском. Далее я буду использовать только жесткий диск, поскольку только он может позволить мне загружать систему с флешки. Иначе никак.