Совсем недавно на хабре появилась следующая новость: На GitHub опубликован исходный код MS-DOS 4.00 под лицензией MIT. Раз появились исходные коды, стало сразу интересно: а можно ли собрать эту операционную систему?
Задача оказалась нетривиальной и совсем неочевидной. Оказывается, что исходные файлы DOS не так-то уж и легко переносятся в git, и уж как минимум, не как текстовые файлы в кодировке UTF-8. Но, к счастью, в отличие от утечек исходников MS-DOS 6.0, здесь имеется полный комплект файлов и инструментов, достаточный для корректной сборки и тестирования. Остались сущие нюансы, которые попили много крови.
Поэтому я, как и многие — начал свои эксперименты по сборке MS-DOS 4.0, с исправлением ошибок, а также возможностью исследования исходных кодов и тестирования их на реальном железе.
В статье же изложено краткое руководство по сборке и созданию загрузочной дискетки.
❯ Инструментарий
Собирать всё буду в Linux Mint (читай Ubuntu). Средой DOS для сборки выбрал dosbox, к сожалению, это не самый лучший вариант, потому что там идёт замедление частоты (чтобы старые программы корректно работали), поэтому сборка идёт достаточно долго. Лучше всего использовать любой удобный DOS, запущенный в виртуальной машине.
Для создания загрузочной дискеты и тестирования полученной сборки буду задействовать виртуальную машину qemu. А чтобы получить дискеты с готовым образом, я буду использовать установочную дискету MS-DOS 4.0 (найденную тут см. 4.00 OEM [Sampo]).
Прежде чем пойдём дальше — важное замечание:
Никаких чужих прав задеть не собираюсь, все модификации кода были сделаны исключительно в юмористических целях, и не подлежат распространению. Модифицированные исходники удалены.
❯ В чём сложности сборки?
Проблемы две:
- Некорректная инициализация переменных среды (в самом bat-файле
SETENV.BAT
содержатся ошибки или опечатки). - Проблемы с кодировкой при переносе кода с дискеток DOS в GIT с кодировкой UTF-8.
Первая проблема легко исправляется даже самостоятельно, при беглом анализе исходного кода. Она легко вскрывается при сборке, дальше просто необходимо внести правки, либо создать свой обновлённый bat-файл, который будет инициализировать переменные среды окружения.
Значительно сложнее обстоят дела с тем, что в части кода, при переносе в UTF-8, побились некоторые символы. У меня была попытка сборки, которую я описывал у себя в ЖЖ, и, в конце концов, я получил вот это:
Это достаточно частая и болезненная проблема со старыми исходниками времён DOS. С аналогичной задачей я столкнулся и при попытке собрать программу RAM View. Об этом пути и исправлении проблемы, я подробно написал в статье Правка чужого кода.
Здесь же мы исключим ручной труд и автоматизируем исправление проблем с кодировками.
❯ Подготовительные операции перед сборкой
Итак, шаги по сборке ДОС. Клонируем оригинальный репозиторий:
git clone https://github.com/microsoft/MS-DOS.git
Исправляем проблемы с кодировками:
sed -i -re 's/\xEF\xBF\xBD|\xC4\xBF|\xC4\xB4/#/g' MS-DOS/v4.0/src/MAPPER/GETMSG.ASM
sed -i -re 's/\xEF\xBF\xBD|\xC4\xBF|\xC4\xB4/#/g' MS-DOS/v4.0/src/SELECT/SELECT2.ASM
sed -i -re 's/\xEF\xBF\xBD|\xC4\xBF|\xC4\xB4/#/g' MS-DOS/v4.0/src/SELECT/USA.INF
Переходим в рабочую папку:
cd MS-DOS/v4.0
Перекодируем все текстовые файлы в формат MS-DOS:
find -iname '*.bat' -o -iname '*.asm' -o -iname '*.skl' -o -iname 'zero.dat' -o -iname 'locscr' | xargs unix2dos -f
find -iname '*.BAT' -o -iname '*.ASM' -o -iname '*.SKL' -o -iname 'ZERO.DAT' -o -iname 'LOCSCR' | xargs unix2dos -f
и создаём там обновлённый бат-файл для переменных среды окружения, следующего содержания:
$ cat src/e.bat
@echo off
echo setting up system to build the MS-DOS 4.01 SOURCE BAK...
set CL=
set LINK=
set MASM=
set COUNTRY=usa-ms
set BAKROOT=e:
rem BAKROOT points to the home drive/directory of the sources.
set LIB=%BAKROOT%\src\tools\bld\lib
set INIT=%BAKROOT%\src\tools
set INCLUDE=%BAKROOT%\src\tools\bld\inc
set PATH=%BAKROOT%\src\tools;%PATH%
В принципе этих операций достаточно для сборки, а то что ниже — это лично моё хулиганство, чтобы продемонстрировать, что DOS в действительности собрался, и нет подмены файлов. Я заменяю компанию Microsoft своим ником:
find -name "*.ASM" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.INC" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.H" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.MAC" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.MSG" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.C" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.CLB" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
find -name "*.SKL" -type f -exec sed -i 's/Microsoft/Dlinyj/g' {} +
Всё, теперь исходники подготовлены, для того чтобы их можно было корректно собрать.
❯ Сборка
Собирать буду в dosbox, как показала практика — это не самое лучшее решение, сборка занимает около часа, что, мягко скажем, раздражает.
Запускаю dosbox:
dosbox
Далее в нём монтирую текущую директорию как диск E.
mount e: ./
И переходим на диск e, запускаем в dosbox бат-файл, который инициализирует среду окружения, и начинаем сборку:
e:
cd SRC
e.bat
и запускаем сборку командой nmake:
Если вы делаете это в dosbox, то можно пойти погулять. Окончанием сборки будет выглядеть следующим образом:
После этого надо скопировать все собранные файлы в один каталог. Создаём каталог «4» в корне диска и копируем все бинарники специальным скриптом:
mkdir \4
CPY.BAT \4
Далее самое интересное: проверка того, что файлы запускаются. Для этого надо сделать так, чтобы dosbox прикидывался старым ДОСом. Выполняем следующую команду:
ver set 4.0
После переходим в каталог
\4
и можно выполнить в нём command.com
:Хулиганство сработало, ДОС собрался и прикидывается, будто бы я его разработал. Дело стало за малым — протестировать это на реальном железе.
❯ Создание загрузочной дискетки
Дальше я думал просто примонтировать в dosbox пустой образ дискетки, и прямо из собранных файлов выполнить перенос системных файлов командой:
sys <path> a:
Но, факир был пьян, и фокус не удался. Поэтому решил MBR (Master Boot Record) позаимствовать с загрузочной дискетки DOS 4.0. К сожалению, MBR от MS-DOS 6.22 у меня не заработал.
Скачиваем установочные дискетки, попутно создаём пустую дискетку командой:
truncate --size 1474560 fdd.img
Загружаемся с установочной дискетки и ставим наш пустой образ 1,44 МБ дискетки в дисковод B, с помощью qemu:
qemu-system-i386 -fda Disk01.img -fdb fdd.img
Отменяем установку и форматируем дискету с переносом системных файлов:
По окончании можно закрывать окно qemu. Возвращаемся к окну с dosbox и монтируем полученный образ дискетки, с помощью следующей команды:
imgmount a: <path to fdd.img> -t floppy
И потом просто вручную переносим файлы
COMMAND.COM
, IO.SYS
и MSDOS.SYS
на дискету:Всё, образ готов. Можно его протестировать в виртуальной машине, или даже записать на настоящую дискету и загрузиться!
Для запуска в qemu следует использовать следующую команду:
qemu-system-i386 -fda fdd.img
Записать на дискетку можно командой dd, я использую USB-FDD дисковод.
sudo dd if=fdd.img of=/dev/sdk status=progress
И, да! Эта система успешно работает на реальном железе. В данном случае проверка идёт на 386 компьютере.
❯ Выводы
Запуск свежесобранного MS-DOS 4.0 на реальном железе
Не буду лукавить, сборка MS-DOS 4.0 оказалась не столь простой. Пришлось посмотреть некоторые видео, пошерстить различные репозитории. Но всё же это прекрасный опыт, который позволяет заглянуть внутрь исторических исходников и покопаться в них.
Давняя утечка MS-DOS 6.0 была неполной, и собрать его не представлялось возможным. А теперь у исследователей есть готовый инструментарий, для того чтобы попрактиковаться в разработки каких-то своих модулей старой операционной системы.
Конечно же, я по-настоящему жду, когда же обнародуют исходники MS-DOS 6.22, так как ещё надеюсь увидеть их на своём веку.
Удачи вам в ваших экспериментах!
❯ Полезные ссылки:
- Исходные коды MS-DOS от Microsoft
- Пример сборки MS-DOS 4.0 во FreeDOS (видео)
- Compiling MS-DOS 4.0 from DOS 4.0, on a PS/2!
Если вам интересна металлообработка, старое железо, всякие DIY штуки, погроммирование и linux, то вы можете следить за мной ещё в телеграмме.
Возможно, захочется почитать и это:
- ➤ Играем в крестики-нолики c RPN калькулятором
- ➤ Из небытия 1987 года. Оживляем индустриальный программатор SIEMENS SIMATIC S5 PG685, ставим CP/M-86 и MS-DOS 2.11
- ➤ Оживляем раритетный домофон с магнитным ключом
- ➤ Эмад Мостак: визионер или обманщик? Разоблачение создателя Stability AI и Stable Diffusion
- ➤ Полная история игровой вселенной «Гарри Поттера»: часть 2 — «Поколение экспериментов»
Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале ↩
Комментарии (67)
vicsoftware
06.05.2024 08:13+33Чтобы собиралось шустрее, наверное, стоило поднять число Cpu Speed. На 3000 он моделирует довольно древнюю машинку. Либо вообще выставить cycles=max в .conf - файле.
JordanCpp
06.05.2024 08:13+4Спасибо. В самое сердечко.
Всё же есть, что-то чарующее в старых железках и в старом софте.
MaFrance351
06.05.2024 08:13+1Кстати, интересно, а там вообще есть что-то, что может не запуститься на современном процессоре, если использовать ВМ вроде VirtualBox какого-нибудь (типа слишком высокой скорости или ошибки как в Windows NT 3.1)? Надо бы попробовать...
dlinyj Автор
06.05.2024 08:13+2Для экспериментов рекомендую таки qemu, с ней проще чем с Virtualbox. Для второго надо диски преобразовывать в формат VM. А qemu может работать с dd-шными образами диска.
DarkWolf13
06.05.2024 08:13+3интересная статья, но возник вопрос а как была собрана и записана на диск самая первая версия на самый первый диск?
domix32
06.05.2024 08:13+8Как и большинство программ тех лет - ручками писался машинный код для конкретной машины, который реализовывал более высокоуровневый компилятор уже текстового ассемблера. Среди инструкций всегда найдутся опкоды аппаратных прерываний, которые позволяли в том числе писать в конкретное устройство. В том числе и флоппики.
veryboringman
06.05.2024 08:13+3На самом деле изначально разработка шла на мини-ЭВМ, где были быстродействующие компиляторы и возможность записи на дискеты.
Разработка на самих микрокомпьютерах началась позднее.
domix32
06.05.2024 08:13+281 первый год первый выпуск. Первый Си был в 72. По идее микрокопьютеры должны были догнать за эти десять лет по закону Мура, учитывая что сам дос почти полностью на своём ассемблере писался.
veryboringman
06.05.2024 08:13+4Если говорить конкретно про MS-DOS - то и в изначальном виде (QDOS) ее разрабатывали на компьютере с процессором Z80 от компании Cromemco. Под Z80 был написан ассемблер для компилирования исходников и записи их на дискеты через контроллер Cromemco 4FDC (он же стоял на первых компьютерах SCP с процессором 8086, на которых QDOS запускалась).
Потом уже разработка переехала на комьютеры SCP полностью. Но это было уже с 1979 года - к тому моменту уже хватало достаточно оснащенных микрокопьютеров.
alexxisr
06.05.2024 08:13+5Например, pdp-8 и pdp-11 умели грузиться с перфолент/перфокарт и писать на дискеты.
А для перфокарт/перфолент вроде бы были ручные набиватели. И да, в первые компьютеры программы набирали тумблерами/кнопочками прямо в оперативку на машинных кодах.
DarkWolf13
06.05.2024 08:13перфокарты перфоленты школьником застал, там понятно...а вот как в случае персоналки происходило таинство...ручной компилятор и запись MBR в формате текстового редактора с размещением на нужной дорожке и секторе нужного дампа?
vanxant
06.05.2024 08:13+6Операторы PDP помнили начальный загрузчик в машинных кодах и вводили его с консоли при включении.
maxpivovar
06.05.2024 08:13+3PDP не видел. мал ещё(46годов). но J3QQ4-H7H2V-2HCH4-M3HK8-6M8VW на всю жизнь
lorc
06.05.2024 08:13+2Ну я думаю что кросс-компиляция даже в те времена существовала. Так что первый софт скорее всего готовили на машине другой архитектуры.
vanxant
06.05.2024 08:13+6Ещё была постадийная сборка. Например, первый компилятор Паскаля его автор Никлаус Вирт реализовал в несколько стадий. Был некий промежуточный P-код, можно сказать дальний предок байт-кода. Очень простой стековый язык типа форта, порядка 20 примитивных команд всего. Его "компилятор" писался на макросах ассемблера под конкретную машину. Дальше собственно компилятор Паскаля был написан на этом машино-независимом P-коде. Дальше этим компилятором собиралась стандартная библиотека (crt) "первого этапа". Дальше, уже со стандартной библиотекой, где были строки, целые и т.д., в т.ч. ассемблерные вставки под конкретную машину, собирался полноценный компилятор, а им уже собиралась полноценная стандартная библиотека.
Xeldos
06.05.2024 08:13+1GCC и сейчес похожим образом вытягивал себя за волосы. Вот сейчас на сайте gcc пишут, что ему нужен gcc версии GCC 4.8.3 или любой C++11 компилятор. 4.8.3 можно собрать с помощью 3.4, его можно собрать с помощью 2.95, и так дойти до 1.27 (если он запустится на современном линуксе). А дальше надо будет собирать компилятор для minix, а его собирать под старым досом? А тот - под cp/m? Дальше, наверное, придётся переходить на z80 или на m68k, и уже без вариантов заниматься кросс-компиляцией.
uuger
06.05.2024 08:13+1в первые компьютеры программы набирали тумблерами/кнопочками прямо в оперативку на машинных кодах
вспомнил не так давно посмотренную мной [лекцию про компьютер Аполлона 11] (https://www.youtube.com/watch?v=B1J2RMorJXM), где рассказывают в том числе, как была запрограммирована его ПЗУ путём ручной намотки на магнитных кольцах
alexxisr
06.05.2024 08:13+2а зачем в пзу магнитные кольца? Там же просто перемычек бы хватило - замкнуто - 1, разомкнуто - 0. Или эту пзу на магнитах можно было программно перезаписывать?
Зашел в статью - да, это по сути аналог не пзу, а флеша. Записанное не пропадает после выключения питания.
kekoz
06.05.2024 08:13У меня в конце 80-х “боевые алгоритмы” шились накруткой, только не на кольца, а на ферритовые “пеньки”. Обычной медной проволокой. Вручную.
А в статье речь не про ПЗУ, а про энергонезависимую RAM. Это скорее аналог флешки. У той же СМ-3 были модификации с RAM на ферритовых кольцах. Не стирается при выключении питания. А программируется всё же не накруткой проводов, а сигналами по этим проводам.
VasiliyLiGHT
06.05.2024 08:13+2Эта система успешно работает на реальном железе. В данном случае проверка идёт на 386 компьютере.
Эх, я то думал, что на современном железе будут сборка и запуск...
Xeldos
R&K?! С ума сойти. Олдскулы свело.
dlinyj Автор
Очень долго искал этот корпус.
bodyawm
Да, очень красивый
strvv
А сколько их видел в 00-10-х годах на помойках, позади разных контор, когда списать нельзя, а использовать тоже, в итоге втихую их выносили и выкидывали.
Там разная экзотика попадалась, но в основном десктопы 286-386-е с большими, полноразмерными жесткими, 20-40МБ, дисками типа ST351.
Матричные принтеры чуть позже А3 формата стали популярны для столодрыжных фрезеров, а вот с системниками такого не было.
Kilmez
А сейчас матричным принтерам формата А3 можно найти применение? Кроме как просто печатать, а то лежат несколько epsonов без применения.
Naves
У меня вот Robotron такой широкий лежит. Давным давно долго и упорно пытался завести его.
Кодировки переключались перемычками в принтере. До сих пор помню, распечатку английского текста: Мицрософт Виндовс. В кодовой таблице включена транслитерация символов и невозможно печатать двуязычный текст.
В текстовом режиме он печатал в режиме кои-7 и не помню, печатал ли он что-либо полезное в итоге.
Но самое интересное, что в Windows XP с драйвером Epson compatible 9 pin он начал печатать в графическом режиме, но при этом каждую строчку он печатал два раза. Вот прям тестовая страница печати с логотипом XP, но двойные строчки. Как это исправить, гугл в то время мне не смог помочь.
Быть может кто знает в какую сторону искать, и получится когда-нибудь запустить принтер для печати широких листов. Правда к тому моменту придется искать компьютер с LPT-портом.
ciuafm
Изи. Если винда на нем может графику, значит сам принтер умеет графический режим. У вас 2 пути:
Выбрать правильный драйвер путем перебора доступных драйверов (название принтера будет другим)
Погуглить ESCAPE- последовательности для Epson, и работать напрямую через порт принтера или формировать файл с последовательностями и копировать его на prn: / lpt:
Если принтер 9-пиновый, графика будет унылая, так что лучше использовать фиксированный шрифт, загружаемый перед печатью
Двойные строчки, это микросдвиг, т.е. винда пытается прокрутить вперёд/назад и за счёт люфта сдвинуть бумагу на половину точки чтобы напечатать в 2 раза плотнее чем позволяет принтер. Но у вас видимо назад не тянет, вот и получается задваивание.
MaFrance351
Кстати, в WinXP у Epson было два драйвера. Один работал нормально, а с другим (даже на куда более новом LQ-100) были описанные вами глюки. Так что рекомендую поэкспериментировать с драйверами ещё.
ufm
Матричные принтеры до сих пор используются в двух случаях
Нужна "печать под копирку" (есть специальная бумага для этого)
Нужно скидывать что-то типа логов на твёрдый носитель построчно.
MaFrance351
А ещё - там, где надо печатать много, но без претензий к качеству графики (обычно как раз всяческое типа логов). Так как матричная печать очень дешёвая, а современные матричники сравнялись по скорости со струйниками и слабыми лазерниками.
Зайдите в аэропорт или на сортировочную станцию - документы типа списка пассажиров, номеров вагонов и тому подобного почти всегда печатают на матричнике.
VasiliyLiGHT
У почтальона видел пачку пенсионных квитков (и прочие пособия), которые на матричном печатают
MaFrance351
Ещё недавно почти в каждом банкомате (когда ещё были старые вроде NCR Personas 5877 или Wincor ProCash 2500xe) стояли матричники как чековые и журнальные принтеры.
Yra_36
их используют в банках и на морских судах в составе радиокомплексов Глобальная Морская Система Связи при Бедствии https://furuno.ru/gmssb/