Меня зовут Виктор, и в этом году я единственный студент в программе Google Summer of Code на проекте ReactOS. Сегодня я расскажу немного о том, что я делаю в рамках стажировки.
ReactOS поддерживает кучу всяких разных файловых систем для чтения и записи (fat32, ext2, ReiserFS, BTRFS), однако загружаться до сих пор умеет только с раздела, отформатированного в fat32. Этой весной я решил что пора начать исправлять эту ситуацию, и подал заявку на GSoC. И вот, спустя несколько месяцев я пишу этот пост :)
Почему BTRFS? Ответ прост — драйвер файловой системы WinBtrfs на текущий момент самый стабильный и полнофункциональный из всех, что включены в код РеактОС. На данном этапе, мы хотим пофиксить именно баги ядра, которые мешают использовать другие ФС для загрузки, так что баги драйвера ФС нам тут совсем ни к чему.
Но начать мне пришлось не с ядра ОС, а с установщика. Благо для установщика было уже почти всё готово: нужно было только включить загрузку драйвера WinBtrfs в нашем установщике (usetup), и добавить пару строчек кода, для поддержки форматирования в нужной файловой системе. После чего мне удалось (почти) без проблем скопировать файлы ReactOS на раздел, отформатированный в BTRFS.
С установщиком расправились быстро, а вот следующая задача гораздо интереснее. Загрузчик ReactOS — FreeLdr поддерживает практически только две файловые системы — fat32 и iso (есть код для ext2 и ntfs, но его уже лет 5 никто не пробовал запускать). Поскольку FreeLdr повторяет принцип работы загрузчика ntldr от MS, он состоит из двух частей — загрузочного сектора в начале раздела, куда передает управление MBR диска, и основной части, которая переводит процессор в защищенный режим, загружает ядро ntoskrnl.exe в память, и делает ещё кучу всего.
(так выглядит процесс загрузки ReactOS)
Таким образом, для поддержки новой файловой системы, нужно написать загрузочную запись раздела (VBR), задача которой найти в корневой директории диска исполняемый файл основной части загрузчика (у нас он называется freeldr.sys), загрузить его в память и передать туда управление. Но это ещё не всё, в самом freeldr.sys нужен практически полноценный read-only драйвер файловой системы, для того чтобы считывать конфигурационные файлы, ядро, кусты реестра и т.д.
Вначале нужно было разобраться с самой файловой системой BTRFS. До этого самыми сложными вещами, что я ковырял были fat32 и ext2, так что на изучение “комбайна” BTRFS мне потребовалось немало времени. Документация на wiki.kernel.org помогает разобраться, но для полного понимания её было недостаточно — приходилось ходить в исходники grub, u-boot и других загрузчиков. Очень полезной для изучения строения файловой системы оказалась утилита на python, которую я написал для вывода структур файловой системы в консоль. С помощью нее я и написал первый прототип загрузочного сектора, который вытаскивает загрузчик из бинарного файла с образом диска с файловой системой BTRFS.
(на картинке видны элементы корневой директории)
Теперь пришло время настоящего загрузочного сектора. Осложняется его написание тем, что тут мы работаем в реальном режиме процессора со всеми вытекающими последствиями (~1мб памяти, сегментная адресация и работа с диском через прерывания BIOS). Раздолье для любителей олдскула типа меня :)
В структурах BTRFS почти все поля имеют 64-битный размер, что весьма “раздуло” код, поскольку пришлось активно использовать 32-битные x86 инструкции. Частенько приходится использовать конструкции типа:
mov si, SOME_OFFSET
lea si, [esi+ecx*8]
lea si, [esi+ecx*8]
lea si, [esi+ecx*8] // one element is 24 bytes long
Самой трудоёмкой оказалось написание процедуры обхода b-дерева, на её отладку ушло больше всего времени. И после нескольких бессонных ночей, мне таки удалось получить заветное сообщение об ошибке из второго этапа загрузки:
freeldr.sys получилось успешно загрузить в память, и даже не понадобилось использовать магию вроде Unreal Mode. 640кб хватит всем!
Код загрузочного сектора можно посмотреть в моём репозитории на github (его ещё ожидает рефакторинг), а всю работу по BTRFS в этой ветке.
Теперь очередь за второй частью загрузчика — нужно научить его считывать файл конфигурации с новой файловой системы. Следите за новостями!
Комментарии (33)
Siemargl
06.07.2018 11:01Для экономии времени я бы предложил первоначально писать на С, а полученный асм код, например с godbolt.org, уже потом дорабатывать. Количество глупых ошибок уменьшится в разы.
Есть еще вариант вообще писать на С со специальным скриптом линкеру ld для получения нужного бинарника. Но отлаживаться все равно придется в ассемблере.Extravert34 Автор
06.07.2018 19:22+2Я хотел сначала использовать что-то подобное, но пока думал уже и так справился :)
Но если буду ещё что-то писать на асме, то наверное да, воспользуюсь таким способом
khim
06.07.2018 23:51-1Тут всё, увы, не так просто. Современные компиляторы C и C++ не умеют в 16-битный режим. Обычно все стараются как можно быстрее переключиться в защищённый режим и там, уже в 32-битах, всё делают. Исключения есть, да, но из-за проблем с компиляторами FreeDOS собирается, на минуточку, с помощью Turbo C++ 1.01 выпуска 1990го года!
Так что не уверен я, что писать на C — в данном случае хорошая идея…Siemargl
07.07.2018 11:42Достаточно много компиляторов умеют генерировать приличный 16-битный код: bcc, djgpp, dmc, watcom. Дело в принципе — избавиться от рутинной работы, в которой легко ошибиться.
khim
08.07.2018 11:58-1djgpp не умеет. Остальные — очень старые и простые компиляторы, генерирующие весьма неэффективный код. Собственно эффективный код под 16-битный режим вообще гораздо сложнее сотворить, чем под 32х битный — именно поэтому современные компиляторы этим не заморачиваться.
mvy
06.07.2018 19:20Поддержка BTRFS — это круто, но так заморачиваться с загрузочным сектором мб и не стоило. Реальные системы (да и виртуалки) используют UEFI и там всегда есть бутовый раздел на FAT где можно разместить freeldr.
Extravert34 Автор
06.07.2018 19:20+3Сделать поддержку UEFI занимает несколько больше сил, чем добавить поддержку новой файловой системы в то, что есть
Superl3n1n
Всегда с интересом читаю новости про ReactOS. Всегда забавляют комментарии под постами от диванных Танненбаумов, о том что «РеактОС не нужон». Интересно, когда эта операционная система выйдет в более-менее стабильное состояние, тоже появиться какой-нибудь RedHat который будет строить свой бизнес на поддержке пользователей?
vasyan
Миллионы праворульных «Жигулей»
Заполнят пространство японских хайвеев
trdm
Если допилят и поддержкой займется какой-нибудь наш институт с программистским уклоном(мечты, мечты), то будет сэкономлена куча бабла для России.
Focushift
Где-то был комментарий, что в одном магазине на нем работают кассы.
Salabar
Это имеет смысл для специфичного класса приложений, которые намертво прибиты к Винде, но не работают под Вайном. При этом приличная часть программ из второй категории и под современной Виндой тоже не работает, потому что требует жутких фокусов уровня ядра, очевидно непереносимых. Для остального проще допилить Вайн.
denisromanenko
Конечно, ведь если можно будет запускать 1С с Postgres без лицензионных отчислений за Windows — это будет огромная экономия.
Я бы кстати в разработке над РеактОС сконцентрировался именно на полной поддержке 1С и работе в виртуальном окружении — даже наплевал бы на поддержку драйверов, лишь бы в виртуализированном окружении запускалось.
И если бы тянуло БД и сервера 1С — это дало бы огромный скачок в пользовательском интересе.
pavelpromin
Ага, сначало бы научили в виртуалбоксах и qemu/KVM работать стабильно, это уже было бы хорошо.
Extravert34 Автор
Кстати, один из багов, препятствующих запуску postgres я исправил когда подавал заявку на GSoC. Как это у нас обычно происходит, он был в CRT
ntfs1984
Зачем вам еще одна Винда?
Zenitchik
Чтобы играть в наши любимые игры.
ntfs1984
В любимые игры позволяет играть и Windows.
Zenitchik
Windows для этого купить надо.
ntfs1984
Если вы не купите Windows — от этого ничего не изменится, другим Windows продолжит позволять играть в любимые игры.
Zenitchik
И?
Extravert34 Автор
Чтобы было
Superl3n1n
Разве альтернатива это плохо? Тем более, что проект открытый! Где гарантии, что Майкрософт не обанкротится и не закроется? А РеактОС вот он, бери не хочу.
ntfs1984
Это никогда не станет альтернативой, хотя бы потому что Windows и Microsoft неразрывно связаны в плане инноваций, дистрибюторской политики, и так далее.
Иными словами, ReactOS может быть лишь тенью основной системы, Windows, при чем определенной ее версии.
Без мелкомягких, эта ОС просто будет «Линуксом, умеющим запускать exe-шники».
Zenitchik
Именно поэтому нам нужна ось, в которой запустится всякое старьё, даже после того, как поддержку выпилят из актуальных версий винды.
ntfs1984
Всякое старье можно запускать и на старых версиях Windows. Другое дело, что старые версии Windows не встанут на новое железо, но не понятно с чего вы взяли что ReactOS встанет.
Это же проект полностью зависимый от Винды. Выпилят в Винде очередное API в угоду новому — и в РеактОСи выпилят.
Но делить шкуру неубитого медведя — рановато.
ExplosiveZ
Старые версии windows уже не продают.