Page 3 of 31

Posted: Sun May 14, 2006 8:15 am
by Иван Поддубный
Можно объединить загрузчик и ядро в один файл. И загружать их вместе.

loader.asm <- загрузчик: синий экран, переход в защищённый режим, включение страничной адресации
executive.asm <- всё остальное

kernel.asm:

Code: Select all

org 0
file "loader.bin"    ; при условии, что загрузчик не превышает 8 Кб
rb (0x2000-$)
file "executive.bin"
Если загрузчик находится по адресу 0x10000, то ядро физически - на 0x12000, и не надо будет менять ни acroboot, ни mtldr.

Posted: Sun May 14, 2006 11:33 am
by Serge
Это хороший вариант. Потом загручик может переместить ядро в нужное место. Но если грузится с HD то FAT12 загрузчик уже не нужен.

Posted: Mon May 15, 2006 4:10 pm
by diamond
Общая схема. Процесс загрузки операционной системы можно разделить на следующие части:
1. BIOS после всяких своих действий загружает bootsector и передаёт туда управление.
2. bootsector (который должен быть маленьким и укладываться в 512 байт!) загружает либо сразу какую-то часть ядра (в Kolibri всё ядро kernel.mnt, в DOS/9x/Me - io.sys, в NT/2k/XP+ ntldr) либо вспомогательные секторы, в которых закодирован разбор конкретной файловой системы и догрузка вышеупомянутой части ядра.
Естественно, всё это очень сильно зависит от используемой файловой системы. Поскольку на этом шаге код должен быть очень маленьким, то всё, что он делает, - это загрузка большой части кода.
3. Загруженный на шаге 2 код - это начало действий собственно операционной системы, уже начинает разбираться, что нужно пользователю, какие компоненты и т.п. Причём этот код уже не зависит от конкретной файловой системы и может грузиться разными загрузчиками.
Подчёркиваю, что код самой системы начинается только на шаге 3! Это надо, чтобы можно было загружаться с разных файловых систем без изменения ядра. После этого real-mode часть кода ядра производит необходимую инициализацию (у нас это синий экран загрузки) и переходит в protected-mode, где уже система может показать себя.
Что предлагается сделать (как это понимаю я; если я ошибаюсь, поправьте): заставить на шаге 2 грузить не kernel.mnt, а файл загрузчика (назовём его условно loader.bin); после чего этот loader.bin сам займётся инициализацией ядра (в частности, запросом параметров у пользователя/считывание/сохранение), сам прочитает оставшуюся часть ядра (kernel.mnt) и образ дискеты, причём при чтении будет руководствоваться FAT12. По сути, это означает, что часть код ядра перебрасывается на шаг 2. Результатом чего становится зависимость от файловой системы. И потребуется дублировать солидную часть кода (синий экран загрузки).
Теперь почему я считаю, что загрузке с жёсткого диска хана. Отвечаю. Именно потому, что загрузчик руководствуется FAT12. И когда тот же mtldr загрузит loader.bin откуда-то с NTFS, загрузчик растеряется и не сможет продолжить.
Если же loader.bin не зависит от файловой системы, то от bootsector'а/mtldr/acroboot требуется загрузить уже два файла. А теперь вопрос: а почему бы и не объединить эти файлы в один? Как это сделано сейчас? Я не понимаю преимуществ предлагаемого подхода перед существующим, но вижу недостатки - необходимость переписывать кучу кода, причём как в ядре, так и во всех (!) загрузчиках.

Posted: Mon May 15, 2006 5:40 pm
by Serge
Что предлагается сделать (как это понимаю я; если я ошибаюсь, поправьте): заставить на шаге 2 грузить не kernel.mnt, а файл загрузчика (назовём его условно loader.bin); после чего этот loader.bin сам займётся инициализацией ядра (в частности, запросом параметров у пользователя/считывание/сохранение), сам прочитает оставшуюся часть ядра (kernel.mnt) и образ дискеты, причём при чтении будет руководствоваться FAT12. По сути, это означает, что часть код ядра перебрасывается на шаг 2.
Совершенно точно. В том числе и название. Пока loader.bin потом можно будет назвать loader.sys.
Теперь почему я так сделал.
Было сложно откомпилировать в одном файле работающий в первом мегабайте загрузчик и ядро, работающее в верхних адресах.
В нынешнем загрузчике есть только код для загрузки дискеты в память. Настройки хранятся в образе системы а их сохранение происходит довольно своеобразным образом - загрузчик патчит находящийся в памяти бутсектор и передает ему управление . Похожим образом загрузчик работает и с mtldr.
Я не думаю, что это хорошая идея - хранить настройки зашитыми в первый сектор образа системы и использовать для их сохранения самомодификацию. Тем более удобней работать с настройками когда они хранятся в текстовом файле. Поэтому я добавил в загрузчик код для чтения файлов с FAT12.
Я не вижу никаких проблем в том, чтобы добавить туда код и для работы с другими файловыми системами.
Загрузочный сектор или mtldr могут передавать загрузчику тип файловой системы - это упростит его работу. Нет проблем и с размером загрузчика - позже система может затереть его.
Если очень нужно чтобы ядро и система были в одном файле то можно использовать предложение Поддубного.
Что касается переделки кода, то ядро просто "потеряло" 16-битный код и стало на несколько килобайт легче.

