Page 2 of 9

Posted: Wed Apr 25, 2007 10:12 pm
by Phantom-84
Синтаксис конфигурационных файлов - это детали, которые нужно хорошо "обтачивать", но только после того, как заготовки для них будут готовы. Про отдельный конфиг-лист для базовых драйверов мое мнение таково, что ядро должно в себя включать базовые драйверы (и только их), а как грузить само ядро и модули, жизненно необходимые для его раскрутки, пусть остается в сфере деятельности загрузчика и касается ядра лишь с точки зрения соглашения о том, куда само ядро и эти модули были загружены. Может кому-то будет интересно, как я использую конфигурационные файлы. Так вот у меня имеется два основных конфигурационных файла - первый для указания ядру, какие драйверы следует загрузить вне зависимости от того, кто и в каком режиме будет использовать систему (у меня поддерживаются два режима работы - обычный и режим настройки системы), а также какие каталоги следует примонтировать к корню файловой системы на все время работы ОС (последнее можно указать как через параметры драйверов, так и непосредственно с помощью спец. директивы); второй для указания того, какие пользователи могут регистрироваться в системе (регистрационное имя пользователя - логин, имя конфигурационного файла для этого пользователя и имя профильного файла для него). Структура конфиг. файлов для отдельных пользователей полностью аналогична основному конфигурационному файлу, однако все, что описано в нем будет автоматически выгружаться при завершении сеанса работы данного пользователя. Структура профайлов содержит пароль пользователя, его "полное" имя (поле расширяемое, предназначено для хранения персональной информации о пользователе, пока практически не используется) и имя персональной оболочки для этого пользователя.
- Загрузчик должен перевести процессор в unreal mode, прочитать конфигурационный файл, а также всё то там написано средствами БИОС, и передать управление по указанному адресу, предварительно поместив адрес массива адресов загруженных файлов c последним элементом равным нулю в eax, в esp значение eax-4, а все остальные регистры обнулить.
Unreal mode - это круто! Не проще ли уж в этом случае все сделать в защищенном режиме и уже не возвращаться обратно в реальный. Я вообще считаю, что ядру для раскрутки не нужно много файлов. У меня, например, помимо самого ядра загрузчиком грузится лишь один модуль - драйвер загрузочного устройства/файловой системы. Все остальное, в том числе и конфигурационные файлы ядро подгружает в защищенном режиме с помощью этого драйвера, а базовые драйверы, прежде всего консольные, встроены в ядро. Я этой идеей пытался поделиться с Марио, но он, видимо, не воспринял ее серьезно, т.к. посчитал, что раз я не стал выкладывать свою систему по первому его требованию, то все это лишь мои теоретические изыскания и не более того.

Posted: Wed Apr 25, 2007 10:16 pm
by hidden
Я эту тему поддержал, потому что тоже хочу участвовать в создании OC на АССЕМБЛЕРЕ(fasm), а тут вдруг Си и XML :? :wink: так-что тоже матерю)))

Я вообще упростил конфигурационный файл, чтоб его обработчик занимал всего несколько строк, только потому, что некоторое время думал, как сделать OS, легко переносимой на другие файловые системы и поддерживающую все виды носителей. Идея заключается в том, чтоб не делать никакого загрузчика, а код обработки загрузочного файла поместить в загрузочный сектор, который будет читать всё, что надо, средствами BIOS, и передавать управление на ядро.

т.е. При добавлении поддержки новой FS, просто сделать другой загрузочный сектор, а также сделать драйвер FS, который прописать в загрузочный файл.

А переводить процессор в PM, это ИМХО задача ядра, загрузщику всего-лишь нужно получить доступ к расширенной памяти.

Posted: Wed Apr 25, 2007 10:26 pm
by hidden
Unreal mode - это круто! Не проще ли уж в этом случае все сделать в защищенном режиме и уже не возвращаться обратно в реальный.
В защищённом режиме прерывания БИОС не доступны, пот в чём проблема. ;)

