Завантаження операційної системи Hello world, dev64

Programming

Зміст

Що таке “завантаження Операційної системи”? Як уже згадувалося вище, виробники комп'ютерів постачають комп'ютер із встановленою програмою, званою BIOS. При включенні живлення або натисканні на кнопку Reset процесор комп'ютера починає виконувати програму з BIOS автоматично. Сам по собі BIOS мало корисний користувачеві, він дозволяє лише переглянути список пристроїв підключених до комп'ютера та зробити деякі налаштування. Більш того. Звичайному користувачеві комп'ютера, як правило, не доводиться в ці налаштування "лазити" і щось змінювати. Щоб комп'ютер перетворився на щось корисне, потрібно, щоб процесор почав виконувати якусь корисну програму, ніж BIOS. Ця програма і є операційною системою. BIOS вміє стартувати лише одну програму — Операційну систему. Операційна система, у свою чергу, надає користувачеві можливість запуску безлічі програм користувача. Процес передачі управління від BIOS до операційної системи і є завантаження операційної системи. Головна складність цієї передачі управління в тому, що з точки зору процесора при завантаженні операційної системи нічого особливого не відбувається. Процесор просто продовжує виконувати набір інструкцій доти, доки його не вимикають або не зустрінеться спеціальна інструкція HLT.

Комп'ютери та BIOS-и створюють одні компанії, а операційні системи пишуть інші компанії. Тому щоб процесор перейшов від виконання інструкцій BIOS до операційної системи, передбачена не проста передача управління, а ціла процедура (програма). Цю процедуру пишуть розробники операційної системи, а не виробники комп'ютера. Ця процедура називається Boot Loader(Завантажувач), що зберігається на носії, з якого завантажується операційна система. Найбільш відомими з досі підтримуваних носіїв, з яких може завантажуватися Операційна система, є Floppy Disk-і (дискети). Сьогодні, правда, Floppy Disk-і витіснені новими пристроями, типу CD/DVD приводів або USB Drive-ами. При експериментах зручно використовувати справжній комп'ютер, а віртуальну машину. Віртуальна машина замість справжніх дискет використовує звичайні файли, в яких зберігається вміст завантажувальної дискети, тому незважаючи на те, що дискети застаріли, з ними (віртуальними), як і раніше, зручно експериментувати. На малюнку налаштування моєї віртуальної машини. Видно що як floppy-диск підключений файл "D:\VM\hw.flp".

world

Перший експеримент

Хороший початковий експеримент описаний у статті: http://habrahabr.ru/tag/Пишемо свою ОС. Експеримент полягає в заміні Boot Loader простою програмою, яка виведе на екран рядок "Hello World!".

Програма безпосередньо із статті:

Для виконання експерименту потрібен асемблер: nasm або yasm. Обидва доступні для вільного завантаження в Інтернеті. Також простіше експериментувати із віртуальною машиною. Для цього підійде VMWare чи Bochs. Вochs – Open Source – проект. Перевага Bochs - маленький розмір і можливість налагодження вашої операційної системи, починаючи з моменту завантаження. Усього кілька мегабайт. VMWare – комерційний продукт, але для різноманітних експериментів надає для вільного використання VMWare Player. (Можливо, ще якісь продукти, політика неодноразово змінювалася). Перевага VMWare – швидкість. Працює дуже швидко.

Я помістив цей вихідний код файл hw.asm (hello world), і скомпілював:

Отриманий файл "hw" скопіювавшляхом D:\VM\hw.flp, налаштованому як віртуальний флоппі диска в VMWare. Стартував віртуальну машину і дійсно отримав бажане повідомлення Hello World!

Завантаження процесора мого комп'ютера, на якому працює VMWare, виявилося 50%:

Варто зазначити, що на ноутбуці, на якому я тестуюся, встановлений двоядерний процесор Intel. 50% завантаження означає 100% завантаження одного з ядер. Чи це випадково?

Код прикладу закінчується нескінченним циклом jmp$; вічний цикл

Цей цикл і вантажить одне із ядер процесора на 100%. Як цього уникнути? Згадаймо твердження “Процесор просто виконує послідовність інструкцій, доки його не вимкнуть або не зустрінеться спеціальна інструкція HLT”.

Перевірю це твердження. Заміню вічний цикл на 2 інструкції:

cli; забороняю апаратні переривання hlt; зупиняю процесор до виникнення апаратного переривання

hlt призводить до припинення виконання команд процесором до найближчого апаратного переривання. Але, оскільки апаратні переривання заборонені попередньою командою, процесор просто припиняє виконання програми. Зупиняється. Тест показує, що отримана на екрані картинка все та ж: "Hello World!". Проте завантаження процесора 0%.

world

У 512-байтному просторі Boot Loader-a залишається ще багато місця для розміщення справжнього Boot Loader-a, який завантажить "справжню" операційну систему.

Деякі кроки експериментів (наприклад, контроль завантаження процесора) легко зробити тільки в умовах віртуальної машини. На цій машині, якщо завантажувач підмінено на вищеописану програму “Hello World!”, завантаження процесора можна оцінити лише за гучністю вентилятора процесора. (Тому складно перевірити зупинку процесораінструкціями cli; hlt).

Що далі?

Наприклад, у наведеному прикладі виведення на екран здійснюється за допомогою переривання int 0x10. Послідовність команд виведе символ 'H' у поточну позицію курсору.

На додаток до наведених вище тверджень, я думаю (на даний момент), що функції BIOS доступні тільки з реального режиму процесора. Відповідно спочатку завантажувач повинен завантажити ядро, користуючись функціями BIOS, потім передати управління на завантажене ядро. Поки що не бачу обмежень на точку входу. І ще один цікавий момент – куди вказує стек, у момент завантаження? Який його розмір?

Згодом я провів експеримент з визначення стану регістрів процесора, в момент старту Boot Loader-a. Див. статтю за цим посиланням. Виявилося, що в VMWare, наприклад, при завантаженні з дискети стек вказує 0:3EC, що відповідає верхній частині таблиці переривань. ax=0x7C03 ds=0x40 sp=0:3EC, інші регістри дорівнюють 0. У регістрі dl BIOS передає ідентифікатор диска з якого завантажувався завантажувальний сектор. Для диска A: (дискети) значення 0.