Posted: Mon May 15, 2006 6:19 pm
by diamond
Хранить настройки зашитыми в первый сектор ядра действительно не лучшая идея. Проблема в том, что понадобится добавлять код для работы с другими файловыми системами, который по большому счёту уже есть в загрузчике. Мне не нравится именно дублирование кода. Например, для NTFS: я уже написал код чтения (и самомодификации) в mtldr, но мне совершенно не хочется переписывать его с нуля (и вряд ли хочется кому-нибудь другому) (особенно с учётом того, что в перспективе понадобится ещё 32-битный код для самого ядра). Насколько я понял, в данный момент при предлагаемых модификациях с жёсткого диска с NTFS (да даже и с FAT32) загрузиться просто не удастся, а чтобы это можно было сделать, понадобится либо дописывание NTFS-кода в loader.bin, либо какой-то глобальный мухлёж и с loader.bin, и со всеми существующими загрузчиками.

Posted: Mon May 15, 2006 6:39 pm
by Serge
Особенно переписывать ничего и не надо. Достаточно чтобы mtldr поместил загрузчик в память и передал ему управление. Разумеется загрузчик должен уметь работать с FAT32 и NTFS. Сейчас этого нет, но это можно сделать. Пока всё ядро - лишь alpha версия и я не говорю, что оно будет готово завтра к вечеру.

Posted: Mon May 15, 2006 7:19 pm
by Иван Поддубный
Чтобы прояснить, напишу ступени загрузки, как я понимаю...
0) первичный загрузчик - либо в секторе жесткого диска/дискеты, либо mtldr, либо acroboot...
1) загрузчик реального режима - спрашивает у пользователя настройки, которые уже нельзя изменить в защищённом режиме, переводит систему в ЗР
2) загрузчик защищенного режима - выполняет всё остальное: инициализацию менеджера памяти, поиск устройств... переход к многозадачности
Вот.

Я тоже думаю, что включать поддержку ФС в загрузчик реального режима - плохое решение. Драйверов для всех ФС не предусмотришь, к тому же весь код будет мёртво сидеть в загрузчике, для всех поддерживаемых ФС сразу.

Поддержка ФС реально необходима только для з0 и з2.

Есть одна загвоздка с з2, при условии что драйвера ФС динамически подгружаемые. А именно, нельзя загрузить файл с драйвером ФС, потому что для этого требуется драйвер ФС :)

Первое приходящее в голову решение - загружать драйвер на этапе 0, потому что он
а) знает, с какой ФС происходит загрузка
б) может загружать файлы с этой ФС

Загрузчики 1,2 находятся в ядре в КолибриОС сейчас, и я считаю, что разумно так делать и дальше.
Либо сливать бинарники в один, либо по-прежнему всё будет в одном .asm.

Posted: Mon May 15, 2006 8:12 pm
by Serge
тоже думаю, что включать поддержку ФС в загрузчик реального режима - плохое решение. Драйверов для всех ФС не предусмотришь, к тому же весь код будет мёртво сидеть в загрузчике, для всех поддерживаемых ФС сразу.
А что в этом плохого. Удобней работать с настройками, когда они хранятся в текстовом файле. Параметров настройки может быть много например можно жестко задавать размер ОЗУ и объем видеопамяти если надо проверить определённую конфигурацию. Ещё один плюс раздельной загрузки - может быть несколько ядер: одно рабочее, другое отладочное
в ini может быть строка KERNEL с:\kernel_1.dbg для загрузки отладочного ядра. В таком случае загрузчик должен уметь работать с файловой системой. Мёртвый код конечно будет но это же не мегабайты. И еще. Ядро ведь не обязательно должно грузиться в первый мегабайт ОЗУ. Сейчас оно грузится по прежним адресам но не факт что так должно быть всегда. Отделив код загрузчика от кода ядра можно легко перемещать ядро по новым физическим/линейным адресам. Это повышает возможности модификации системы. Ещё один арумент: ядро может быть скомпилировано как DLL (какой формат будет выбран?), код и данные наконец-то разнесены по разным страницам памяти и страницы кода могут быть защищены от записи. Это если и не повысит надежность всей системы, то позволит быстрее найти ошибку когда "кривой" драйвер начнет затирать код ядра.