Posted: Wed Apr 25, 2007 10:42 pm
by Phantom-84
- Загрузчик также должен уметь пользоваться файловой системой, для чего нужно вынести функции работы с файловыми системами в отдельные .inc файлы, для последующего расширения возможностей.
При добавлении поддержки новой FS, просто сделать другой загрузочный сектор, а также сделать драйвер FS, который прописать в загрузочный файл.
Абсолютно верно, я вообще не использую вторичный загрузчик, т.к. все мои дисковые загрузчики справляются с задачей загрузки двух файлов в базовую память. Это мой принцип: дисковый загрузчик не обязан быть универсальным, т.к. отдельно взятый его экземпляр существует в окружении конкретной ФС и конкретного типа диска. Это обстоятельство кстати и позволило мне разместить весь необходимый код в одном секторе (FAT12, FAT16) и в двух секторах (FAT32).
А переводить процессор в PM, это ИМХО задача ядра, загрузщику всего-лишь нужно получить доступ к расширенной памяти.
Согласен про перевод в PM, но т.к. у меня нет вторичного загрузчика, а разместить в первичном помимо всего прочего еще и этот код действительно непосильная задача (я не имею в виду те ФС, в готорых размер бутблока позволяет гарантированно это сделать в любых обстоятельствах), то у меня (основное) ядро и драйвер грузятся загрузчиком в базовую память в реальном режиме. И уже во время инициализации ядро догружает себя с помощью драйвера загрузочного устройства (догружаемый модуль я называю икстендером).

Posted: Wed Apr 25, 2007 10:54 pm
by Phantom-84
В защищённом режиме прерывания БИОС не доступны, пот в чём проблема. ;)
Ну нереальный режим является все-таки недокументированной возможностью, а потом чтобы в него перейти, нужно прежде переключаться в PM. Я же описал то, как можно "большую" систему загрузить в чисто реальном режиме.

Posted: Thu Apr 26, 2007 2:01 am
by hidden
Phantom-84 wrote:
В защищённом режиме прерывания БИОС не доступны, пот в чём проблема. ;)
Ну нереальный режим является все-таки недокументированной возможностью, а потом чтобы в него перейти, нужно прежде переключаться в PM. Я же описал то, как можно "большую" систему загрузить в чисто реальном режиме.
А в реальном режиме не хватит памяти, чтоб загрузить туда все базовые драйвера, тем-более что код перевода в нереальный режим занимает всего несколько строк, вот пример, как я это делаю

Code: Select all

  boot_code:
        jmp     0x0:start
  start:

        cli                             ; Запрещаем маскируемые прерывания

        xor     ax, ax                  ; Предпологется что 32-х битное
                                        ; расширение и так равно нулю

        mov     es, ax                  ; Устанавливаем ss и ss в 0
        mov     ss, ax
        mov     sp, LOADER_BASE
        mov     di, LOADER_BASE + 512  ; Буффер для GDT сразу за образом

;***************************************************************************;
; Включаем нереальный режим
;***************************************************************************;
        ;shl     eax, 4
        ;add     eax, edi
        ;push    eax
        push    edi                     ; Сохраняем его
; Нудевой дескриптор
        ;xor     eax, eax
        stosd
        stosd
; Плоский дескриптор
        or      ax, -1
        stosd
        mov     eax, 0x00CF9200         ; Флаги плоского дескриптора
        stosd

        push    8 * 2                   ; Длина GDT для загрузки в GDTR
        lgdt    [esp]
        add     sp, 6

        in      al, 0x70                ; Запрещаем не маскируемые прерывания
        mov     bl, al
        or      al, 10000000b           ; Ставим 8й бит
        out     70h , al                ; некоторые RTC после записи байта в порт 0х70
        in      al, 0x71                ; ожидают обращения к порту 0x71

        mov     eax, cr0                ; Включаем PM (Protected mode)
        or      al, 1
        mov     cr0, eax

        mov     dx, 8                   ; Cмещение плоского элемента GDT
        mov     ds, dx                  ; Загружаем все сигментные регистры
        ;mov     es, dx
        ;mov     ss, dx
        ;mov     gs, dx
        ;mov     fs, dx

        and     al, not 1
        mov     cr0, eax                ; Отключаем PM

        sti                             ; Разрешаем маскируемые прерывания

        mov     al, bl                  ; Разрешаем не маскируемые прерывания
        out     0x70, al
        in      al, 0x71

        mov     dx, 92h
        in      al, dx
        or      al, 2
        out     dx, al
Большая часть из приведённого кода уже присутствует в большенстве загрузчиков.
Цитата:
- Загрузчик также должен уметь пользоваться файловой системой, для чего нужно вынести функции работы с файловыми системами в отдельные .inc файлы, для последующего расширения возможностей.
Я только потом додумался делать отдельные загрузчики для каждой ФС

