Unreal mode - это круто! Не проще ли уж в этом случае все сделать в защищенном режиме и уже не возвращаться обратно в реальный. Я вообще считаю, что ядру для раскрутки не нужно много файлов. У меня, например, помимо самого ядра загрузчиком грузится лишь один модуль - драйвер загрузочного устройства/файловой системы. Все остальное, в том числе и конфигурационные файлы ядро подгружает в защищенном режиме с помощью этого драйвера, а базовые драйверы, прежде всего консольные, встроены в ядро. Я этой идеей пытался поделиться с Марио, но он, видимо, не воспринял ее серьезно, т.к. посчитал, что раз я не стал выкладывать свою систему по первому его требованию, то все это лишь мои теоретические изыскания и не более того.- Загрузчик должен перевести процессор в unreal mode, прочитать конфигурационный файл, а также всё то там написано средствами БИОС, и передать управление по указанному адресу, предварительно поместив адрес массива адресов загруженных файлов c последним элементом равным нулю в eax, в esp значение eax-4, а все остальные регистры обнулить.
Тех. Задание на Микро-Ядро
-
Синтаксис конфигурационных файлов - это детали, которые нужно хорошо "обтачивать", но только после того, как заготовки для них будут готовы. Про отдельный конфиг-лист для базовых драйверов мое мнение таково, что ядро должно в себя включать базовые драйверы (и только их), а как грузить само ядро и модули, жизненно необходимые для его раскрутки, пусть остается в сфере деятельности загрузчика и касается ядра лишь с точки зрения соглашения о том, куда само ядро и эти модули были загружены. Может кому-то будет интересно, как я использую конфигурационные файлы. Так вот у меня имеется два основных конфигурационных файла - первый для указания ядру, какие драйверы следует загрузить вне зависимости от того, кто и в каком режиме будет использовать систему (у меня поддерживаются два режима работы - обычный и режим настройки системы), а также какие каталоги следует примонтировать к корню файловой системы на все время работы ОС (последнее можно указать как через параметры драйверов, так и непосредственно с помощью спец. директивы); второй для указания того, какие пользователи могут регистрироваться в системе (регистрационное имя пользователя - логин, имя конфигурационного файла для этого пользователя и имя профильного файла для него). Структура конфиг. файлов для отдельных пользователей полностью аналогична основному конфигурационному файлу, однако все, что описано в нем будет автоматически выгружаться при завершении сеанса работы данного пользователя. Структура профайлов содержит пароль пользователя, его "полное" имя (поле расширяемое, предназначено для хранения персональной информации о пользователе, пока практически не используется) и имя персональной оболочки для этого пользователя.
Я эту тему поддержал, потому что тоже хочу участвовать в создании OC на АССЕМБЛЕРЕ(fasm), а тут вдруг Си и XML так-что тоже матерю)))
Я вообще упростил конфигурационный файл, чтоб его обработчик занимал всего несколько строк, только потому, что некоторое время думал, как сделать OS, легко переносимой на другие файловые системы и поддерживающую все виды носителей. Идея заключается в том, чтоб не делать никакого загрузчика, а код обработки загрузочного файла поместить в загрузочный сектор, который будет читать всё, что надо, средствами BIOS, и передавать управление на ядро.
т.е. При добавлении поддержки новой FS, просто сделать другой загрузочный сектор, а также сделать драйвер FS, который прописать в загрузочный файл.
А переводить процессор в PM, это ИМХО задача ядра, загрузщику всего-лишь нужно получить доступ к расширенной памяти.
Я вообще упростил конфигурационный файл, чтоб его обработчик занимал всего несколько строк, только потому, что некоторое время думал, как сделать OS, легко переносимой на другие файловые системы и поддерживающую все виды носителей. Идея заключается в том, чтоб не делать никакого загрузчика, а код обработки загрузочного файла поместить в загрузочный сектор, который будет читать всё, что надо, средствами BIOS, и передавать управление на ядро.
т.е. При добавлении поддержки новой FS, просто сделать другой загрузочный сектор, а также сделать драйвер FS, который прописать в загрузочный файл.
А переводить процессор в PM, это ИМХО задача ядра, загрузщику всего-лишь нужно получить доступ к расширенной памяти.
В защищённом режиме прерывания БИОС не доступны, пот в чём проблема.Unreal mode - это круто! Не проще ли уж в этом случае все сделать в защищенном режиме и уже не возвращаться обратно в реальный.
- Загрузчик также должен уметь пользоваться файловой системой, для чего нужно вынести функции работы с файловыми системами в отдельные .inc файлы, для последующего расширения возможностей.
Абсолютно верно, я вообще не использую вторичный загрузчик, т.к. все мои дисковые загрузчики справляются с задачей загрузки двух файлов в базовую память. Это мой принцип: дисковый загрузчик не обязан быть универсальным, т.к. отдельно взятый его экземпляр существует в окружении конкретной ФС и конкретного типа диска. Это обстоятельство кстати и позволило мне разместить весь необходимый код в одном секторе (FAT12, FAT16) и в двух секторах (FAT32).При добавлении поддержки новой FS, просто сделать другой загрузочный сектор, а также сделать драйвер FS, который прописать в загрузочный файл.
Согласен про перевод в 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-разрядные инструкции, прежде чем их использовать, а определить доступную память выше первого мега, чтобы грузить файлы имено в память, а не фиг знает куда, да много еще чего. В первичном загрузчике все это не поместится, поэтому нужно использовать либо вторичный загрузчик, либо тот вариант, о котором говорил я.Большая часть из приведённого кода уже присутствует в большенстве загрузчиков.
Действительно, линию А20 забыл открыть, но ведь это 3 строкиPhantom-84 wrote:А линию A20 открыть, чтобы можно было последовательно грузить файлы выше первого мега, а проверить, способен ли вообще проц выполнять 32-разрядные инструкции, прежде чем их использовать, а определить доступную память выше первого мега, чтобы грузить файлы имено в память, а не фиг знает куда, да много еще чего. В первичном загрузчике все это не поместится, поэтому нужно использовать либо вторичный загрузчик, либо тот вариант, о котором говорил я.Большая часть из приведённого кода уже присутствует в большенстве загрузчиков.
Code: Select all
; открываем адресную линию A20
in al, 92h
or al, 2
out 92h, al
Там всего-ли пару проверок можно оставить, ошибку при чтении диска и ошибку в синтаксисе загрузочного файла, и вообще избавится от всех текстовых строк и фукций для их вывода, они там больше всего занимают, а поставить элементарнейший код вывода ошибок.
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, одна проверяет всё и вся, а другая вообще ничего не проверяет, для чего? для производительности конечно...
Умножь эти три строки на 2 и возведи в квадрат, тогда может и получишь количество строк кода, дающего приемлемый результат для открытия A20 на разных машинах.Действительно, линию А20 забыл открыть, но ведь это 3 строки
Я не понял, а как же сами файлы, которые нужно грузить? Что если для их загрузки недостаточно памяти?Зачем проверять доступную для загрузки память и совместим ли процессор в начальном загрузчике? Может там ещё и остальное оборудование тоже проверить на всякий, ну и антивирь встроеный, а-то зачем вообще грузить OS, если там вирусы)))
Там всего-ли пару проверок можно оставить, ошибку при чтении диска и ошибку в синтаксисе загрузочного файла, и вообще избавится от всех текстовых строк и фукций для их вывода, они там больше всего занимают, а поставить элементарнейший код вывода ошибок.
Ну один набор функций предназначен для чисто внутреннего использования, там проверки выполняются на менее глубоких уровнях вложенности подпрограмм, а другой для независимого использования этих функций со стороны любого caller'а. Это вполне естественно и, думаю, практикуется во многих системах в том числе и в Линуксе.ИМХО Рантайм проверок должно быть необходимый минимум, это касается также и самого ядра, так как они очень сильно сказываются на производительности. Например если программа обращается к драйверу, он должен проверить каждый переданный параметр и обращаться к другому драйверу уже через доверенную функцию, чтоб то не начал снова перепроверять каждый параметр.
Я просматривал некоторые исходники линукса, так там эти проверки налепляны не то-что при меж-драйверном взаимодействии, но даже внутри одной и той-же динамической библиотеки, на 3-4 уровня в глубину, такого ИМХО допустить нельзя.
К примеру в NT реализовано 2 набора функций ядра, это Nt и Zw, одна проверяет всё и вся, а другая вообще ничего не проверяет, для чего? для производительности конечно...
Везде где встречаю открытие A20 вижу только этот код, а у тебя какой?Phantom-84 wrote:Умножь эти три строки на 2 и возведи в квадрат, тогда может и получишь количество строк кода, дающего приемлемый результат для открытия A20 на разных машинах.
Если там не хватает памяти для загрузки необходимой базы, то какой разговор может быть о работе системы на этой машине? Ещё можно выводить имена не найденных файлов, но это мелочи. Весь этот код вполне может поместится в бут сектор, некоторые туда целую ОС вписывают: http://board.flatassembler.net/topic.php?t=2164Phantom-84 wrote:Я не понял, а как же сами файлы, которые нужно грузить? Что если для их загрузки недостаточно памяти?
Короче эта дисскусия мне что-то напоминает, а конкретно - http://www.minix3.ru/articles/balet.pdf
У меня значительно длиннее. Ты вообще в курсе, что традиционный способ открытия A20 заключается в программировании контроллера клавиатуры? Твой вариант тоже используется, но не как альтернативный, а как один из возможных на конкретной машине. Ну и по причине последовательного применения нескольких способов открытия A20 (еще возможен вариант открытия через BIOS, хотя я его пока не использую) также необходим код, проверяющий факт открытия, что тоже не является тривиальной задачей, как может показаться на первый взгляд, из-за кэширования памяти.Везде где встречаю открытие A20 вижу только этот код, а у тебя какой?
О работе не может быть разговора, но нехватку памяти нужно детектить и выводить соответствующее сообщение, а не ждать, пока из-за этого возникнут ошибки.Если там не хватает памяти для загрузки необходимой базы, то какой разговор может быть о работе системы на этой машине?
Это не может быть осью по определению.Весь этот код вполне может поместится в бут сектор, некоторые туда целую ОС вписывают...
SHREDER, явного сходства не заметил, но вообще я за монолит с подгружаемыми модулями.
SHREDER спасибо, почитал, интересно, не знал что микроядерных ОС так много, ща миникс3 тестить буду)))
Что хорошо, в микроядерных ОС, это то, что их легко отлаживать, практически не нужно перезагружать, горячая загрузка и выгрузка драйверов, никаких руткитов, т.к. в нулевое кольцо попасть нельзя, читать память других процессов тоже можно запретить, у каждого драйвера строго отведённые права, единственное что может привести к краху системы, это ошибка в ядре или испорченное оборудование.
Я лично за микроядерные, даже за помещение драйверов в 3-е кольцо, кстати, никто серьёзно не рассматривал помещение их в первое кольцо как и планировал интел?
Что хорошо, в микроядерных ОС, это то, что их легко отлаживать, практически не нужно перезагружать, горячая загрузка и выгрузка драйверов, никаких руткитов, т.к. в нулевое кольцо попасть нельзя, читать память других процессов тоже можно запретить, у каждого драйвера строго отведённые права, единственное что может привести к краху системы, это ошибка в ядре или испорченное оборудование.
Я лично за микроядерные, даже за помещение драйверов в 3-е кольцо, кстати, никто серьёзно не рассматривал помещение их в первое кольцо как и планировал интел?
Это всего-лишь лоадер, ему не нудно заботится о том сколько памяти, хватает ли её для загрузки, загрузятся ли все нудные файлы, он ведь всё-равно их не будет исполнять, но их передаст ядру, которому по любому придётся проверить валидность каждого из них, вот тогда уже и сообщить пользователю, что загрузилось, что загрузилось не правильно, а что вообще не загрузилосьО работе не может быть разговора, но нехватку памяти нужно детектить и выводить соответствующее сообщение, а не ждать, пока из-за этого возникнут ошибки.
Who is online
Users browsing this forum: No registered users and 28 guests