середа, 22 березня 2017 р.

Нарешті стартовий код

Колись я тут згадував за "стартовий код". Коли, рік тому? Не пам'ятаю точно. І лише зараз можу хоч шось сказати про зроблене в цьому плані.

Іронія, перший стартовий код, код який насправді можна закинути на реальну машину і запускати і дивитись, шо він робить, він у мене вийшов таки на MIPS архітектурі. :) Так склалось, знайшов схожий проєкт (клікни мене), він допоміг зрозуміти як починати програмувати апаратуру, бо знаєте, та купа зваленої інформації під назвою TRM від TI, не дуже цьому допомагала, того хоч Beagle Bone Black і стояв першим в черзі, Mips Creator CI20 вийшов першим.

По-перше, ми відкинули імплементацію Pei фази. Бо тут на йоді, дуже мало TCSM, а по-друге - з часом стало ясно, шо Pei і Dxe дуже сильно дублюють одне одного, а все ж мають трохи різні внутрішні організації. Вийшла б зайва робота, більше помилок. Обов'язок ініціалізувати SDRAM перейшов на SEC. А всю решту робитиме Dxe. Зміна насправді не дуже істотна.

Почитавши і подивившись на схожий проєкт, ми вирішили взятися за те, шо завсіди називали "стартовий код". Шоб збудити проєкт, який до цього писався лише в стіл так би мовити - бо код же Boot Service'ів, наприклад, сам по собі не поганяєш. Ця частина - стартовий код - дуже особлива, вона і має емоційний ефект від запускання на реальній машині, і, також, - дає великий поштовх, впевненість в собі, бо якшо це вдалося, думаєш, значить, ти можеш написати і ФВ і ОС. :)

От ми й узялися за нього. І так вийшло, шо попри більшу ознайомленість на той момент з ARM'ом, ніж з MIPS'ом, саме останній став першою архітектурою, де це сталося. Тепер я можу сказати, шо знаю обидві архітектури однаково. Однаково пагано, :D але однаково.

Перший запуск ясно шо не працював. Виявилось не працював він через неправильну лінкувальну адресу образу, і переплутане описання багатьох речей в мануалі, в убутових вихідних кодах... Далі наш код нарешті показав ознаки керування машиною - першим, шо він зробив було перемикання наплатного LED з червоного на синій колір. Далі ми надрукували в послідовний порт перше слово - воно вийшло "UefiUefi". Скриншот цього я виклав в твітер, і цей допис навіть ретвітнули люди з Imagination. Отако. Потім я нарешті виявив помилку з адресою, і зміг викликати власні функції - це дало можливість друкувати більше, ми привітали світ і Гаврилівну! і надрукували трохи потрібних регістрів. Потім взялися за PLL. І тут були помилки, прикрі, але зважаючи на те яке це складне діло ті PLL, можна сказати, з цим вийшло все не так важко. І ми тепер ініціалізували дві з чотирьох PLL - APLL (для процесора і його кешу 2-го рівня) і MPLL (для пам'яти і AHB шин (а значить і для периферії)). Ми виставили вихідну частоту APLL на 1200 МГц, це якраз максимальна рекомендована частота процесора на йоді, MPLL виставили на 400 МГц, знову ж з прицілом на 400 МГц для DDR3 і AHB0 шини. Але ділителі для цих кореневих компонентів ми зробили такими, шо принаймні поки вони бігають на значно менших частотах. Далі буде видно, але це ж фірмваря. Конкретніше частоти такі:
КомпонентДжерело тактівДілительЧастота, МГц
APLLEXTCLK(50/2/1)1200
MPLLEXTCLK(50/6/1)400
CPUAPLL (SCLK_A)6200
L2APLL (SCLK_A)12100
AHB0MPLL4100
AHB2MPLL4100
PCLKMPLL850
От. А тепер ми хочемо налаштувати таймери - Watchdog і OS таймери, перший, шоб уникнути безкінечного зависання, ми думаємо виставити його ресетити плату після 3 хвилин  нічогонеробіння - так наприклад ром-код мурана робить. Ясно, шо нам в нормальному плині, треба незадовго до краю цього терміну, скидати лічильник, ну сторожовий собака. Другий, це серце системного коду, фірмварі, ОС. Тут він нам потрібен практично для ефективного чекання на довгих інтервалах, де busy wait виглядає неприйнятним, а такі інтервали будуть в ініціалізації SDRAM, і нам там потрібно чекати коло 400 мс. От для цього. Але шоб це справді було ефективне нічогонеробіння, одних таймерів мало. Треба ще налаштувати контроллер переривань, і, звичайно, надати відповідні обробники. Це не буде "занадто" для цієї фази. Навіть специфікація UEFI зобов'язує підтримувати обробку переривань від таймера, і використовувати це. Не кажучи вже за ОС. А оскільки все шо треба робити у нас уже перед очима, нема ніяких причин відкладати це на потім. Тим паче, як ми вже казали, нам це потрібно вже тут і зараз.

От на цьому ми поки зупинилися - на таймерах і контроллері переривань. Багато ще треба
робити, шоб мати шось юзабельне, але все ж уже неможна сказати, шо ми лише теоретизуємо,
стартовий код уже є!
А це один з скриншотів його роботи. Тут ми вже налаштували PLL. Та це вчора було. :)