Posted: Thu Apr 26, 2007 12:31 pm
by Phantom-84
А в реальном режиме не хватит памяти, чтоб загрузить туда все базовые драйвера
Ну я имел в виду начать загрузку в реальном режиме, а потом продолжить в защищенном и уже не возвращаться обратно в реальный. Мне всегда хватит полметра для основного файла ядра и 100 килобайт для драйвера загрузочного устройства. Весь код, обеспечивающий работу многозадачного режима, поддержку приложений и т.п., находится в икстендере.

Posted: Thu Apr 26, 2007 12:43 pm
by Phantom-84
Большая часть из приведённого кода уже присутствует в большенстве загрузчиков.
А линию A20 открыть, чтобы можно было последовательно грузить файлы выше первого мега, а проверить, способен ли вообще проц выполнять 32-разрядные инструкции, прежде чем их использовать, а определить доступную память выше первого мега, чтобы грузить файлы имено в память, а не фиг знает куда, да много еще чего. В первичном загрузчике все это не поместится, поэтому нужно использовать либо вторичный загрузчик, либо тот вариант, о котором говорил я.

Posted: Thu Apr 26, 2007 7:17 pm
by hidden
Phantom-84 wrote:
Большая часть из приведённого кода уже присутствует в большенстве загрузчиков.
А линию A20 открыть, чтобы можно было последовательно грузить файлы выше первого мега, а проверить, способен ли вообще проц выполнять 32-разрядные инструкции, прежде чем их использовать, а определить доступную память выше первого мега, чтобы грузить файлы имено в память, а не фиг знает куда, да много еще чего. В первичном загрузчике все это не поместится, поэтому нужно использовать либо вторичный загрузчик, либо тот вариант, о котором говорил я.
Действительно, линию А20 забыл открыть, но ведь это 3 строки

Code: Select all

    ; открываем адресную линию A20
    in	 al, 92h
    or	 al, 2
    out  92h, al
Зачем проверять доступную для загрузки память и совместим ли процессор в начальном загрузчике? Может там ещё и остальное оборудование тоже проверить на всякий, ну и антивирь встроеный, а-то зачем вообще грузить OS, если там вирусы)))
Там всего-ли пару проверок можно оставить, ошибку при чтении диска и ошибку в синтаксисе загрузочного файла, и вообще избавится от всех текстовых строк и фукций для их вывода, они там больше всего занимают, а поставить элементарнейший код вывода ошибок.

Code: Select all

NERR_READ_ERROR = 'R'
NERR_SYNTAX_ERROR = 'S'
        mov     ax, 0x0E00 + NERR_READ_ERROR
        int     0x10
        jmp     $
А уже для выявления причин самой ошибки сделать дополнительную утилиту, проверяющую синтакс загрузочного файла с выводом строки с ошибкой, да и вообще используемую для его конфигурирования под самой системой.

ИМХО Рантайм проверок должно быть необходимый минимум, это касается также и самого ядра, так как они очень сильно сказываются на производительности. Например если программа обращается к драйверу, он должен проверить каждый переданный параметр и обращаться к другому драйверу уже через доверенную функцию, чтоб то не начал снова перепроверять каждый параметр.
Я просматривал некоторые исходники линукса, так там эти проверки налепляны не то-что при меж-драйверном взаимодействии, но даже внутри одной и той-же динамической библиотеки, на 3-4 уровня в глубину, такого ИМХО допустить нельзя.
К примеру в NT реализовано 2 набора функций ядра, это Nt и Zw, одна проверяет всё и вся, а другая вообще ничего не проверяет, для чего? для производительности конечно...

Posted: Thu Apr 26, 2007 7:49 pm
by Phantom-84
Действительно, линию А20 забыл открыть, но ведь это 3 строки
Умножь эти три строки на 2 и возведи в квадрат, тогда может и получишь количество строк кода, дающего приемлемый результат для открытия A20 на разных машинах.
Зачем проверять доступную для загрузки память и совместим ли процессор в начальном загрузчике? Может там ещё и остальное оборудование тоже проверить на всякий, ну и антивирь встроеный, а-то зачем вообще грузить OS, если там вирусы)))
Там всего-ли пару проверок можно оставить, ошибку при чтении диска и ошибку в синтаксисе загрузочного файла, и вообще избавится от всех текстовых строк и фукций для их вывода, они там больше всего занимают, а поставить элементарнейший код вывода ошибок.
Я не понял, а как же сами файлы, которые нужно грузить? Что если для их загрузки недостаточно памяти?
ИМХО Рантайм проверок должно быть необходимый минимум, это касается также и самого ядра, так как они очень сильно сказываются на производительности. Например если программа обращается к драйверу, он должен проверить каждый переданный параметр и обращаться к другому драйверу уже через доверенную функцию, чтоб то не начал снова перепроверять каждый параметр.
Я просматривал некоторые исходники линукса, так там эти проверки налепляны не то-что при меж-драйверном взаимодействии, но даже внутри одной и той-же динамической библиотеки, на 3-4 уровня в глубину, такого ИМХО допустить нельзя.
К примеру в NT реализовано 2 набора функций ядра, это Nt и Zw, одна проверяет всё и вся, а другая вообще ничего не проверяет, для чего? для производительности конечно...
Ну один набор функций предназначен для чисто внутреннего использования, там проверки выполняются на менее глубоких уровнях вложенности подпрограмм, а другой для независимого использования этих функций со стороны любого caller'а. Это вполне естественно и, думаю, практикуется во многих системах в том числе и в Линуксе.