Posted: Mon May 15, 2006 8:54 pm
by Serge
Придумал радикальный вариант: загрузчик-link читает make файл и собирает ядро из отдельных *.obj файлов в один файл. Получается и модульность и монолитность в одном флаконе.

Posted: Mon May 15, 2006 9:04 pm
by Иван Поддубный
Плохого? нужно а) дублировать драйверы для всех поддерживаемых ФС и б) переписывать их для работы в реальном однозадачном режиме.

Файл с натройками может загружать з0. Так делается в MeOS 64.
Для отладочного ядра можно сделать и отладочный загрузчик, который будет читать фат (к примеру) и при необходимости перегружать уже загруженное з0 ядро. Но в обычное ядро, которое идёт в дистрибутиве, такого не надо.

Перемещать код ядра можно всегда, вне зависимости разделения на файлы, надо только знать откуда и куда. И разумеется, зачем.

Posted: Mon May 15, 2006 11:30 pm
by Serge
Файл с натройками может загружать з0. Так делается в MeOS 64.
И сохранять тоже будет бутсектор как сейчас?
Что касается дублирования то это не страшно. Я думаю лучше наоборот раздуть загрузчик как можно больше, поместив туда код определения устройств, работу с PCI BIOS и весь другой код который может работать в реальном режиме и использовать прерывания БИОС. Потом система просто затрет загрузчик а размер ядра будет реально меньше чем сейчас.
Зачем делать специальный отладочный загрузчик если его работу может выполнить обычный просто загрузив нужный файл? И почему не надо включать в дистрибутив отладочное ядро? Cистемой пользуются в остновном энтузиасты-программисты им отладочное ядро с выводом разной вспомогательной информации было бы весьма полезно.
Конечно такой загрузчик будет чуть больше чем просто загрузчик
Но, думаю, стоит подумать о тех возможностях что он может дать, а не только о проблемах.
Может у кого-нибудь есть идеи?

