Тех. Задание на Микро-Ядро

No comments
  • Я эту тему поддержал, потому что тоже хочу участвовать в создании OC на АССЕМБЛЕРЕ(fasm), а тут вдруг Си и XML :? :wink: так-что тоже матерю)))

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

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

    А переводить процессор в PM, это ИМХО задача ядра, загрузщику всего-лишь нужно получить доступ к расширенной памяти.
  • Unreal mode - это круто! Не проще ли уж в этом случае все сделать в защищенном режиме и уже не возвращаться обратно в реальный.
    В защищённом режиме прерывания БИОС не доступны, пот в чём проблема. ;)
  • - Загрузчик также должен уметь пользоваться файловой системой, для чего нужно вынести функции работы с файловыми системами в отдельные .inc файлы, для последующего расширения возможностей.
    При добавлении поддержки новой FS, просто сделать другой загрузочный сектор, а также сделать драйвер FS, который прописать в загрузочный файл.
    Абсолютно верно, я вообще не использую вторичный загрузчик, т.к. все мои дисковые загрузчики справляются с задачей загрузки двух файлов в базовую память. Это мой принцип: дисковый загрузчик не обязан быть универсальным, т.к. отдельно взятый его экземпляр существует в окружении конкретной ФС и конкретного типа диска. Это обстоятельство кстати и позволило мне разместить весь необходимый код в одном секторе (FAT12, FAT16) и в двух секторах (FAT32).
    А переводить процессор в PM, это ИМХО задача ядра, загрузщику всего-лишь нужно получить доступ к расширенной памяти.
    Согласен про перевод в PM, но т.к. у меня нет вторичного загрузчика, а разместить в первичном помимо всего прочего еще и этот код действительно непосильная задача (я не имею в виду те ФС, в готорых размер бутблока позволяет гарантированно это сделать в любых обстоятельствах), то у меня (основное) ядро и драйвер грузятся загрузчиком в базовую память в реальном режиме. И уже во время инициализации ядро догружает себя с помощью драйвера загрузочного устройства (догружаемый модуль я называю икстендером).
  • В защищённом режиме прерывания БИОС не доступны, пот в чём проблема. ;)
    Ну нереальный режим является все-таки недокументированной возможностью, а потом чтобы в него перейти, нужно прежде переключаться в PM. Я же описал то, как можно "большую" систему загрузить в чисто реальном режиме.
  • 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 файлы, для последующего расширения возможностей.
    Я только потом додумался делать отдельные загрузчики для каждой ФС
  • А в реальном режиме не хватит памяти, чтоб загрузить туда все базовые драйвера
    Ну я имел в виду начать загрузку в реальном режиме, а потом продолжить в защищенном и уже не возвращаться обратно в реальный. Мне всегда хватит полметра для основного файла ядра и 100 килобайт для драйвера загрузочного устройства. Весь код, обеспечивающий работу многозадачного режима, поддержку приложений и т.п., находится в икстендере.
  • Большая часть из приведённого кода уже присутствует в большенстве загрузчиков.
    А линию A20 открыть, чтобы можно было последовательно грузить файлы выше первого мега, а проверить, способен ли вообще проц выполнять 32-разрядные инструкции, прежде чем их использовать, а определить доступную память выше первого мега, чтобы грузить файлы имено в память, а не фиг знает куда, да много еще чего. В первичном загрузчике все это не поместится, поэтому нужно использовать либо вторичный загрузчик, либо тот вариант, о котором говорил я.
  • 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, одна проверяет всё и вся, а другая вообще ничего не проверяет, для чего? для производительности конечно...
  • Действительно, линию А20 забыл открыть, но ведь это 3 строки
    Умножь эти три строки на 2 и возведи в квадрат, тогда может и получишь количество строк кода, дающего приемлемый результат для открытия A20 на разных машинах.
    Зачем проверять доступную для загрузки память и совместим ли процессор в начальном загрузчике? Может там ещё и остальное оборудование тоже проверить на всякий, ну и антивирь встроеный, а-то зачем вообще грузить OS, если там вирусы)))
    Там всего-ли пару проверок можно оставить, ошибку при чтении диска и ошибку в синтаксисе загрузочного файла, и вообще избавится от всех текстовых строк и фукций для их вывода, они там больше всего занимают, а поставить элементарнейший код вывода ошибок.
    Я не понял, а как же сами файлы, которые нужно грузить? Что если для их загрузки недостаточно памяти?
    ИМХО Рантайм проверок должно быть необходимый минимум, это касается также и самого ядра, так как они очень сильно сказываются на производительности. Например если программа обращается к драйверу, он должен проверить каждый переданный параметр и обращаться к другому драйверу уже через доверенную функцию, чтоб то не начал снова перепроверять каждый параметр.
    Я просматривал некоторые исходники линукса, так там эти проверки налепляны не то-что при меж-драйверном взаимодействии, но даже внутри одной и той-же динамической библиотеки, на 3-4 уровня в глубину, такого ИМХО допустить нельзя.
    К примеру в NT реализовано 2 набора функций ядра, это Nt и Zw, одна проверяет всё и вся, а другая вообще ничего не проверяет, для чего? для производительности конечно...
    Ну один набор функций предназначен для чисто внутреннего использования, там проверки выполняются на менее глубоких уровнях вложенности подпрограмм, а другой для независимого использования этих функций со стороны любого caller'а. Это вполне естественно и, думаю, практикуется во многих системах в том числе и в Линуксе.
  • Phantom-84 wrote:Умножь эти три строки на 2 и возведи в квадрат, тогда может и получишь количество строк кода, дающего приемлемый результат для открытия A20 на разных машинах.
    Везде где встречаю открытие A20 вижу только этот код, а у тебя какой?
    Phantom-84 wrote:Я не понял, а как же сами файлы, которые нужно грузить? Что если для их загрузки недостаточно памяти?
    Если там не хватает памяти для загрузки необходимой базы, то какой разговор может быть о работе системы на этой машине? Ещё можно выводить имена не найденных файлов, но это мелочи. Весь этот код вполне может поместится в бут сектор, некоторые туда целую ОС вписывают: http://board.flatassembler.net/topic.php?t=2164
  • Короче эта дисскусия мне что-то напоминает, а конкретно - http://www.minix3.ru/articles/balet.pdf
  • Везде где встречаю открытие A20 вижу только этот код, а у тебя какой?
    У меня значительно длиннее. Ты вообще в курсе, что традиционный способ открытия A20 заключается в программировании контроллера клавиатуры? Твой вариант тоже используется, но не как альтернативный, а как один из возможных на конкретной машине. Ну и по причине последовательного применения нескольких способов открытия A20 (еще возможен вариант открытия через BIOS, хотя я его пока не использую) также необходим код, проверяющий факт открытия, что тоже не является тривиальной задачей, как может показаться на первый взгляд, из-за кэширования памяти.
    Если там не хватает памяти для загрузки необходимой базы, то какой разговор может быть о работе системы на этой машине?
    О работе не может быть разговора, но нехватку памяти нужно детектить и выводить соответствующее сообщение, а не ждать, пока из-за этого возникнут ошибки.
    Весь этот код вполне может поместится в бут сектор, некоторые туда целую ОС вписывают...
    Это не может быть осью по определению.
  • SHREDER, явного сходства не заметил, но вообще я за монолит с подгружаемыми модулями.
  • SHREDER спасибо, почитал, интересно, не знал что микроядерных ОС так много, ща миникс3 тестить буду)))

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

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

    Users browsing this forum: No registered users and 9 guests