Совсем недавно на хабре появилась следующая новость: На 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]).

Прежде чем пойдём дальше — важное замечание:

Никаких чужих прав задеть не собираюсь, все модификации кода были сделаны исключительно в юмористических целях, и не подлежат распространению. Модифицированные исходники удалены.

В чём сложности сборки?


Проблемы две:

  1. Некорректная инициализация переменных среды (в самом bat-файле SETENV.BAT содержатся ошибки или опечатки).
  2. Проблемы с кодировкой при переносе кода с дискеток 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, так как ещё надеюсь увидеть их на своём веку.

Удачи вам в ваших экспериментах!

Полезные ссылки:


  1. Исходные коды MS-DOS от Microsoft
  2. Пример сборки MS-DOS 4.0 во FreeDOS (видео)
  3. Compiling MS-DOS 4.0 from DOS 4.0, on a PS/2!

Если вам интересна металлообработка, старое железо, всякие DIY штуки, погроммирование и linux, то вы можете следить за мной ещё в телеграмме.



Возможно, захочется почитать и это:


Новости, обзоры продуктов и конкурсы от команды Timeweb.Cloud — в нашем Telegram-канале

Комментарии (67)


  1. Xeldos
    06.05.2024 08:13
    +13

    R&K?! С ума сойти. Олдскулы свело.


    1. dlinyj Автор
      06.05.2024 08:13

      Очень долго искал этот корпус.


      1. bodyawm
        06.05.2024 08:13
        +2

        Да, очень красивый


        1. strvv
          06.05.2024 08:13
          +3

          А сколько их видел в 00-10-х годах на помойках, позади разных контор, когда списать нельзя, а использовать тоже, в итоге втихую их выносили и выкидывали.
          Там разная экзотика попадалась, но в основном десктопы 286-386-е с большими, полноразмерными жесткими, 20-40МБ, дисками типа ST351.

          Матричные принтеры чуть позже А3 формата стали популярны для столодрыжных фрезеров, а вот с системниками такого не было.


          1. Kilmez
            06.05.2024 08:13
            +1

            А сейчас матричным принтерам формата А3 можно найти применение? Кроме как просто печатать, а то лежат несколько epsonов без применения.


            1. Naves
              06.05.2024 08:13
              +1

              У меня вот Robotron такой широкий лежит. Давным давно долго и упорно пытался завести его.

              Кодировки переключались перемычками в принтере. До сих пор помню, распечатку английского текста: Мицрософт Виндовс. В кодовой таблице включена транслитерация символов и невозможно печатать двуязычный текст.

              В текстовом режиме он печатал в режиме кои-7 и не помню, печатал ли он что-либо полезное в итоге.
              Но самое интересное, что в Windows XP с драйвером Epson compatible 9 pin он начал печатать в графическом режиме, но при этом каждую строчку он печатал два раза. Вот прям тестовая страница печати с логотипом XP, но двойные строчки. Как это исправить, гугл в то время мне не смог помочь.

              Быть может кто знает в какую сторону искать, и получится когда-нибудь запустить принтер для печати широких листов. Правда к тому моменту придется искать компьютер с LPT-портом.


              1. ciuafm
                06.05.2024 08:13
                +6

                Изи. Если винда на нем может графику, значит сам принтер умеет графический режим. У вас 2 пути:

                • Выбрать правильный драйвер путем перебора доступных драйверов (название принтера будет другим)

                • Погуглить ESCAPE- последовательности для Epson, и работать напрямую через порт принтера или формировать файл с последовательностями и копировать его на prn: / lpt:

                  Если принтер 9-пиновый, графика будет унылая, так что лучше использовать фиксированный шрифт, загружаемый перед печатью

                Двойные строчки, это микросдвиг, т.е. винда пытается прокрутить вперёд/назад и за счёт люфта сдвинуть бумагу на половину точки чтобы напечатать в 2 раза плотнее чем позволяет принтер. Но у вас видимо назад не тянет, вот и получается задваивание.


              1. MaFrance351
                06.05.2024 08:13
                +1

                Кстати, в WinXP у Epson было два драйвера. Один работал нормально, а с другим (даже на куда более новом LQ-100) были описанные вами глюки. Так что рекомендую поэкспериментировать с драйверами ещё.


            1. ufm
              06.05.2024 08:13
              +3

              Матричные принтеры до сих пор используются в двух случаях

              1. Нужна "печать под копирку" (есть специальная бумага для этого)

              2. Нужно скидывать что-то типа логов на твёрдый носитель построчно.


              1. MaFrance351
                06.05.2024 08:13
                +2

                А ещё - там, где надо печатать много, но без претензий к качеству графики (обычно как раз всяческое типа логов). Так как матричная печать очень дешёвая, а современные матричники сравнялись по скорости со струйниками и слабыми лазерниками.

                Зайдите в аэропорт или на сортировочную станцию - документы типа списка пассажиров, номеров вагонов и тому подобного почти всегда печатают на матричнике.


                1. VasiliyLiGHT
                  06.05.2024 08:13
                  +3

                  У почтальона видел пачку пенсионных квитков (и прочие пособия), которые на матричном печатают


                  1. MaFrance351
                    06.05.2024 08:13
                    +1

                    Ещё недавно почти в каждом банкомате (когда ещё были старые вроде NCR Personas 5877 или Wincor ProCash 2500xe) стояли матричники как чековые и журнальные принтеры.


            1. Yra_36
              06.05.2024 08:13

              их используют в банках и на морских судах в составе радиокомплексов Глобальная Морская Система Связи при Бедствии  https://furuno.ru/gmssb/


  1. vicsoftware
    06.05.2024 08:13
    +33

    Чтобы собиралось шустрее, наверное, стоило поднять число Cpu Speed. На 3000 он моделирует довольно древнюю машинку. Либо вообще выставить cycles=max в .conf - файле.


  1. JordanCpp
    06.05.2024 08:13
    +4

    Спасибо. В самое сердечко.

    Всё же есть, что-то чарующее в старых железках и в старом софте.


  1. MaFrance351
    06.05.2024 08:13
    +1

    Кстати, интересно, а там вообще есть что-то, что может не запуститься на современном процессоре, если использовать ВМ вроде VirtualBox какого-нибудь (типа слишком высокой скорости или ошибки как в Windows NT 3.1)? Надо бы попробовать...


    1. dlinyj Автор
      06.05.2024 08:13
      +2

      Для экспериментов рекомендую таки qemu, с ней проще чем с Virtualbox. Для второго надо диски преобразовывать в формат VM. А qemu может работать с dd-шными образами диска.


      1. MaFrance351
        06.05.2024 08:13
        +3

        Ну а совсем каноничным вариантом будет, наверное, 86box.


        1. strvv
          06.05.2024 08:13
          +2

          я, особо разницы не заметил, если не брать XT-шную специфику.


      1. VT100
        06.05.2024 08:13

        Можно подключить физический диск или раздел и к VirtualBox.


        1. dlinyj Автор
          06.05.2024 08:13

          Да можно, но сложнее чем к qemu


  1. DarkWolf13
    06.05.2024 08:13
    +3

    интересная статья, но возник вопрос а как была собрана и записана на диск самая первая версия на самый первый диск?


    1. domix32
      06.05.2024 08:13
      +8

      Как и большинство программ тех лет - ручками писался машинный код для конкретной машины, который реализовывал более высокоуровневый компилятор уже текстового ассемблера. Среди инструкций всегда найдутся опкоды аппаратных прерываний, которые позволяли в том числе писать в конкретное устройство. В том числе и флоппики.


      1. veryboringman
        06.05.2024 08:13
        +3

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

        Разработка на самих микрокомпьютерах началась позднее.


        1. domix32
          06.05.2024 08:13
          +2

          81 первый год первый выпуск. Первый Си был в 72. По идее микрокопьютеры должны были догнать за эти десять лет по закону Мура, учитывая что сам дос почти полностью на своём ассемблере писался.


          1. veryboringman
            06.05.2024 08:13
            +4

            Если говорить конкретно про MS-DOS - то и в изначальном виде (QDOS) ее разрабатывали на компьютере с процессором Z80 от компании Cromemco. Под Z80 был написан ассемблер для компилирования исходников и записи их на дискеты через контроллер Cromemco 4FDC (он же стоял на первых компьютерах SCP с процессором 8086, на которых QDOS запускалась).

            Потом уже разработка переехала на комьютеры SCP полностью. Но это было уже с 1979 года - к тому моменту уже хватало достаточно оснащенных микрокопьютеров.


    1. alexxisr
      06.05.2024 08:13
      +5

      Например, pdp-8 и pdp-11 умели грузиться с перфолент/перфокарт и писать на дискеты.

      А для перфокарт/перфолент вроде бы были ручные набиватели. И да, в первые компьютеры программы набирали тумблерами/кнопочками прямо в оперативку на машинных кодах.


      1. DarkWolf13
        06.05.2024 08:13

        перфокарты перфоленты школьником застал, там понятно...а вот как в случае персоналки происходило таинство...ручной компилятор и запись MBR в формате текстового редактора с размещением на нужной дорожке и секторе нужного дампа?


        1. vanxant
          06.05.2024 08:13
          +6

          Операторы PDP помнили начальный загрузчик в машинных кодах и вводили его с консоли при включении.


          1. maxpivovar
            06.05.2024 08:13
            +3

            PDP не видел. мал ещё(46годов). но J3QQ4-H7H2V-2HCH4-M3HK8-6M8VW на всю жизнь


        1. lorc
          06.05.2024 08:13
          +2

          Ну я думаю что кросс-компиляция даже в те времена существовала. Так что первый софт скорее всего готовили на машине другой архитектуры.


          1. vanxant
            06.05.2024 08:13
            +6

            Ещё была постадийная сборка. Например, первый компилятор Паскаля его автор Никлаус Вирт реализовал в несколько стадий. Был некий промежуточный P-код, можно сказать дальний предок байт-кода. Очень простой стековый язык типа форта, порядка 20 примитивных команд всего. Его "компилятор" писался на макросах ассемблера под конкретную машину. Дальше собственно компилятор Паскаля был написан на этом машино-независимом P-коде. Дальше этим компилятором собиралась стандартная библиотека (crt) "первого этапа". Дальше, уже со стандартной библиотекой, где были строки, целые и т.д., в т.ч. ассемблерные вставки под конкретную машину, собирался полноценный компилятор, а им уже собиралась полноценная стандартная библиотека.


            1. Xeldos
              06.05.2024 08:13
              +1

              GCC и сейчес похожим образом вытягивал себя за волосы. Вот сейчас на сайте gcc пишут, что ему нужен gcc версии GCC 4.8.3 или любой C++11 компилятор. 4.8.3 можно собрать с помощью 3.4, его можно собрать с помощью 2.95, и так дойти до 1.27 (если он запустится на современном линуксе). А дальше надо будет собирать компилятор для minix, а его собирать под старым досом? А тот - под cp/m? Дальше, наверное, придётся переходить на z80 или на m68k, и уже без вариантов заниматься кросс-компиляцией.


      1. uuger
        06.05.2024 08:13
        +1

        в первые компьютеры программы набирали тумблерами/кнопочками прямо в оперативку на машинных кодах

        вспомнил не так давно посмотренную мной [лекцию про компьютер Аполлона 11] (https://www.youtube.com/watch?v=B1J2RMorJXM), где рассказывают в том числе, как была запрограммирована его ПЗУ путём ручной намотки на магнитных кольцах

        вот ссылка на статью с фото


        1. alexxisr
          06.05.2024 08:13
          +2

          а зачем в пзу магнитные кольца? Там же просто перемычек бы хватило - замкнуто - 1, разомкнуто - 0. Или эту пзу на магнитах можно было программно перезаписывать?

          Зашел в статью - да, это по сути аналог не пзу, а флеша. Записанное не пропадает после выключения питания.


        1. kekoz
          06.05.2024 08:13

          У меня в конце 80-х “боевые алгоритмы” шились накруткой, только не на кольца, а на ферритовые “пеньки”. Обычной медной проволокой. Вручную.

          А в статье речь не про ПЗУ, а про энергонезависимую RAM. Это скорее аналог флешки. У той же СМ-3 были модификации с RAM на ферритовых кольцах. Не стирается при выключении питания. А программируется всё же не накруткой проводов, а сигналами по этим проводам.


  1. VasiliyLiGHT
    06.05.2024 08:13
    +2

    Эта система успешно работает на реальном железе. В данном случае проверка идёт на 386 компьютере.

    Эх, я то думал, что на современном железе будут сборка и запуск...


    1. dlinyj Автор
      06.05.2024 08:13
      +1

      Эм, а разве этого не было в статье?