Posted: Tue May 16, 2006 1:15 pm
by VaStaNi
О! У Вас опять родные слуху и сознанию дебаты! :) Ну ка я свои пять копеек вонзЮ, авось кто то, что то услышит :O)
Я согласен с Иваном(!), как минимум потому, что он максимально близок к моему проектированию этого дела.
Бутов, как и масса FS + будут новые FS, значит новые буты будут, а имею ввиду именно бут сектора!
Это, можно сказать, неоспоримый ФАКТ. Что из этого получается? А получается, что лениться делать буты под свою ось и новые возможно FS не стоит или пытаться обойтись чем либо горбатым или унифицированным и под него потом вязать шнурочки-бантики, примочки... только лишь бы было и как то работало - неразумно, пассивно и НЕавторски!
Как быть с этой пестротой FS, ведь их в идеале должна иметь ОС и владеть ими? Тогда, где грань разумного? Т.е. где и когда нужно подключить работу c FS, где "начинать ими пользоваться"? Лупить все в кучу и сразу - дикое безумие.
Плодить к куче бут секторов еще цепочку файлов/принципов дозагрузок... - неоптимально, ненадежно и похоже на тяп-ляп. Плюс надо учесть, что где то тут проходит грань между RM и PM, а это накладывает еще большие неприятности и потребности одновременно.
Посему в моем решении (c) ATOM OS :) вся эта матата продумана, разбита на 3 основных этапа, называемых ступенями загрузки (как ступени у ракеты - отработал ступень, отстрелил ее в утиль = овсободив/затерев память... но каждая ступень РАЗВИВАЕТ ЯДРО!!! Создает СРЕДУ его обитания: диагностика, поиски, тесты, структуры, MOVING блоков кода по назначению...:)
А реальный рабочий финал он у ВСЕХ осей (типично) один PM + многозадачка или запущенные службы (СТУПЕНЬ 3) или самая первая задача ОСи - задачка загрузки НУЖНЫХ ДРАЙВЕРОВ... скажем, ФАКТИЧЕСКИЙ(!) список которых уже выявлен и очерчен на предидущем этапе.
Вообще, если быть хоть чуть чуть внимательным, то видно, что винда оживает несколько подобным образом.
Таким образом, красота саморазвивающегося, минимально-самодостаточного принципа загрузки, дозагрузки, запуска ядра
в нашей идеологии выглядит так:
1.0 Бутсектора (индивидуальные под FS и под конкретный загрузочный файл! Это позволяет регистрироваться в мультизагрузчиках: SyMon, Acronis, System Commander именно, как новая уникальная инсталляция ОС (даже если это лишь отладочный вариант, НО, это полный аналог рабочей!) + соотв. ее сохранения) любых типов FS загружают ВСЕГДА ОДИН и ТОТ ЖЕ ФАЙЛ - СТУПЕНЬ 1 и стартуют его по ФИКСИРОВАННОМУ адресу 0x5000 (верхние адреса предпочтительнее т.к. позволяет отлаживать в ДОС реальные дела ступени 1:) т.к. не перекрывыаются рабочей зоной ДОС прог и самим ДОСом:)
2.0 СТУПЕНЬ 1 - чисто RM. Первичная цель - устранить убожество MenuetOS относительно уродских вопросов какая у тебя память,проц,драйвы,мышь, какой порт на... какое разрешение и т.п.... Т.е. тестинг оборудования всеми возможными методами и средствами ибо тут ПОКА CPU в RM и ему доступны ВСЕ методы и средства BIOS + можно играться прерываниями как хош и где хош :), можно использовать листинги, тесты ДОС прог, методы... ;)
Финал её - подготовка минимальных GDT и IDT + переход в PM еще по адресам гдг лежит она сама (граница этапа СТУПЕНЬ 2)
3.0 Иниты нужных селекторов для дорабатывания задач 1й, но используя ме возможности PM и адресации. Скажем память тестовать надо тут, а вот с BIOSом работатьНАДО БЫЛО в 1й! :) Оптимальное распределение функций! Но! Для общего дела, блага оживания!
Тут пробы ВСЕх возможных аппаратных прерываний IRQ прописыванием их в IDT! Цель добить РЕАЛЬНО работу устройств,
особенно приводов, с тем чтобы он(и) были готовы и настроены (обработчики) для обслуживания ДРАЙВЕРОВ FS.
4.0 Переброс из 640 области (загрузочной локализации) остатков НУЖНОГО и ПРОВЕРЕННОГО кода ядра (например обработчик проверенного в ступени 2 прерывания мыши PS/2, в обрасть свыше 1мб и пропись её в IDT на место IRQ12. Теперь IRQ12 - табу для ВСЕХ кроме самого ядра! :)) Далее запуск дозагрузки нужных файлов, но драйвер FS тоже перемещен и подключен програмно, правда из тела СТУПЕНИ 2 где он лежал ПАССИВНЫМ ПРИЦЕПОМ. Теперь ядро может загружать все что нужно для дальнейшей жизни в том числе и файлы драйверов: звука, видеодрайвера, сетевого контроллера... но по строго очерченному типажу, списку, конечно, который готов, как результат, после СТУПЕНИ 2. Вот это и есть НАЧАЛО полноценного функционирования системы. Именно с этой временой отметки!
Опять я нафлудил на 5 рублей вместо 5 копеек обещанных, неисправим, блин! нУ ЛАДУШКИ, МОЖЕТ вЫ ВСЕ ЭТО БОГАйСТВО БЫСТРЕЕ НАШЕГО ВОПЛОТИТЕ... Берите, прочувствуйте, используйте!

Posted: Wed May 17, 2006 4:04 pm
by diamond
У меня есть конструктивное предложение. Пусть начальный загрузчик предоставляет callback-функции типа "прочитать/записать такой-то файл". И тогда loader.bin будет просто вызывать эти функции, когда надо будет прочитать/записать ядро или ini-файл. А разбором ini-файла будет заниматься уже сам. (Собственно, в текущей реализации что-то подобное сделано, но callback-функция только одна, "записать назад первый сектор ядра", и не принимает никаких параметров). Тогда автоматически отпадает необходимость повторно писать код разбора всех поддерживаемых файловых систем и добавляется совместимость с ещё не поддерживаемыми системами (интересно, кто-нибудь умеет загружаться с ext3fs?)

Posted: Wed May 17, 2006 5:49 pm
by Serge
А удастся запихнуть write_file в бутсектор? Конечно так можно сделать, но такое компромисное решение только маскирует проблему. И как быть если хочется держать систему не на С:\ а где нибудь на E:\OS\KOLIBLI\MAIN\053 ?

Posted: Wed May 17, 2006 6:00 pm
by diamond
Запись в существующий файл без изменения длины (или, по крайней мере, без изменения длины в секторах) - относительно несложная операция. С разбором папок с путями, конечно, сложнее, но всё равно бутсектор осуществляет разбор корневой папки, так что по идее чтение папки добавить можно.