Вопрос по созданию ос
В первой версии моей ос я планирую сделать аллокатор оперативной памяти, который, при запуске будет создавать два взаимодействующих процесса: обработчик клавиатуры, который будет считывать введённые символы и передавать их процессу отвечающему за вывод сообщений на экран.
Пока что возник вопрос как работает аллокатор памяти и как его реализовать. Помогите чем сможете.
"Решите мне задачу", "научите меня программировать" -- это уже знакомо и привычно, но вот "напишите мне ОС"...
Можно посмотреть здесь.
Если хочется большего, то можно почитать книжку Таненбаума "Операционные системы" и поизучать исходники minix.
Для микроконтроллера, ОС написать наверно проще. Микроконтроллер - это готовый однокристальный компьютер. ОС для МК очень мало весят. Например ScmRTOS, кстати там есть описание на русском здесь. А, и вот еще, достаточно подробный курс.
Съесть?
каждый просит того чего не хватат ) кому то гвоздей.
Съесть?
Купить, приобрести, и прочее, но если съесть чужие мозги какого нибудь там доктора наук то может быть поможет)))))
вам лучше обратится на форум поваров с просьбой изготовить съедобный гвоздь . :)
Выигравший поедает мозги проигравшего.
Ну а если без шуток, то мне самому знакома трудность поиска именно для меня важной информации среди файловой помойки. Вот например.
Более конкретные вопрос. Немного подумав над тем как должен работать этот самый менеджер памяти я пришёл к выводу, что каждой программе даётся какоето ограниченное кол-во оперативной памяти. Это так?
Еще немного и ваши посты можно будет на анекдоты разбирать.
Есть такая штука, называется "виртуальная память".
Более конкретные вопрос. Немного подумав над тем как должен работать этот самый менеджер памяти я пришёл к выводу, что каждой программе даётся какоето ограниченное кол-во оперативной памяти. Это так?
Здравствуйте!
Если говорить конкретно про менеджер управления памятью, то в современных машинах есть модуль MMU (Memory managment unit). Если Вы хотите написать что-нибудь достойное внимания, без него Вам не обойтись. Рискну предположить, что менеджеры памяти давно не пишутся на ассемблере. Вероятно, есть библиотеки для более "высоких" языков. Но только ассемблер дает возможность полного контроля ресурсов системы. Так что, и его Вам придется подучить.
С вашими текущими знаниями еще рано планировать, какова будет структуры вашей ОС.
Начните с чего-нибудь попроще.
К примеру, установите DOS в virtualbox и попробуйте:
а) написать хоть какую-нибудь программу под DOS
б) написать что-нибудь на ассемблере
в) написать программу под DOS, перехватывающую прерывание от клавиатуры (это называется резидентная программа) и при каждом нажатии выводящую что-нибудь на экран непосредственно через видеопамять
В процессе решения этих промежуточных задач вы получите необходимые вам знания.
А если что-нибудь конкретное не получится (поначалу обязательно не получится), то вопрос следует задавать по следующей схеме:
Я сделал {...} и {...} (вставка фрагмента кода).
Должно было получиться {...} (последовательность рассуждений, почему так должно было получиться),
но получилось {...}. Объясните, что в моих рассуждениях не так.
Тогда будет легче ответить вам что-нибудь осмысленное.
Чтобы сделать что-то свое надо понять в чем оно. Вы так хорошо знаете Linux и другие ОС? Сами же пишите:
Это как раз правильная установка.
Я хочу чтобы по нажатию клавиатуры символ выводился на экран. Для этого я решил после прерывания int 16h проверить регистр
al. Если он равен 0 то моя программа повторяет цикл. Если не равен то программа должна вывести нажатый символ на экран.
Но после серии тестов я понял что в регистре al если не нажата ни одна клавиша содержится пробел и моя программа выводит
на экран этот самый пробел, причём только один. помогите разобраться в чём проблема.
; --------------------------------
[ORG 0x7C00]
start:
cli
mov ax, cs
mov ds, ax
mov ss, ax
mov sp, start
sti
call print
keyboard:
int 0x16
test al, al
call keyboard
call print
print:
mov ah, 0x0E
int 0x10
call keyboard
times 510-($-$$) db 0
db 0xAA, 0x55
1. Запретить прерывания;
2. Сохранить адрес функции 01h прерывания 21h в один из регистров;
3. Записать на его место адрес своей функции;
4. Разрешить прерывания.
В самой функции вызвать функцию 01h прерывания 21h по адресу, сохраненному в п. 2.
P.S. В ассемблере не асс, поэтому пишу текстом.
Я хочу чтобы по нажатию клавиатуры символ выводился на экран. Для этого я решил после прерывания int 16h проверить регистр
al. Если он равен 0 то моя программа повторяет цикл. Если не равен то программа должна вывести нажатый символ на экран.
Но после серии тестов я понял что в регистре al если не нажата ни одна клавиша содержится пробел и моя программа выводит
на экран этот самый пробел, причём только один. помогите разобраться в чём проблема.
Резидентная программа и загрузчик -- это совершенно разные вещи. Но можно начинать и с загрузчика.
На всякий случай расскажите, как вы его запускаете. Самый простой способ -- подключать вашу программу (после компиляции) как образ дискеты в virtualbox и давать команду загрузиться с этой дискеты.
Здесь полная фигня написана
keyboard:
int 0x16 ; А почему не задан параметр? Параметры для прерываний BIOS можно посмотреть здесь: http://www.codenet.ru/progr/dos/
test al, al ; Это сравнение AL с нулем. Результат сравнения нигде не используется. Чего вы хотели этим добиться?
call keyboard
call print ; До это строки выполнение не дойдет никогда, так как в процедуре keyboard отсутствует команда возврата.
print:
mov ah, 0x0E ; А почему у прерывания 0x10 задан только один параметр? Не задано, какой собственно символ будет выводиться.
int 0x10
call keyboard ; Опять вызов процедуры с сохранением текущего адреса в стеке. При этом ни одной команды завершения процедуры у вас нет. В keyboard опять вызывается print, происходит бесконечная рекурсия, и переполняется стек. Разберитесь, что делают команды jmp, call и ret
db 0xAA, 0x55
start:
cli
mov ax, cs
mov ds, ax
mov ss, ax
mov sp, start
sti
1. Запретить прерывания;
2. Сохранить адрес функции 01h прерывания 21h в один из регистров;
3. Записать на его место адрес своей функции;
4. Разрешить прерывания.
В самой функции вызвать функцию 01h прерывания 21h по адресу, сохраненному в п. 2.
P.S. В ассемблере не асс, поэтому пишу текстом.
Это инструкция, как переопределить прерывание 21h. В общих чертах все правильно, но не совсем к месту, так как zelyak2 сейчас совершенно другое пытается сделать.
Ой... просмотрел, что речь о загрузчике и настройке вектора прерывания. Тогда, может BIOS, работа с диском пригодится?
как мне использовать результат сравнения с нулём и выйти из цикла keyboard?
забыл объяснить что call print в начале забыл удалить. Я сначала сделал программу которая просто выводил на экрна один символ. Потом начал
переделывать и забыл удалить эту комнаду
вот как я понимаю этот фрагмент кода
start: ; начинается главная подпрограмма
cli ; заперщаем прерывания
mov ax, cs ; заполняем регистры нулями
mov ds, ax
mov ss, ax
mov sp, start ; вот это я не совсем понял
sti ; разрешаем прерывания
Да, и еще. Сейчас BIOS плавно меняется местами с UEFI (например, т.к. в Википедии информация скудная). Кто что может сказать об особенностях загрузки ОС через UEFI?
Не совсем.
В первых 512 байтах загрузочного раздела находится первичный загрузчик, который загружает с заданного адреса на диске вторичный загрузчик (имеющий намного больший размер). Вторичный загрузчик уже много чего умеет и понимает файловую систему.
При большом желании можно поставить Linux на NTFS, но обычно это не требуется.
как мне использовать результат сравнения с нулём и выйти из цикла keyboard?
1) Результат сравнения используется командами условного перехода, такими как jz, jnz и т.д. Я не буду копировать сюда документацию, пользуйтесь гуглом.
2) Еще раз повторю: у вас нет никакого цикла keyboard. call -- это команда вызова процедуры. Ищите информацию про отличие цикла и рекурсии, про стек вызовов, про call, ret и jmp
3) Также еще раз повторю, что у вас неправильно указаны параметры прерываний.
Вы так и не сказали, как вы компилируете и запускаете вашу программу. Это тоже имеет значение.
забыл объяснить что call print в начале забыл удалить. Я сначала сделал программу которая просто выводил на экрна один символ. Потом начал
переделывать и забыл удалить эту комнаду
вот как я понимаю этот фрагмент кода
start: ; начинается главная подпрограмма
cli ; заперщаем прерывания
mov ax, cs ; заполняем регистры нулями
mov ds, ax
mov ss, ax
mov sp, start ; вот это я не совсем понял
sti ; разрешаем прерывания
ORG 0x7c00 вовсе не означает переход.
Это указание транслятору, что если в вашей программе есть, например, строковая константа (str: db "Hello, world!"), то метку str следует использовать со сдвигом на 0x7c00 (т.к программа будет загружена со сдвигом 0x7c00 от начала оперативной памяти).
start: - это объявление метки на текущее место в программе. Это самое начало программы, поэтому start будет иметь значение 0x7c00 (так как ORG 0x7c00 задает, что отсчет начинается именно с этого числа).
Запрет и разрешение прерываний действительно делается командами cli и sti, но я не очень понимаю, зачем их здесь запрещать. Впрочем, хуже от этого не будет.
Дальше. Это не совсем заполнение нулями.
Происходит копирование из CS в DS и SS через промежуточный регистр AX. Это так нызваемые сегментные регистры. Разберитесь, зачем они нужны.
Команда mov sp, start настраивает, откуда будет начинаться стек. У вас стек будет начинаться от 0x7c00 (метка start) в сторону уменьшения. Стек -- это то, что портится, когда вы используется call вместо jmp.
И напоследок: вот описание распределения оперативной памяти в первом мегабайте. Unused - это то, что можно использовать. Сейчас ваш стек расположен в первой из областей, обозначенных Unused
- 0x00000000 - 0x000003FF - Real Mode Interrupt Vector Table
- 0x00000400 - 0x000004FF - BIOS Data Area
- 0x00000500 - 0x00007BFF - Unused
- 0x00007C00 - 0x00007DFF - Our Bootloader
- 0x00007E00 - 0x0009FFFF - Unused
- 0x000A0000 - 0x000BFFFF - Video RAM (VRAM) Memory
- 0x000B0000 - 0x000B7777 - Monochrome Video Memory
- 0x000B8000 - 0x000BFFFF - Color Video Memory
- 0x000C0000 - 0x000C7FFF - Video ROM BIOS
- 0x000C8000 - 0x000EFFFF - BIOS Shadow Area
- 0x000F0000 - 0x000FFFFF - System BIOS
С заданного абсолютного адреса головка:цилиндр:сектор без учета файловой системы, правильно? Или BIOS давно понимает LBA?
Таков дзэн дикой лисы.
PS: Впрочем как и весь тред.