Posted: Thu Apr 26, 2007 10:55 pm
by hidden
Phantom-84 wrote:Умножь эти три строки на 2 и возведи в квадрат, тогда может и получишь количество строк кода, дающего приемлемый результат для открытия A20 на разных машинах.
Везде где встречаю открытие A20 вижу только этот код, а у тебя какой?
Phantom-84 wrote:Я не понял, а как же сами файлы, которые нужно грузить? Что если для их загрузки недостаточно памяти?
Если там не хватает памяти для загрузки необходимой базы, то какой разговор может быть о работе системы на этой машине? Ещё можно выводить имена не найденных файлов, но это мелочи. Весь этот код вполне может поместится в бут сектор, некоторые туда целую ОС вписывают: http://board.flatassembler.net/topic.php?t=2164

Posted: Fri Apr 27, 2007 2:32 pm
by SHREDER
Короче эта дисскусия мне что-то напоминает, а конкретно - http://www.minix3.ru/articles/balet.pdf

Posted: Sat Apr 28, 2007 7:58 pm
by Phantom-84
Везде где встречаю открытие A20 вижу только этот код, а у тебя какой?
У меня значительно длиннее. Ты вообще в курсе, что традиционный способ открытия A20 заключается в программировании контроллера клавиатуры? Твой вариант тоже используется, но не как альтернативный, а как один из возможных на конкретной машине. Ну и по причине последовательного применения нескольких способов открытия A20 (еще возможен вариант открытия через BIOS, хотя я его пока не использую) также необходим код, проверяющий факт открытия, что тоже не является тривиальной задачей, как может показаться на первый взгляд, из-за кэширования памяти.
Если там не хватает памяти для загрузки необходимой базы, то какой разговор может быть о работе системы на этой машине?
О работе не может быть разговора, но нехватку памяти нужно детектить и выводить соответствующее сообщение, а не ждать, пока из-за этого возникнут ошибки.
Весь этот код вполне может поместится в бут сектор, некоторые туда целую ОС вписывают...
Это не может быть осью по определению.

Posted: Sat Apr 28, 2007 8:04 pm
by Phantom-84
SHREDER, явного сходства не заметил, но вообще я за монолит с подгружаемыми модулями.

Posted: Sat Apr 28, 2007 10:08 pm
by hidden
SHREDER спасибо, почитал, интересно, не знал что микроядерных ОС так много, ща миникс3 тестить буду)))

Что хорошо, в микроядерных ОС, это то, что их легко отлаживать, практически не нужно перезагружать, горячая загрузка и выгрузка драйверов, никаких руткитов, т.к. в нулевое кольцо попасть нельзя, читать память других процессов тоже можно запретить, у каждого драйвера строго отведённые права, единственное что может привести к краху системы, это ошибка в ядре или испорченное оборудование.

Я лично за микроядерные, даже за помещение драйверов в 3-е кольцо, кстати, никто серьёзно не рассматривал помещение их в первое кольцо как и планировал интел?
О работе не может быть разговора, но нехватку памяти нужно детектить и выводить соответствующее сообщение, а не ждать, пока из-за этого возникнут ошибки.
Это всего-лишь лоадер, ему не нудно заботится о том сколько памяти, хватает ли её для загрузки, загрузятся ли все нудные файлы, он ведь всё-равно их не будет исполнять, но их передаст ядру, которому по любому придётся проверить валидность каждого из них, вот тогда уже и сообщить пользователю, что загрузилось, что загрузилось не правильно, а что вообще не загрузилось ;)