Цією статтею я хочу допомогти всім, хто починає розбиратися зі створенням операційних систем і близько того, а саме з написанням MBR. У цій статті я постараюся розповісти про створення MBR.bin на практиці, і взагалі описати все це якомога більш детально і цікаво. Ну і писати ми, звичайно ж, будемо на FASM'е.
Про завантажувач загрузчиков
Цей сектор називається головного завантажувального запису (Master Boot Record - скорочено MBR). На початку MBR розташований машинний код завантажувача, за ним йде Таблиця Розділів (Partition Table), яка описувала схему розбиття логічних дисків. В кiнцi завантажувального сектора знаходиться сигнатура 55AAh, що говорить BIOS'у про те, що це дійсно MBR, а не щось ще.
Завантажувач повинен проаналізувати Таблицю Розділів, знайти кращий логічний диск, вважати його перший сектор (він називається завантажувальним - boot) і передати йому управління. Можна сказати, що він завантажує завантажувач ОС.
Структура для опису розділу
Зі структурою MBR розібралися, тепер приступимо до формування 512 байтного бінарники. Перше, що нам потрібно зробити - написати код завантажувача. Потім ми повинні скласти таблицю розділів диска і додати сигнатуру 55AAh. Зараз ми спробуємо написати простий завантажувач, що виводить повідомлення про етапи своєї роботи.
Отже, ось наш MBR:
; ці 2 директиви не займають місця в програмі.
; друга змушує компілятор генерувати 16 бітний код
Структура для LBA читання
Якщо читання з якоїсь причини не вдалося BIOS встановить прапор переносу. В цьому випадку стрибаємо на error, яка виведе повідомлення про помилку на 2й рядку (на 1й - 'MBR loaded') і повісить машину.
Далі йде код функцій, які виводять повідомлення про знаходження boot sector'а і про помилку. Впринципі їх робота вже описана вище, потрібно тільки сказати, що вони теж працюють через BIOSprintstring.
На цьому основний виконуваний код MBR закінчується. Але це ще не все. Ми ж ще не розглянули функції BIOSprintstring і BIOSreadkey, а також структуру для LBA читання. Наступний рядок за кодом - include 'BIOSFunctions.ink', значить пора розглянути BIOSreadkey і BIOSprintstring які, як видно з назви використовують переривання BIOS.
Щоб заощадити місце (512 байт не гумові) винесемо часто використовувані переривання в функції, які в свою чергу помістимо в .ink файл, який підключимо в кінці нашого MBR.
Ось як у нас буде виглядати файл BIOSFunctions.ink:
; чекаємо одним натисненням
Тут описані функції, які використовуються в нашому засобі завантаження.
Почнемо з BIOSprintstring. Вона витягує переданий код клавіші з стека, порівнює його з лічених з клавіатури і якщо вони співпадуть повертає управління який викликав коду, якщо немає - повторює ці дії знову.
Думаю варто пояснити чому саме sp + 02h. У перших двох байтах (так як код 16-і розрядний) у нас точка повернення з функції. Так як байти кладуться в пам'ять (а стек - це пам'ять) в зворотному порядку, то переданий байт, який ми кладемо в стек останнім (передаємо код клавіші як 00XXh) виявиться попереду.
Читаємо символ з клавіатури ми функцією 00h переривання int 16h. Після виклику переривання в al буде поміщений код натиснутоюклавіші.
Тепер висновок рядки - функція BIOSprintstring. Вона отримує зміщення рядки, довжину рядка, рядок і стовпець початку рядка, виводить рядок і повертає управління який викликав коду.
Тут ми отримуємо дані з стека інструкцією pop. Тому зберігаємо точку повернення. Зберігаємо ми її в регістр si, так як регістр bp зайнятий для переривання в функції.
Використовувати атрибут в bl, не чіпати курсор
Використовувати атрибут в bl, перевести курсор в кінець рядка
Використовувати формат рядка символ, атрибут; символ, атрибут ;. не чіпати курсор
Використовувати формат рядка символ, атрибут; символ, атрибут ;. перевести курсор в кінець рядка
Підфункції функції 13h переривання int 10h
Кольори тексту (ще 8 кольорів можна отримати встановивши біт яскравості)
Функції розглянули - на цьому код закінчується. Залишилися тільки структури даних.
Спочатку тут йдуть виведені MBR рядки, тут ми бачимо рядки англійською мовою, так як російських символів у нас немає такого змісту: 'MBR завантажений', Boot sector знайдений 'і' Помилка '.
Усе! Останні 2 байта вказують BIOS'у, що це дійсно MBR.