Перейти до вмісту

"Мій нікому нецікавий блоґ" або записки за UEFI.

GPT UEFI FAT

Повідомлень в темі: 146

#121 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 20.05.2017 – 18:44

Невеличка нотатка стосовно простору імен Об'єктного Менеджера (ОбМ) і іменування пристроїв.
Аналізуючи організацію ОбМ і іменування пристроїв в нашій системі, стало ясно, шо найкраще взагалі оминати іменування пристроїв загалом. Бо проблема не в тому як назвати пристрій - mmcblk0 чи ROOT#AHB1#EMMCC__this_is_eMMC_{cafebabe-aeea-1122-099812345ab1}, а в тому, шо в високодинамічних сучасних системах, де будь який пристрій може бути довільно витягнений, взагалі ці імена не дають гарантії, шо в наступний момент, це ім'я означатиме той самий пристрій, хай які акробатичні трюки з "прив'язування" цього імени до конкретного пристрою система робитиме. Це PnP, бейбі, тож ці імена це пшик, краще взагалі на них не покладатися.
Тож покишо, в наших планах є виключити "конвенційні" імена пристроїв з простору імен ОбМ. Яке всеодно лишається для тих об'єктів, які, все ж, потребують іменування. Це переважно там, де йде інтерфейс з користувачем, або ж програмістська зручність.
Наприклад дерева файловосистемних ієрархій, ми вже казали за них, це круто, це потрібно - користувач так адресує свої файли. Замість ліпити все на один корінь, як робе Уних, ми як це є в Віндовс, ще з часів Дос, маємо по кореню для кожного тому. А розрізняємо їх літерами. Ці літери і є конвенційне ім'я для тому. І воно потрібне. Воно теж динамічне, за винятком завантажувального тому (диск C:), в тому сенсі, шо якась програма має бути готова, шо через 3 хвилини, образно кажучи, диск D: наприклад, де користувач сконфіґурував класти кеш цієї програми (ми балакаємо за бравзер тут), шо цей диск може несподівано зникнути - наприклад це був зовнішній усб-диск, підключений ззовні до живлення в обхід ДжПЖ - свєт вимкнули, компутер живиться від ДжПЖ, диск "зник".
Але тут принаймні система може ґарантувати певний рівень консистентости між "сесіями" - наприклад використовуючи GPT, ми можемо, беручи GUID'и диску, його партицій, запам'ятовувати їх, і потім, коли вони повернуться в систему - присвоїти їм те саме конвенційне ім'я. Та й не дивлячись на високу динамічність, ми не можемо оминути тут іменування диску/тому - це частина шляху файла, тут іменування чітко і ясно потрібне.
Суть іще купа, ну купка, сценаріїв, де конвенційне іменування потрібне.
Але переважно, коли йдеться про доступ до пристроїв, відчувається, шо треба шось інше.
Поки шо ми придумали таке.
Всі пристрої очевидно групуються за функціональністю - за тим, шо вони роблять. Клавіатури, миші, пристрої сховища, послідовні порти, паралельні порти, принтери тощо. Тут теж не все супер ясно, але більш менш чітко.
І очевидно, - коли користувач або користувацька програма, хоче доступитися якогось пристрою, вона це робе на базі його функціональности, яка її цікавить. Наприклад програма, яка обслуговує т. зв. термінальне з'єднання, шукатиме послідовні порти. А Скайпу потрібна камера. І так далі. Тож ключем у пошуку є функціональність. А далі, найшовши групу пристроїв з потрібною функціональністю, лише кінцевий користувач (програма або людина) має вирішувати - вибрати перший пристрій, який попався в цьому класі, чи продовжувати шукати, базуючись на якихсь ще критеріях розрізнення, які тільки цьому користувачеві й відомі. Логічно?
Отже, зважаючи на абзац вище, з пристроями, до яких користувачеві можливо треба буде доступатися, адресуючи їх якось, ми встановлюємо таку схему доступання. Ми викидаємо конвенційне іменування, як таке яке нічого не дає, і звільняємо ПІ ОбМ від цієї валізи без ручок. І представляємо інший механзім. Молодьожніший.
Ми, система, а також будь хто інший, визначаємо набір класів інтерфейсів пристроїв, в якому кожен інтерфейс ідентифікується теж іменем, але не рядковим, а GUID'овим - це ґарантує унікальність (відсутність цих неприємних колізій), і це швидше для роботи між іншим. А далі, кожен клас має зразки. Скільки в системі пристроїв, які зареєструвались як такі, шо належать до цього класу, стільки й зразків. Користувач може запитати набір цих зразків (тих, які він має право запитувати, ясно шо), і, якшо йому треба якийсь саме той, а не інший пристрій з цього класу, він уже має сам це вирішувати перебираючи усі варіанти і витягуючи якусь допоміжну пристрій специфічну інформацію.
Внутрішньо це планується бути імплементоване як словник класів - червоно-чорне дерево, ключами в якому будуть GUID'и інтерфейсів. На кожному вузлі такого дерева сидітиме масив об'єктів пристроїв, які належать до цього класу. Все як з деревом протоколів в нашій UEFI імплементації.
Наприклад уявімо ми хочемо (і можемо) доступитися жорсткого диску насиро, тобто в обхід ФС. Шо ми маємо робити?
Власне нам треба відкрити цей пристрій. А для цього, його ще потрібно знайти.
Як ми відкриваємо пристрій в такому випадку?
Шось накшталт:

handle = CreateFile("\.\PhysicalDrive0");
чи
file = open("/dev/sda");

Оці "PhysicalDrive0" чи "sda" - це конвенційні імена. І вони і близько не можуть сказати, шо за тим іменем стоїть. Середовище високодинамічне, пам'ятаємо. Навіть внутршні ЖД легко можна витягти під час роботи системи. Шо там вже казати за усб диски наприклад. А сурпрайз ремовал не забуваємо ще.
Тож, як нам знайти потрібний диск і не написати наприклад шось на ваш основний ЖД заміть флешки? Програма, або ви самі, або ви разом, маєте за допомогою магії додаткових критеріїв перебрати усі пристрої того ж класу, і вибрати саме той, шо треба. Це просто природа цього завдання.
Тож замість робити ілюзію розрізнення цими незручними для програм рядковими літералами, ми вводимо швидший і природніший для ситуації механізм пошуку по класу.
Ми запитуємо шось накшталт:

EnumerateInstances(OurDeviceClassGuid, &instances, &NumberOfInstances);

Відзначте, одразу, за один запит, ми отримуємо список всіх зразків. І оце OurDeviceClassGuid, - це число між іншим, програмі з ним значно зручніше працювати, ніж морочитися з багатослівними рядками.
А потім, якшо треба, шукаємо глибше, питаючи користувача чи самі якось вирішуємо.

for(i=0; i<NumberOfInstances; i++){
   answer = AskUserAbout(GetSomeAdditionalInfo(instance[i]));
   if(answer == YES)break;
}
DoTask(instances[i]);

Власне ми причепурюємо цей процес, не вдаючи, шо маніпулювання рядками тут це круто. Ні, тут воно не круто, і ми його не використовуємо.
  • 0

#122 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 12.06.2017 – 22:53

Нічого цікавого насправді, просто рішив зробити з блога трохи щоденник, роблячи коротенькі записки про зрушення.
Отже зараз всі думки в керування пам'яттю. Це дуже складна тема. Але нам треба мати таке сяке керування пам'яттю вже зараз - на цьому базується вся решта. Маючи грунт тут, ми можемо братися за фреймворк для драйверів - тобто Менеджер введення/виведення (В/В), PnP менеджер і павир менеджер. Не забуваючи про Об'єктний і Конфігураційний Менеджери.
Головна проблема на нашій міпс платформі з керуванням пам'яттю - це неефектиність використання 4 КБ-них сторінок. Значно ефективніше було б використовувати різні розміри, і більші за 4 КБ головно. Це б зменшило кількість TLB промахів. Але це ускладнює керування пам'яттю. Треба вигадати ефективну організацію PFN db (page frame number database) - структури, яка веде облік станів і алокації фізичної пам'яти.
Коротко наша модель пам'яти буде така:
В ядрі ми матимемо два регіони для динамічної алокації пам'яти - Paged Pool і Non-Paged Pool, сторінкований і несторінкований ставки. :) Сторінки в першому можуть скидатися на заднє сховище, де це можливо, в другому не можуть.
На міпсі, ми використовуватимемо таку архітектурну можливість як тривіальне відображення, це коли VA-PA трансляція відбувається без участи MMU, просто відніманням константи, я розказував за це, є такі сегменти як kseg0 і kseg1, які якраз мають таку властивість. На йоді, ми маємо аж 256 МБ простору для цього. Тобто, віртуальні адреси (зона ядра) від 0x80000000 по 0xa0000000 (kseg0), і від 0xa0000000 по 0xc0000000 (kseg1), вказують на ту саму ділянку системного простору (від 0x00000000 по 0x20000000), і не потребують картування (і значить залучення MMU з TLB). Все ядро, крім частини кешу, ми кластимемо сюди. Це архітектурна оптимізація. Нагадаю, kseg0 і kseg1 вказують на ту саму системну пам'ять (тобто вони аліаси на міпсі), але можуть відрізнятися атрибутикою кешованости - kseg0 може бути зроблений кешованим, - це нормальний сценарій, ми хочемо використовувати кеш в ібльшости випадків (під кешем тут мається на увазі процесорні кеші 1-го і 2-го рівнів).
Таким чином в ядрі, а ми покишо лише за нього, ми маємо таку карту пам'яти ПАП (процесорний адресний простір, те саме, шо віртуальний адресний простір):
  • 80000000 - 90000000 - це ті самі 256 МБ, за які ми казали, тут ми на них дивимося з боку kseg0 - кешованого сегменту ПАП, який ми переважно використовуватимемо. Саме тут сидітимуть Run-Time сервіси UEFI (якшо ми не зуміємо посадити їх в TSCM - суто платоформна можливість), конфігураційні таблиці від фірмварі (самопальні, ACPI, ще шось), тут опиниться наш OSLoader.efi - UEFI застосунок завантажувач нашої ОС. Сама ОС з усіма її модулями і дровами (hal.dll, різні чисельні драйвери), їхнім кодом і статичними даними. Тут будуть сидіти Сторінкований і Несторінкований Пули, згадані вище, в яких буде уйма різних структур ядра (вулики реєстру наприклад, PFN база, простір Об'єктного менеджера, дерево об'єктів пристроїв і ще дуже багато всього). Тут будуть стеки ядра на кожен потік1. Все, за винятком якоїсь частини Системного Кешу - сховища, в якому ОС відображає файли, якшо програми самі цього не роблять. Та й то, це лише того, і на випадок, якшо він, кеш не влазитиме в 256 МБ. Тобто це лише на такий випадок. Але, думаю, влізе; 256 МБ з 1024-х наявних, це чимало для ядра, еге ж? Якшо вліземо, то вся Віртуальна Пам'ять ядра (вона спільна для всіх прцесних адресних просторів) буде тривіально картована, отже значно розвантажиться система керування пам'яттю, особливо добре це вплине на TLB. А значить - це істотне пришвидшення.
  • 90000000 - a0000000 - це ділянка kseg0, зарезервована платформою (йодом) і містить всі відображені в пам'ять пристрої (а тут вони всі відображені в пам'ять, нема окремого В/В простору як на x86); і просто зарезерована недоступна пам'ять. дірки між ділянками, таке, просто невикористовуваний в поточній версії SoC'а системний адресний простір.
  • a0000000-b0000000 - ділянка kseg1, вказує туди ж шо й в першому пункті, але звернення через цей діапазон, оминає кеші процесора. Це для випадків обробки речей пов'язаних з обслуговуванням кешів, синхронізації між проесорами (нагадаю, тут два ядра).
  • b0000000-c0000000 - а це те саме, шо в другому пункті, тобто пристрої, але, знову - некешована ділянка. логічно саме сюди ми й писатимемо, коли програмуватимемо пристрої. Навідміну від звичайної пам'яти, де ми хочемо кешувати, тут кешувати писання в регістри пристроїв - це просто не те. Власне в нашому Sec коді, сам сюди ми й пишемо, це видно в прикладах з попередніх дописів.
  • c0000000-f4000000 - сегменти, які мають бути відображені кудись в фіз. пам'ять, через MMU з використанням TLB, шоб бути використаними. Сюди ми кластимемо ту частину системного кешу, яка не влізе в kseg0.
  • f4000000-f5000000 - це, якшо правильно запам'ятав розмір (16 МБ), костиль від Індженика, архітектурно мала б бути частина kseg3, кешованого мапованого сементу як в пункті вище, але саме в цей діапазон вони відобразили TSCM, SRAM де виконується наша Sec фаза. Шо буде якшо спробувати відобразити цю ділянку, невідомо. Типова "фіча" від вендора. Ніяк неописана. "Дижаст воркс", ми її просто не чіпатимемо в ядрі.
  • f5000000-ffffffff - "нормальна" частина kseg3, горішня частина ПАП ядра. Ми її мабуть не чіпатимемо.
1 - а може стеки ядра доведеться теж виносити в kseg3, як і кеш. якшо не влазитиме.

Далі. Алокація ВП (віртуальної пам'яти). Двохрівнева - резерв і коміт. Облік ведеться в дереві VAD'ів - Virtual Address Descriptor. Сплей дереві.
Про організацію пулів ще нічого сказати не можу. :facepalm:
Взагалі, хоча наявність немапованого сегменту, полегшує й пришивдшує, все ж, треба особливо обдумати як це вплине на облік ПАП тут, тобто алокації в пулах, і взагалі, в ядрі. Чи потрібне VAD дерево чи не потрібне, шо потрібне - ще треба розбиратися. Ясно лише те, шо через немапованість, не треба задавати карту (не треба мати таблиці сторінок для цього діапазону), тут не буде пейджь-фолтів пов'язаних з "неприсутністю" фіз. сторінки, вона автоматично присутня, якшо SDRAM ініціалізована. І також через відсутність заднього сховища, ми казали про це, нема ЖД, нема заднього сховища, сторінкований і несторінокваний пули стають невідмінні. Але це останнє лише тут, де нема заднього сховища. Наприклад менеджеру пам'яти не буде потреби синхронізувати брудні сторінки. Але й скидати і забирати комусь іншому він не зможе, доки вони не звільняться. Саме виясняти ще.
Системна (фізична) пам'ять. Про складнощі з динамічним розміром сторінок і їхнім впливом на організацю ПФН бд я вже казав. Треба терміново вигадувати тут шось. ехвективне. Алокація пам'яти йтиме за принципом "на вимогу". Тобто на коміті, ми віділяємо від 1-єї до кількох сторінок (в термінах 4 КБ-них сторінок), а потім, всі наступні виділення робимо в обробнику падіння сторінки (page fault). Тобто даємо процесу мінімум фіз. пам'яти, а додаємо потрохи в міру його потреб, коли він лізе в невиділену ще пам'ять і генерує пейджь фолт.
Виділена системна пам'ять організовується в робочі набори, WS (working sets). Всі сторінки, які знаходяться в робочих наборах, а також в Non-Paged пулі, є в активному стані. Це власне - використана фіз. пам'ять. Решта сторінок знаходить в таких станах:
  • stand-by - чисті, вимушено забрані сторінки з якогось робочого набору, можуть туди вернутися - soft page fault сценарій, такі сторінки робляться для того, шоб мати резерв за відсутности вільних сторінок.
  • free - вільні але не занулені
  • zero - занулені, через "teh security", ці два стани - головні постачальники пам'яти для системи, ми спочатку не робитимемо занулення. це свистілка для розробленіших версій, вона некритична, насалоджуватимемося небезпечною швидкодією покишо.
  • modified - брудні, вимушено забрані з якогось робочого набору, їхній вміст не збігається з їхнім заднім сховищем, не синхронізовані писальні сторінки. це сценарій дуже великого дефіциту пам'яти, менеджер якої, висмикуватиме такі сторінки з робочих наборів в останню чергу. Але за відсутности заднього сховища, як у нас, він взагалі не вимсикуватме їх, тобто нема заднього сховища, нема модифікованого стану сторінок. такі сторінки лежатимуть в робочих наборах (активний стан) аж доки процес добровільно (примусово) не звільнить їх.
  • modified-no-write - екзотика, те саме, шо пункт вище, але це для якихсь мутних потреб ФС в їхньому осблуговуванні журналювання. Їх не треба синхронізувати, доки ФС не дозволить
  • transitional - тимчасовий перехідний стан, для внутршініх потреб менеджера пам'яти, поки він возиться з сторінками - синхронізація і всі діла.
  • bad - пагані сторінки - хардваре не може гарантувати цілісність даних в цій ділянці, патологія, не має траплятися.
Наш менеджер пам'яти, має підтримувати таку ефективну структуру, яка обслуговуватиме динаміку сторінок, їхні переходи з станів. Двонапарвлений список, всажений в масив, де позиція запису задає номер сторінки, гарантував би миттєвий, константний доступ до запису, в нього можна було б вмістити всі списки по станах, і робочі набори. Але така структура зжирає велику кількість пам'яти. Але найприкріше - за наявности "великих" сторінок, будь яких, більших за 4 КБ, ця структура б просто марнувала купу місця. Або б довелося відмовитися від константного доступу до запису, шо є найголовнішою її фішкою.
Треба вигадувати шось. Хоча на перший раз ми принаймні можемо імплементувати нашого монстрика, як знаємо, тобто плетиво списків в масиві.
  • 0

#123 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 14.06.2017 – 20:31

наявність на міпсі прямоадресованих сегментів, про які ми розказували, істотно впливає на модель керування пам'яттю. навіть якби в нас було заднє сховище, а воно, нагадаю, може бути - досить приєднати USB диск; ми не можемо одночасно використовувати такі регіони і покладатися на "неприсутність" сторінки. неприсутність досягається спеціальним позначенням в записі таблиці сторінок для цієї сторінки, шо ось для цього відображення між ПАП і САП, зв'язку немає. Саме так ми можемо робити сторінку modified, stand-by, free або zero. Всі такі сторінки між іншим не мають жодної віртуальної сторінки з ними зв'язаної. А за прямого відображення, таблиці зв'язування не потрібні для відображення, все шо потрібно, це шоб SDRAM був ініціалізований, і якшо так, то наприклад звернення за ПАП адресою 0x80000000 однозначно приведе до звернення за САП адресою 0x00000000, і ніякі записи таблиць сторінок навіть не будуть інспектуватися. Нам би штучно довелось перелазити на вищі адреси, в kseg3 тобто, шоб мати там можливість робити сторінки незв'язаними, і керувати їхньою алокацією. Але за наявности такого пришвидшення, яким пряме відображення поза сумнівом є, нам краще пристосувати керування пам'яттю до цього. Це додає архітектурноспеціифічної мороки, але дає пакращення з т.з. шивдкодії. Як наслідок, всі 256 МБ відображеної таким чином пам'яти (25% всієї пам'яти), стають фактично несторінкованим пулом. :) Але це максимум, ядро може само себе обмежити.
В ньому, в цьому пулі, треба розгорнути якийсь алокаційний механізм. Який? планується використати buddy-механізм. Який ще треба вивчити.) От тоді як і якшо я його вивчу і зроблю в моєму Менеджері Пам'яти, я за нього й розкажу. Коротко звичайно. :D
  • 0

#124 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 27.06.2017 – 20:28

теревені ожили, оживімо й ми наш блох-щоденник. отже, після тривалого простою на ниві практичних дій, повертаємося до них. переходимо до збирання понаписаного в Sec фазі, і, якшо воно робитиме, ідемо до наступного кроку - завантажуємо (вже в SDRAM!) Dxe.
Як воно зараз виглядає? Sec фаза, потягла поки на кілька секторів коду, вона ініціалізує SDRAM і далі має вибрати грузити з NAND чи SD. У нас поки друге.
Отже, після успішної інціалізації пам'яти, ми шукаємо заголовок CFV (Core Firmware Volume), він за умовою теж має попасти в TCSM, тобто має лежати на сховищі не далі, ніж 14КБ від MBR чи взагалі, від початку. І таким чином, він опиняється загруженим ром-кодом разом з Sec фазою. Далі, та іде і читає заголовок, і, якшо все гаразд, шукає файл який має GUID, шо відповідає Dxe Core. В FV, іменами файлів суть GUID'и. А далі, Sec фаза має завантажити цей файл, як виконуваний PE файл в пам'ять, в SDRAM, на напередвизначену адресу, на яку цей файл злінкований. І передати на нього керування. Частина файлу може опинитися в TCSM, добре, тоді, після відповідних PE обрахунків і шукань, ми просто копіюємо відповідні секції в SDRAM. На PE, всі маніпуляції ідуть на рівні секцій. А якшо файл не увесь попав в TCSM - ну це коли він опиниться далі, ніж 14КБ-на межа, увесь чи частково - тоді нам треба читати ту його частину, шо не попала, з SD картки в буфер в TCSM, і копіювати в SDRAM.
От оце зараз цим займатимемося. Після того, як переконаємося шо SDRAM ініціалізація працює. Написана вона вже давно, але не тестована. :)
  • -1

#125 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 01.07.2017 – 22:51

Ну от, то а чьом так долга гаварілі такі базікали як я, свіршилась - ми нарешті ініціалізували SDRAM (1GB DDR3 від Гнусмаса). Запустили код, написаний вже мабуть два місяці тому, повиправляли помилки і, ось воно, ця таємнича фігня, під назвою SDRAM, тепер ввімкнена. :) Скриншот нижче.
Одна нотатка. код зависав на початку ініціалізації DDR PHY, так очікувано і фатально, а якже, - це ж сама задниця і до того абсолютно незрозумілої задниці! Засіли перевіряти. І блін блін блін! Виявилося, шо помилка взагалі не пов'язана з ахтунг-натурою DDR PHY. Все неуважність, і, шо зіграло злий жарт тут, нерозбірливість гнусного асемблера. Писання в пам'ять на міпсі, робляться так - SW $rX, N($rY) - де $rX - це регістр, який тримає слово, яке треба записати, N - це 16-бітне знакове зміщення, тобто число в діапазоні -32768 ... 32767, $rY - це базовий регістр, регістр, який тримає базову адресу куди, після додавання зміщення, треба писати. Ну типова RISC сторе інструкція. І я в одному з писань в один з DDR PHY регістрів, забув написати базовий регістр з дужками, записав замість:
		sw $zero, DDRP_MR2($s1)
оце
		sw $zero, DDRP_MR2
:facepalm:
Але шо найдосадніше, асемблер це пропустив!!1 Це ж мала бути синтаксична помилка! Але, схоже, це той випадок, коли 100% помилка, чогось непомилка. Хоча всеодно помилка.
Хех. Я навіть не знаю, шо там зґенерувалось, і куди воно писало. Сподіваюсь, воно не підсмажило мою в єдиному екземплярі цільову плату.
І все. Після виправлення цього епічного недогляду, все пробігло як треба. Місяці сумнівів, страхів і переперевірянь окупились. :) Власне це кодова послідоність написана Інджеником, перенесена собі убутом, і, нарешті, перенесена мною. Ну не задокументував Індженик як це робити самому. Але це не копіпаста, я переписав вручну Сішний код в асемблерний.
Дивимось скрин:
Зображення

ЗІ. Останній рядок - це ганьба на мою не дуже вже молоду голову, але, як то кажуть - з пісні слів не викинеш. :lol:
  • 1

#126 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 03.07.2017 – 22:58

Шо далі тепер робити? :D В сенсі, - от прямо зараз. Тут або намагатися "прикрутити" зародок ОС до цього стартового коду, тобто вантажити саме його, і там "шось робити", або - робити те саме, але з зародком ФВ. Вони дуже схожі - в обох є менеджмент пам'яттю, внутрішня база даних, в ОС це реєстр, в ФВ це GCD - Global Coherency Domain, чогось називається. драйвери з моделлю і інтефесами і тд. Але якшо таки почати з ОС, то, виходить, - робитиметься шось інше за цільовий дизайн. Адже в результаті, ми хочемо мати UEFI-свідому ОС, яка на цю ФВ покладається, і, наприклад, вантажиться за допомогою уефі ос-лодарів, які суть застосунки уефі. шо між іншим означає, шо вони роблять свою роботу в контексті уефі, використовуючи його сервіси. якшо ми зараз почнемо писати безфірмварну ОС з нижньорівневими нутрощами також безфірмварними, то ми, власне, писатимемо шось інше. Тоді, пізніше, прийдеться переробляти. Це не правильно.
Того вибираємо перший варіант - прикручувати ФВ до вже наявного стартового коду. Ось шо треба зараз робити для досягнення цього. Нагадаю, ми намагаємося бути повністю UEFI суміними, але не намагаємося бути обов'язково PI-сумісними, того, якшо дуже хочеться, наше Dxe не обов'язково має робити все так, як каже Dxe специфікація. Але дотримуватися все ж непагано, це наша одна з цілей - спробувати імплементувати складний стандарт, набратись досвіду при цьому. От специфікація каже, шо FV, фірмварні томи (ФТ), мають на час виконання Dxe диспетчера бути вже в пам'яті. Цікаво, бо я думав вантажити з SD/NAND саме пофайлово (а не потомно) і саме в Dxe фазі. Ну шо ж, ми можемо або відхилитися від цієї вимоги, або не відхилятися. Спробуємо не відхилятися. Отже, наша Sec фаза має закинути в пам'ять FV. Скільки їх мало б бути? Після скасування ідеї імплементувати Pei, як ви пам'ятаєте, логічною була б думка мати просто один ФТ. Нашо ускладнювати, правда? Але, тут цікавий момент. Ром-код вантажить в SRAM своє навантаження, нашу Sec фазу. Розміром це може бути мало як на йоді чи значно більше, як на мурані. Але це завсіди більше, ніж Sec фаза потягне сама. Отже, чого б не скористатися цим і не вліпити туди хай навіть маленький але ФТ, це ж раціонально - том буде вже в пам'яті, і ми можемо передавати інфу про нього Dxe диспетчеру, який звідтіля вантажитиме виконувані файли - модулі Dxe. Круто. В деяких сценаріях, місця так багато, шо більше нічого й не треба (муран наприклад, ~108КБ). Там можна спробувати обмежитися й одним томом. А от тут, на йоді, не вийде. Вийде 2 томи. І, за традицією, перший, малий, буде зватися BFV, другий - CFV. Хоча й без Pei фази. Розділення обумовлене пам'яттю куди ці томи будуть відображатися. І ким. Перший, BFV, має бути <14КБ, про його розмір нижче, і він вантажитиметься в TCSM, ром-кодом; другий, CFV, його розмір не обмежений нічим окрім бажання бути ефективним, і вантажитиметься він в SDRAM нашою Sec фазою. Бо саме вона, як відомо з попереднього допису, ініціалізує ту SDRAM.
Тут є одна морока. Покишо наша Sec фаза не використовувала стек. Взагалі. Але це робе таке обмеження як неможливість функціям викликати інші функції. Тобто далі, ніж один рівень вкладености ми не робимо викликів (чого? того шо без збереження лінкувального регістру десь, наприклад на стеку, це неможливо). Це не так страшно для невеличкого модуля як Sec фаза, але чим більше він стає, тим це обмеження стає помітнішим. Та й надалі, ми б могли експортувати наші корисні функції Sec фази (друкування в послідовний порт наприклад, busy очікування, взяття лічильника тіків тощо) в ранні етапи Dxe фази, доки та не розгорне свої драйвери і не навчиться те робити своїми руками. Це теж робе однорівневі функції завадою. Обійти це легко - треба просто штовхати в стек регістри, які функція збирається використовувати і які вона має в такому разі зберігати, згідно з угодою по викликах. Це просто. Але треба використовувати стек. Тепер, коли ми збираємося віддати все, шо ром-код завантажив в TCSM за Sec фазою під ФТ, виникає питання - а де ж має бути стек? Це не те, шо невирішуване, але про це не варто забувати. Наприклад за угодою, ми можемо віддати під стек останні 512 байтів в TCSM, це ще трохи відрізає від максимально об'єму нашого BFV.
Який він тут може бути за розміром, і чи варто це все мороки?
Ми маємо ліміт в 14 КБ. 28 секторів.
  • 1 сектор безальтернативно іде на MBR
  • n секторів іде на бінарник Sec фази
  • 1 сектор іде на стек

Отже розмір BFV в секторах m = 28 - n - 2 = 26 - n. Яке n очікується? Зараз наша Sec фаза, яка вже вміє інціалізовувати пам'ять але ще не вміє читати SD/NAND тягне на 2608 байтів. Код, який читає СД як і код, який читає НАНД, кожен, умовно потягне на стільки ж, шо й код який ініціалізує SDRAM. А це приблизно половина від того, шо там є (після вставляння коду інціалізації, грубо кажучи, фаза подвоїлася). Тобто додавання цієї функціональности ще подвоїть фазу. Плюс ще там якась малеча, хай буде десь в районі 6000 байтів. Закругливши на розмір сектора (шоб могти закидати ФТ окремо від Sec фази, вони всеодно мають бути вирівняні на сектор), маємо оціночнй розмір 6144 байтів, шо дає n = 12. Отже ФТ може розраховувати на 14 секторів, тобто на 7 КБ. Не густо. Але всеодно напевно варто того. Запхнемо туди принаймні наш "платформний драйвер", який займатиметься такими нижньорівневими речами, як PLL, кеші, винятки, переривання, таймери і решта важливої галіматті.
Цікаве питання чи влізе Dxe Core, тобто фундація з диспетчером і постачальниками UEFI сервісів в 7 КБ? Напевно шо ні. Спочатку ясно шо влізе, але пам'ятаймо - нам треба робити не на тимчасові рішення, а так як це буде в релізових версіях. Повнофункціональна фундація не влізе. Через такі міркування, виходить цікавий сайд ефект. Ми розраховували класти фундацію так, шоб вона хоча б спочатку влазила в 14 КБ, які попадуть в TCSM. Тепер виходить, навпаки, вона ніколи не має туди кластися. Бо ми маємо там всього 7 КБ, а вона, коли набуде повноти функціональности, в такий об'єм точно не влізе. Отже вона йде в CFV. Який лежатиме на СД картці одразу за BFV, але грузитиметься вже Sec фазою в SDRAM.
Оце шо нам треба робити після ініціалізації пам'яти. Створити HOB список. HOB'и це Hand Off Block, ланцюжок, який описує ресурси, коли ти передаєш керування на Dxe. Ресурси тут це переважно пам'ять і фірмварні томи. Але відображені в пам'ять, тобто їх треба завантажити. BFV вантажиться ром-кодом, а CFV вантажимо ми. Потім ми вже шукаємо там Dxe Core файл, і завантажуємо його як виконуваний образ. І передаємо на нього керування.
Це мінімум, який треба робити. Для цього ще треба створити транслятор з ELF в PE.
  • -1

#127 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 05.07.2017 – 13:59

Якась залупа ще й мінусонула мої дописи. Але ніщо не зупинить прогресу в нашій справі! :lol:
Невеличка нотатка щодо використання TCSM як площі для відображення BFV. Я ж забув за Run Time сервіси UEFI. З Sx режимами на йоді все ще дуже запущено, не дивлячись, шо це нібито мобільний процесор, який підтримує там купу всяких сонних режимів, і пам'ять же наче може бути в самооновлювлювальному))) режимі, але але. Я вже наче казав - тут навіть павир кнопки нема, шоб з S3 виходити. Але, все ж, якшо колись виявиться, шо такі смаколики тут можливі, то, непагано було б мати ран тайм сервіси в TCSM, вона наче лишається в операційному стані в цих режимах. Непагано, зважаючи, шо саме в ран тайм сервісах сидить Reset (і подібне), там би було йому місце. З гастроентерологічної т.з.
Чим більше я морочу собі голову з цим "ефективним використанням" TCSM, тим більше розумію, шо це економія на киселі... 7 КБ, Карл. :)
Власне нотатка за це - вже якшо шось туди й пхати, то ран тайм сервіси UEFI. А не мікроскопічний ФТ. Це принаймні спрощує в плані, шо тепер стає ще ясніше, шо його робити.
Тепер ми матимемо 1 ФТ, і його завсіди треба вантажити з SD/NAND в SDRAM. Той факт, шо на перших порах, як побічний фект, весь його корисний вміст попадатиме в TCSM, бо ром-код грузе 14 КБ без розбору, не має нас хвилювати. Бо дуже швидко функціонал не влазитиме в такий малий об'єм.
Наша Sec, значить, має читати SD і відображати (закидати) в пам'ять наш CFV.
  • 1

#128 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 08.07.2017 – 16:50

На правах щоденника. Зараз міркуємо над менеджментом пам'яти в Dxe фундації. Оскільки ми працюємо в тривіально-відображеному сегменті (kseg0), все зводиться до обліку аллокацій (чи вільного місця). Того, планується бути розгорнутою схема шось нашкталт "як Кнут написав", в розділі про динамічну аллокацію. Зараз ми бачимо, шо це буде або список з First Fit політикою (чи стратегією :gryzin:) або buddy механізм. Останній найшвидший, але, зжирає стільки місця! Подумайте, уявіть вам треба виділити наприклад 36 КБ буфер. Резонно? Так. Але бадді механізм виділяє лише блоками, які суть цілими степенями двійки. Тобто на ваші 36 КБ, буде виділено ... тепло пробігає по спині від різкого викиду аденаліну, наведеному цією думкою ... 64 КБ! Це називається оверхед. І чим більший блок, тим більше марнування. По абсолютній величині. Ну або треба винайти шось схоже на бадді механізм, в якому втім, замість роздвоєння/здвоєння блоків, використовуватиметься віднімання/додавання аллокаційної одиниці, якоїсь резонної зернистости. Подробиці згодом.)
  • 0

#129 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 21.07.2017 – 23:14

Менеджмент пам'яти в Dxe ядрі - це круто, але ще ж треба завантажити саме Dxe в RAM. Спочатку відтінити (shadow) увесь фірмварний том в пам'ять, а потім там знайти dxe.exe, і вже завантажити його як виконуваний образ, не забувши потурбуватися про гожість кешів (зверніть увагу, - це ж завантаження "даних" - data кеш, які стають виконуваним вмістом - instruction кеш).
В майбутньому, тут принаймні треба вміти читати з SD картки і NAND модуля. Але, також, не завадило б вміти читати MMC картки і вміти SDIO сценарій. Але поки SD картка. Ці MMC картки, я так розумію, назараз вже просто археологія - подивився ебай, так там викопні рештки по 32 МБ, які стоять як 32 ГБ сд картки... Для нотатки - MMC не зникло, воно просто фалломорфувало в eMMC - це коли модуль напаюють на плату, або на свою PCB, манюню, і потім чіпляють в такий snap-in слот на основній платі. хз як він правильно називається. MMC стало "мо ембеддед, лес ремовабле" так би мовити. :) Але, на йоді, слот для SD картки повнорозмірний, такий велииикий, і він дає MMC увійти в себе теж. :brovy: І от же обов'язково, серед майбутніх користувачів, знайдеться якийсь філателіст, з мішком таких реліктів, який схоче "оживити" їх так би мовити. Шоб той експіріенс був тошонада®, було б непагано вміти осблуговувати і цю дивину. Ключова річ тут - ці стандарти суть рідні брати, дуже схожі, тож вміючи читати SD, буде неважко навчитися читати MMC.

Вміти читати з SD картки - це складно. Але порівняно з ініціалізацією SDRAM, - значно краще задокументовано. І в частині картки і в частині хосту. От зараз цим і займаємось. Треба вникнути в це все, прояснити усю картину. Покишо вона як вінігрет. Єдине, шо вималювалося - ми використовуватимео DMA режим читання, а не PIO, перший ефективніший. Навіть без дозволених переривань. На цьому SoC'у аж два DMA - один спільний, для всіх компонентів, другий - спеціально для MSCx - хостового контроллера SD, MMC, CE-ATA. Саме його використовуватимемо. Він дескрипторного типу - складаєш йому дескриптор, який описує цільову пам'ять (куди або звідки писати/читати), і даєш йому робити те читання/писання, чекаючи на переривання від нього, якшо вони не замасковані, або опитуючи його статус, якшо переривання замасковані - наш випадок.
Але крім цього, ще багато різного неясного геморою в цьому процесі - ідентифікація картки, узгодження вольтажів, всі оті команди, стани, багато ще треба осягти.

Це найближче завдання. Потім, коли воно успішно виконане, ми матимемо CFV, наш ФТ (фірмварний том), відображеним в пам'яті. І далі нам треба, проходячи по тому, шукати Dxe Core файл. Схожу роботу ми робили на мурані, армівській платі, минулого року вже. (боже, як летить цей час). Там ми просто написали кід, але не ганяли його. Далі, треба розбирати PE устрій того файлу. І робити завантаження вже як виконуваного образу, власне це вже буде копіювання пам'ять-пам'ять. І ото воно - перша робоча версія Sec фази. Вона ще не робить певних речей, які в приниципі мала б, та ж автентифікація того, шо вона вантажить - security фаза як не як - але, всеодно, це вже буде функціональна версія фази. Не впадаючи в таку невдячну річ як планування, все ж, було б непагано зробити описане за місяць. :)

В кінці трохи краси, рішив постити тут фотки Гаврилівни зрідка, мій же блог чи як? На інстаграмі, я якось не тойво постити, а тут - саме воно. Поститиму фотке, які особливо сподобались. Одна з них. Називється - "teh most beautifullest girl in teh world". :wub:
Зображення
  • 0

#130 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 01.08.2017 – 00:12

Прикол, витирав пиляку в своєму барлозі, висмикнув дроти з UART-хедера йоду, і не знаю тепер шо куди вставляти. Rx адаптера до Rx плати, те саме для Tx, чи Rx до Tx. Там може бути і так і так, залежно від виробника. Прийшов сюди перевірити, бо наче я тут писав за це, може ж я задокументував процес. :D
Нє, не задокументував, прийдеться знову вгадувати, млинець. :angry:
Зараз ми вивчаємо специфікацію на SD картки, і частину мануалу на MSC контроллер - той, шо керує SD\MMC\CE-ATA. Я вже писав за це. Ніпрошо поки звітувати. Складна фігня не те слово. Але важлива. Наша фірмваря учиться считувати себе з носія.
  • 0

#131 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 02.08.2017 – 01:01

З третього разу, дроти вставив як треба. Зверніть увагу, зважаючи, шо я знав куди ставити грунт, варіантів було всього два. І я справився гідно - зробив назад, шоб робило з третього разу! :lol:
Коротесенький звіт.
Тепер кід читає BOOT_SEL піни (вибір завантаження, з чого грузити, це ром-код в принципі тут керує, але й нам треба), і знає, звідкіля SEC фаза завантажена ром-кодом. Ми це вибрали як водій для рішення, звідкіля вантажити Dxe. Правило таке: звідкіля Sec фаза завантажена ром-кодом, звідтіля ж вантажити Dxe. Все нормально, піни прочиталися як положено. Ну але не без геморою - згідно з блок схемою мануалу, з таким варіантом, ром-код не мав нас вантажити, а він вантажить. Такого роду представлення інфи в мануалі називатимемо магією - це посилання на магічний рядок "MSPL", з якого має починатися образ для завантаження ром-кодом. як написано в мануалі, і який насправді переплутаний задом наперед. Але боротьба з мануалом - це інше, ми вміємо читати ті піни, круто.
І друге. Наш коротенький тест щойно ініціалізованої пам'яти використовував адреси з kseg0, якось так необдумано, а це ж сегмент кешований, чесно, я ще не знаю, чи кеш робе вже на нашій фазі чи ні, але потенційно ми могли тестувати його, а не SDRAM. Того, помітивши це, ми виправили на адресування з kseg1, сегменту завсіди некешованого. Всеодно робе. І це добре.
Повертаємося до SD карток. :)
  • 0

#132 серпинка

    Старійшина

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1514 повідомлень
  • Стать:Жінка

Відправлено 13.08.2017 – 17:25

Треба тут трохи похуліганити, щоб Nema не було обідно) _Ех, ти ж не проти? ;)
Тут щось про конструктори говорили. Так от, мій племінник любив конструктори, але його засмучувало те, що зібраною з конструктора іграшкою неможливо гратися, бо вона постійно розсипається і доводиться щоразу її збирати знов докупи.

Повідомлення відредагував серпинка: 13.08.2017 – 17:50

  • 0

#133 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 07.10.2017 – 17:01

Завсіди є шось просте і не дуже. Будь де. От наприклад в сісь_тємному програміруванні є відомий "скелет в шафі" - USB шина. Нею лякають молодих ОСь-писарів по специфічних форумах, як одним з найскладніших інтерфейсів, які будь коли існували.
Так от можна додати - є прості речі (на прикладі інтерфейсів) в сісьтємному програмуванні (UART, eMMC), є складні (USB, SATA, SCSI) ... І є PCIe! :lol:
Ось манесенький уривок з змісту першої книги за PCIe, яка ся скромно назива Base, тобто це ще не все. У мене наприклад лежить 9 книг. І це стара версія. Точно не третя. Сподіваюсь хоч друга, не уточняв ще. Просто відкрив подивитися. Сором'язливо позичені роки назад на Піратській Затоці (а точніше - в серпні 2011 року, Експлорер підказує). Бо це знання законно стоє 1500$ за разовий доступ. І ще більше - за членство. Щорічно. :^) Для порівняння - SATA хоче за колекцію специфікацій всіх версій коло 95 баксюків. І всього 25 за старовину. А USB/eMMC/AHCI взагалі безкоштовні.

Цитата

...
FIGURE 7-61: ROOT COMPLEX LINK CAPABILITIES REGISTER.................................................... 445
FIGURE 7-62: ROOT COMPLEX LINK CONTROL REGISTER .......................................................... 447
FIGURE 7-63: ROOT COMPLEX LINK STATUS REGISTER ............................................................. 449
FIGURE 7-64: PCI EXPRESS POWER BUDGETING CAPABILITY STRUCTURE ................................ 450
FIGURE 7-65: POWER BUDGETING ENHANCED CAPABILITY HEADER......................................... 450
FIGURE 7-66: POWER BUDGETING DATA REGISTER ................................................................... 452
FIGURE 7-67: POWER BUDGET CAPABILITY REGISTER............................................................... 454
FIGURE 7-68: ROOT COMPLEX EVENT COLLECTOR ENDPOINT ASSOCIATION CAPABILITY ........ 455
FIGURE 7-69: ROOT COMPLEX EVENT COLLECTOR ENDPOINT ASSOCIATION ENHANCED
...
Вчитайтесь в ці назви... Чи це взагалі можна осягнути?! :D
ROOT COMPLEX EVENT COLLECTOR ENDPOINT ASSOCIATION ENHANCED... Ще й "enhanced". Карл! :D

На армівських ОПК PCIe ще майже не з'явилося. Плати з SoC'ом, який має таке в собі - RK3399, стоять коло 250$ (FireFly, VideoStrong, Theobroma) Задорого. Тим паче, шо там якась неясна фігня з тим, як саме PCIe там використовується. Нічого, колись з'явиться широко і як положено. Як USB3.
Кажучи за яку, треба розказати за невеличке поповнення в моєму парку цільових машин. Як завершальний штрих на першу фазу. Дальші закупи (чи надходження) будуть лише в разі значного прогресу в проєкті.

Саме через стійке бажання мати плату яка має в собі USB3, я вирішив купити оцю гарну плату, родичку Сосни. Називається Rock64.
Зображення

Як бачимо на ній теж чип від Rockchip - RK3328, менший брат вищезгаданого RK3399. Обидва мають кластер з 4-х ядер Cortex-A53, але останній ще має двоядерний кластер з "великими" яйцями ядрами - Cortex-A72 :o - головний selling point.
У них не тільки швидше працюють внутрішні конвеєри, вони ще й на більших частотах бігають. Ну гордість арма, хулє.
І це звичайно 64 біти.
У цього Сока нема PCIe, але є USB3. Також вона продається з 1, 2 чи 4 (!) ГБ DDR3 пам'яти. А стоє 4 гектарний варіант - 45 баксів. Нормально.
Також на ній є аж 16МБ SPI NOR флешу! Нарешті, вендори почали ставити цю річ на ОПК. Це дуже важлива частина для фірмварі, на звичайних пісюках саме на неї пишуть (прошивають :gryzin:) BIOS. Біосаваралапласа. :D Тобто це вельми цікава штука для фірмварної частини нашого проєкту (який тепер називається efify, ефіфай, бітчез! :D). Та ще й аж 128 Мбітів! Охрініть вони впаяли. Шоб мало не здалося. Зазвичай 8-16 Мбітів.
Також Гігабітний етернет, і ще фаст етернет через розширювальний хедер. Є ще сокет для вставляння eMMC модулів. І SD картковий гаманець, звичайно теж. Загалом дуже солідна плата за такі копійки. Для саморобних NAS рішень саме те. А мені - для сісьтємного програміруванія. :D
Але її я ще не купив. Там всеодно лише з листопада почнуть доставляти. А купив я іншу штукенцію. А саме Banana PI M2 Ultra.
Осьо вона:
Зображення

Красиво індигово пофарбована, це armv7, 32-бітний табір. Сок R40 від Allwinner'а. Чотириядерний теж І це armv7 папєрєднік Cortex-A53, Cortex-A7. Дуже популярний.
Основна причина купівлі цієї плати виглядає на передньому плані. Зліва від HDMI-порта. Отой, неприглядного кольору пластмасовий порт з кривим язиком. SATA. Цей SoC має (як і A20) в собі SATA/AHCI-контроллер. І це добре. Це збудливо добре. Це один з наших пріоритетів - сховища. А на ОПК-діапазоні це дуже рідкісне явище. Бо SoC'и сюди ідуть переважно з смартфонового сегменту, ну яка там SATA. А от Allwinner молодці, принаймні в частину своїх чипів все ж вставили такий бажаний для DIY дрочунів інтерфейс. Який медіаплєр без шивдкого і великого сховища? А який NAS без нього? Та взагалі важко знайти кому б він не пригодився. Смартфони просто не можуть, а не не хочуть. :^D
І от тут він є. З sucky швидкістю писання чогось (~50 МБ/с), але ніхто не знає причини, і я надіюсь шо це просто недоробка крепексового "драйвера".
Ця плата це як продовження A20 базованих плат, одну з яких, Cubieboard 2, аргон, я маю. Більше ядер, більше пам'яти, тут її 2 ГБ, Гігагібітний етернет. І 8 ГБ eMMC на платі! Дуже добре. І це все з корпусом і блоком харчування :^D іде за 49.50 долярів. І доставлення вгадайте скільки? 4 долари! Китайські дива. :^) А збирає цю штучку Foxconn, той самий, який збирає еплу його погрімушки. Ще одна причина подрокати подумати про цю плату харашо.
Просто шоб мати таку собі SATA-здатну підмножину, яка складається з трохи більше, ніж однієї машини, я й купив цю плату. Вона дуже добре напічкана для мого проєкту. І я сподіваюсь її включити в роботу дуже скоро. Це дуже цікаво працювати з схожими але не зовсім однаковими платами. І вигідно для якости. Та й надлишковість (redundancy) для безпеки потрібна. Парк і так скромний більш ніж. І весь час боїшся, шо шось згорить.

Банану вже замовив, а каменюку замовлю пізніше. І ось з цим і працюватимемо.
Тепер я можу сказати - I run linux on my banana. :lol:

В кінці трохи краси. Та шо там брехати - на нашу нескромну думку її тут дуже багато. Принаймні 950 на 950 пікселів. :)
Зображення

Повідомлення відредагував _Ex: 07.10.2017 – 17:08

  • 0

#134 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 13.10.2017 – 21:51

Такий трохи підсумок перед штурмом MSC контроллера.
Після того як пам'ять ініціалізована, код читає boot_sel піни, шоб взнати звідки його завантажили, і звідти ж вантажитиме CFV. Ми підтримуємо два варіанти - NAND і MSC (SD картка). Тут ми опишемо SD сценарій, але, окрім специфіки самого NAND'у, там все так само, принаймні в CFV частині.
По-перше, ми спочатку спробуємо скористатися налаштуванням MSC, зробленого ром-кодом. Не того, шо лінимося налаштовувати самі, а того, шо це раціонально - адже нас щойно він завантажив звідтіля, і налаштував контроллер очевидно. і ми хочемо звідтіля ж вантажити, чого ж не скористатися тими конфіґураціями? шо ж до швидкостей, то, за нашими оцінками, CFV навряд вилізе за межі ~130 КБ, так шо швидкість тут некритична. правильність - цього досить. Ми перевірили, і справді - все як треба - піни в GPIO сконфігуровані для використання MSC (MSC1 в нашому випадку). Регістр статусу теж рапортує цілком логічні речі, для стану, шо свідчить, шо недавно відбувалося читання, яке нормально пройшло. Варто також зазначити, шо тактовий сигнал (clock) до картки зупинений. Мабуть його треба нам запускати. перш ніж починати слати картці команди.
Тепер, хоча тут аж два DMA методи, і один дуже простий, ми вирішили використати PIO для цього сеансу введення/виведення, бо який сенс в DMA, коли не роблять ще (ніякі) переривання. Процесор всеодно крутитиметься в busy очікуванні доки DMA працює. Тож не мучаймо DMA, робімо по старінкє. Тобто є FIFO, і ми чекаємо на статус, шо там вже є якісь дані, і виносимо вручну звідтіля їх. Також, є два типи читання (і писання теж) - одноблоковий і багатоблоковий. Використовуватимемо перший. Знову - нема ніяких вигод морочитися з таким гемороєм на такій ранній фазі, досить і найпростішого варіанту. А вже на Dxe, отам вже будемо огого! А тут не будемо. В багатоблоковому варіанті, треба слати стоп-команду, і, чесно, я заплутався з цим - занадто все заплутане всюди з цим SD, і в частині контроллеру і тим паче - в специфікації на SD. Тож робімо поступово, розбираючись і засвоюючи. І в такій ранній фазі обмежмось одноблоковим читанням. Тим паче, шо я не бачу особливої різниці в пирформансі енівей.

Блок в SD картках - 512 байтів, тож спочатку ми зчитаємо в пам'ять один блок з напередвизначеного місця, шоб дістати заголовок тому, з якого ми взнаємо його розмір. Визначено це місце кількома факторами, для SD картки:
  • 1 сектор іде на LBA=0 (LBA - logical block address, адреса блока в блоках, починаючи з нуля) для MBR.
  • максимум 27 секторів для Sec фази, це визначається 14 КБ TCSM, які ми маємо.
Отже найкраще класти CFV на 29-й сектор (LBA=28). На більшості, якшо не на всіх картках, FAT-партиція лежить на LBA=2048. Тобто за першим мегабайтом. Це дуже добре - ми маємо влізти в 1 МБ для усієї фірмварі. От ми й маємо місце для фірмварного тому трохи менше, ніж 1 МБ, а початок його лежатиме на секторі 28.
Розкрій картки таким чином буде такий:
Назва елементу	Адреса (LBA)	Розмір (сектори)
MBR		0		1
SEC		1		27 (максимум)
CFV		28		2020 (максимум)
От знаючи LBA нашого CFV, ми зчитуємо 1 сектор, і дивимося заголовок тому в ньому. Звідтіля беремо розмір, і дочитуємо необхідні дані кладучи їх один за одним. Так, в разі успіху, ми нарешті маємо CFV том відображеним в пам'ять. Супер!
Це намальовки на нинішню роботу. Волокіта з SD специфікаціями і відповідними частинами мануалу на плату - чимала. :wacko:

А за цим, ми шукатимемо в відображеному в пам'ять CFV Dxe Фундацію (файл dxe.exe), він має бути без базових релокацій, ми вантажитимемо його на адресу, на яку він зібраний. Цю адресу визначатиме розмір CFV, який, як бачимо, відображається в пам'ять - так каже специфікація. Плюс, ще маємо покласти десь поблизу HOB-список для Фундації. А от за цим вже йтимуть завантажені образи ФВ. І dxe.exe - першим. Тобто ми розберемо його PE-метадані, і скопіюємо його на його базу. Підготуємо йому аргументи, а це вказівник на загаданий HOB-список, і ... стрибнемо на його точку входу! От це буде початок роботи ядра ФВ, основної її частини, з сервісами і драйверами. Міні ОС. Особливо якшо зважити, шо ми хочемо ввімкнути обробку переривань там (на відміну від polling'у, який пропонує специфікація). Ще треба додати функціоналу в генератор образів фірмварних томів, який уже трохи початий, але вимагає додавання функціоналу, шоб бути справжнім генератором. І, звичайно, - написати транслятор з ELF в PE, - не зовсім тривіальне завдання, хоча може й нескладне.
А далі - писати саме UEFI, efify як ми його обізвали. :^)
  • 0

#135 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 17.10.2017 – 21:43

Ну ось, спішу відзвітувати про перший успіх в читанні з SD картки. Наш кід вже вміє читати її. Ми використовували 4 ГБ SDHC картку, не пам'ятаю якого саме виробника і якого класу, але мабуть 4-го. Ми використали налаштування, які вже зробив ром-код, як і казали вище, наче як. Тобто ми не ресетили картку, не робили всі оті "переговори" з вольтажів і тд, нашо, адже ми використовуємо ту саму картку, шо й ром-код, а він вже те все зробив. Ми налаштовували лише те, шо треба для нової операції В/В - задали номер сектора, який треба читати, запустили тактовий сигнал на картку, записали номер команди, ширину шини, деякі інші речі. Ми використали CMD17 - Single Block Read. Ну і воно спрацювало. Спочатку правда дані отримані, були зовсім не ті, шо очікувались. Виявилось, шо широку, 4-сигнальну шину, ми ще не можемо використовувати, виходив таймаут, який нажаль, ми взівували. Повозившись стало ясно, шо виходить не зовісм успіх, попри успішну відповідь картки, і флажок про завершення трансмісії від контроллера (шо мало б явно вказувати на успіх), разом з тим виходив таймаут, в зовсім неочікуваному місці. довго розказувати, але суть така, шо мабуть таки варто й картці шось казати про 4-сигнальну шину, шоб це робило, не лише в контроллері це писати. І ром-код очевидно в 1-сигнальному режимі читає теж. В будь якому разі, після виставляння саме 1-сигнального варіанту (а це для картки - режим за замовчуванням, до речі), все вдалося. Нам і 1 лінії даних вистачить тут, CFV маненький, це не страшно. просто в мануалі написано - став ширину в 4... То, все ж, мабуть вже для повно-функціонального випадку - дальші фази ФВ, ОС. Звичайно, і ми збираємося чаклувати з налаштуваннями картки в Dxe "по повній". Але ж не тут.
Добрий прогрес, це радує, це мило. Гель я б сказав, він краще за мило. :D
Фотодокази успіху прикладаються.

Зображення

Оці рядки:
"SingleBlockRead returned: 0"
і
"20202e74"
Це доказ, шо це перемога. :) Перше - це статус, який функція вертає в разі успіху. А друге - це очікуваний рядок в пам'яті, який мав би туди попасти в разі успіху читання його з картки. Патерн. Шматок його насправді, ми просто зчитали 4 байти. Ну і по ньому вже видно, шо це те, шо мало бути. Валідність всіх даних в купі, сигналізує правильна CRC, яку перевіряє контроллер і рапортує нам флажком. Ми це теж перевірили.

На кінець звіту, така трохи приблизна калькуляція. В найсвіжішому скриншоті, де ми ще не пробували читати сектор, в кінці таймер натікав 75448 (в шіснадцятковій СЧ) тіків. Зараз, з читанням сектору, - 75dac тіків. Різниця - 964 тіки. В десятковій системі це 2404 тіки. Період кожного тіку в нас - 2560 нс. Тобто додатковий час, який очевидно пішов на читання сектору - 6154240 нс ~ 6.15 мс.
Отже швидкість читання становить ~ 83195 Б/с = 81.25 КБ/с. :)
Ну шо ж ви хотіли - контроллер використовує кристал як джерело такту, а той тікає 48 МГц. Далі, - ділитель на частоту картці, виставлений ділити на 8. Це дає 6 МГц. Тепер, - ми робимо з однією лінією даних. Тобто якшо взяти, шо за один такт передається один біт, то максимальна швидкість була б тут 6 Мбіт/с. Або 750 КБ/с.
Це дуже поверхнева оцінка. Таймінги в спрощеній (яка й є та єдина безкоштовно доступна, повна вимагає NDA і 1500 баксюків за разовий доступ до бази знань, отако) специфікації не вказані. До того ж, як я щойно вияснив, я прочитав тактові налаштування для MSC0 пару днів тому, а не для MSC1, і я власне не знаю, який ділитель виставлений для MSC1. Ось наводитиму лад в кодесі після цих вияснень і вставлю читання відповідного регістру, шоб подивитись. Хух, а то якось прям не дуже вдобно виходило - 81 з 750 можливих. :)
Далі буде.

Повідомлення відредагував _Ex: 17.10.2017 – 21:48

  • 0

#136 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 20.10.2017 – 02:18

Успішно вдалося використати CMD18 - Read Multiple Blocks. Спочатку ми використали простішу, одноблокову команду, CMD17, але, очевидно, нам потрібне читання багатьох блоків. Можна звичайно використати 1-блокову, викликаючи її кілька разів, але використати багатоблокову команду було б ефективніше. Ускладнення з нею те, шо на відміну від MMC, для SD нема можливости вказати картці кількість блоків, яку потрібно прочитати, того треба слати CMD12 - Stop Transmission, шоб зупинити читання. І це лише на словах звучить просто, адже враховуючи всі оті можливі таймаути, не так і просто зрозуміти, коли ж її слати. Але є ще одна фішка - контроллер можна сконфіґурувати слати цю стоп команду автоматично, "коли треба", і це він сам визначає. У нього є поле "кількість" блоків, тож він має знати, коли спинитися. Тут теж не все ясно, адже на відміну від звичайного посилання команд, з читанням статусів і перевіркою таймаутів - адже й для стоп команди треба це робити - тут незрозуміло, а як же перевірити, шо все відбулося як треба. Єдина зачепка - це те, шо флажок, яким ти кажеш контроллеру слати автоматично цю команду, він обнулює після її надсилання. І, забігаючи наперед, він таки його обнулює. Лишається сподіватися, шо цей акт і є свідченням, шо контроллер таки сказав картці, шо хвате слати дані. А то вона так і читатиме до краю. Варто зазначити, шо для писання є аналогічна пара - одно- і багатоблокові команди. І якшо читання - це недеструктивна команда і особливо нічого боятися, то з писанням не зовсім так... Ну писання поки не на часі. А читання, багатоблокове, воно вдалося! :) Все відрапортувалося ОК, і статуси і коди повернення, і кількість секторів, які не лише прочитані, а й записані в пам'ять. Скриншот нижче. Незважаючи на все той же рядок SingleBlockRead, який я просто забув поміняти, читання тепер багатоблокове, а саме - 8-ми блокове, тобто ми прочитали 4 КБ. Отой рядок, де ідуть два числа - 00000008 і 00000909, то й є кількість прочитаних секторів (перше) і відформатований статус від картки, по яких видно, шо всьо ОК. :) Ну й слава Богу.

Зображення

Тепер ми робитимемо наше читання отак:
  • спочатку ми читатимемо не сектор як думали, а 8 їх, тобто сторінку - всеодно далі CFV буде більшим, і в цій зчитаній ділянці тому читатимемо заголовок, перевіряючи його і витягаючи з нього розмір всього тому.
  • а далі дочитуватимемо недочитані сектори, кладучи їх один за одним.
Отак потихеньку, ми наблизилися принаймні до точки, де має розгортатися повнофункціональна фірмваря. Її, звичайно, ще треба написати. :)

Ну і трохи Гаврилівни, як я й обіцяв. Така SCSI.
Зображення



А тут Кайлі показує сценку, яка називається "твоє лице, коли написав багатоблокове читання з SD картки і воно запрацювало."

Зображення
  • 0

#137 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 26.10.2017 – 00:35

Зараз ми працюємо над утилітою PeGen - генератор PE файлів з ELF файлів. Поки простенька - ми контролюємо більшість параметрів вихідного виконуваного файлу через скрипти лінкувальника - чого б ні, адже цей інструмент уже є і його не треба писати (нащастя, завдяки цьому і також завдяки факту, шо між ELF і PE секціями можна встановити задовільну відповідність, ми маємо шанс отримати трансляцію відносно швидко і легко). Тож наша трансляція не матиме таких клопотів як наприклад пересовування секцій, їхнє зливання тощо, і релокації, які вона за собою тягне. Наша перша мета - досягти стану утиліти, в якому вона зґенерує наш перший простенький PE файл для efify. Він покишо більшою мірою тренувальний - halefi.sys. Це драйвер чипсета і hardware abstraction layer (HAL) в майбутньому - тобто платформспецифічна частина ядра Dxe. А зараз, поки, - тестовий майданчик для вищезгаданої утиліти, ну і для стрибка з TCSM (де виконувався весь наш попередній кід) в SDRAM. Тут ми перемикаємо стек, друкуємо рядок вітання з нової фази, і вертаємось назад в SEC. Ото й увесь "драйвер чипсета" на поки шо. :D До речі, про "друкуємо". Чим друкуємо? Засобами з SEC. А як це зробити, якшо SEC модуль і цей модуль не лише сидять в різній пам'яті (якраз це нестрашно зовсім), але головно - ніяк не злінковані! Злінкувати їх динамічно, засобами PE, - це й є один з тестових пойнтів. Чи понтів. :D Це робиться за допомогою IAT - import address table. Нам в вихідному файлі модуля доведеться робити її руками, а SEC, під час вантаження цього модуля, halefi.sys заллє таблицю потрібними вказівниками на свої сервісні функції. Друку в цьому випадку. В асемблерному файлі робити руками легко. А от шо робити коли дійде до C?... Адже цей порт GCC не має й гадки про PE. :( Еквілібристика з директивами всякими, - відповідь.

Наостанок невеличка нотатка, це зручно, я не раз заглядав сюди уточнювати, шо ж я саме хотів робити, забувши точно шо саме, але пам'ятаючи, шо згадував про те тут.
Нотатка про розкрій в пам'яті (SDRAM пам'яті), шо куди класти. У нас була невеличка проблема. Пам'ять для ФВ починається на 80000000. Перше, шо нам виходить класти в пам'ять, це CFV. Але його довжина мінятиметься з часом. Якшо класти все по порядку, виникає проблема з визначенням бази для Dxe.exe, чи або ось для нашого halefi.sys - будь якого PE образу, який іде першим, і який грузиться SEC фазою, яка, звісна річ, - не вміє робити релокації! Не те, шо неможливо її визначити, ту базу, але незручно, якось криво виходить. Спочатку треба зібрати CFV, який і міститиме цей образ, подивитися який розмір CFV вийде, і потім, з цього, вирахувати базу образу, і перелінкувати його цю базу. Або ж робити релокації в SEC чи на часі ґенерації CFV. Ненайлегший підхід! Але млинець, мене осінило - а чого ж не відтінювати CFV (це так по-научному називається факт завантаження тому в пам'ять) десь в інші позиції?! Адже вся пам'ять доступна! Та яка не вимагає трансляції принаймні. Згадуйте, згадуйте, шо за це діапазони такі в MIPS архітектурі, - які не вимагають трансляції, інакше нашо я все оте писав повторюючи по багато разів? Так от, 80000000 ми лишаємо для образу першого виконуваного модуля, а CFV відтінюємо в кінець доступного діапазону. Мінус виставлений максимум для тому, який налаштовується. Кінець це 90000000, "максимум" - 256 КБ поки, ось відповідні визначення з заголовку:
#define CFV_MAX_SIZE		0x00040000	/* let it be 256 KB for now */

#define FW_SDRAM_BASE		0x80000000
#define FW_SDRAM_END_EX		0x90000000

#define	CFV_RAM_BASE		(FW_SDRAM_END_EX - CFV_MAX_SIZE)

Тепер виходить красиво. Далі, стек. Стек іде одразу перед CFV образом. Тобто перший байт за дном стеку, це перший байт MM_CFV - відображеного в пам'ять CFV.
Його розмір ми вибрали теж в 256 КБ. Чи й знадобиться стільки? Але шо нам шкода? :D Ми всеодно взяли 1024-ту частину від доступної адресованої пам'яти на це. І 4096 від загальної, якшо ми організуємо багаторівневу PA-VA трансляцію з каталогом і таблицями.
Оце наша нотатка про розкрій. Цього разу без корцінок. Покишо принаймні. Нема часу!
Спочатку іде головний образ B) Dxe (пізніше це буде Dxe.exe, а зараз - halefi.sys), цей образ має валідну базу, підготовану на етапі його збирання, і на неї ж він грузитиметься. Це 80000000 як уже сказано. Наступні модулі, матимуть dummy базу 10000000 (ну як DLL-ки), і PE-завантажувач в Dxe ядрі динамічно визначатиме їхню справжню базу. базуючись на тому, скільки місця вже зайнято. І прикладатиме базові релокації до них, перш, ніж викликати їхні точки входу.
Далі, на якійсь відстані від "зони образів", починатиметься область динамічних даних - де ФВ вибудовуватиме свої кореневі структури, для обслуговування всіє решти, а далі - зона динамічної алокацій, пул або купа - для всіх - це для всіх, хто для своїх потреб виділятиме пам'ять через відповідні сервіси UEFI.
Але все шо іде за образами і до стеку, це ще попередні намальовки. Визначеність поки є лише шодо того, куди класти образи, CFV і стек. Про шо й нотатка. :)

Повідомлення відредагував _Ex: 26.10.2017 – 00:36

  • 0

#138 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 26.10.2017 – 16:20

Ну от, купив в один день на аліекспресі Банану і SATA-USB3 адаптер, розказував. Адаптер вже приїхав, а банана за статусом навіть Китай не полишила. Продавці різні, різна методологія. :D Шо ж, чекати ймемо!
  • 0

#139 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 04.11.2017 – 17:13

Возячись з ELF -> PE транслятором, виявив в своєму плані деяку неефективність. А саме, я збирався відтінювати в пам'ять CFV, а потім образ за образом, "завантажувати" їх, вже на виконання, власне копіюючи ще кудись, і там вже налаштовуючи адреси (прикладаючи релокації). Але це вигідно було лише для одного - SEC фаза не мала робити релокацій, коли завантажувала Dxe Core. Всеодно ж, вся решта виконуваних образів мали б зазнавати релокацій, і, відповідно, Dxe завантажувальник образів мав би їх робити. Чого так, бо лише перший образ справді легко завантажити на якусь конкретну адресу, шо знімає необхідність робити релокації для нього. Для всіх інших модулів, "вгадувати" куди б вони мали попасти - це марнота і костилі. Але разом з цим, такий підхід давав зайве розкопійовування вмісту CFV. Тоді як виконання прямо з CFV можливе! Єдине, шо для Dxe Core теж доведеться робити релокації, бо це негнучко і незручно на пальцях вираховувати, де в CFV опиниться Dxe і відповідно прописувати в самому образі цю адресу.
Тож, оце поправка - тепер в обох модулях, де робитиметься завантаження виконуваних модулів, робитиметься релокація, і всі модулі лінкуватимуться на dummy адресу. У нас повторю є ініціальний завантажувальник - це SEC фаза, яка завантажує лише Dxe Core, і вся решта (Dxe драйвери) вантажиться лодарем всередині Dxe.
І головний вислід з цього - виконання відбуватиметься з самого CFV. Ніякого додаткового копіювання виконуваних образів не робитиметься. Оптимізація. У нас нема на рівні ФВ дворівневої адресації з мапуванням між системним адресним простором і процесорним адресним простором. Трансляція тривіальна для міпса, як я вже казав. А на армівських цілях - identity mapping. Шо власне те саме по суті, бо всеодно ефективний адресний простір лише один. Через це відпадає необхідність і волокіта пов'язана з секційно базованим мапуванням образів. Балакаючи в термінології PE, файлові офсети (ФО) і RVA стають чимсь одним якісно й кількісно. ФО це позиції секцій внутрі файла, RVA - це відносні до Image Base офсети секцій (і інших сутностей) внутрі пам'яті, після того як образ відображено в пам'ять. PE відображає образи посекційно. Звичайно, чи варто казати, шо мені цей підхід видається значно продуманішим, ніж ELF-івський, де відображаються "сегменти" - ще одна надбудова над секціями, власне непотрібна вигадка, дублікати секцій.
На фірмварі, всього цього нема - відображення іде значно примітивніше - весь файл відображається, і відносні позиції секцій в пам'яті залишаються як були в файлі. От це воно - це дає не розкопійовувати образи знову, а налаштовувати їх на виконання прямо в відображеному в пам'ять (відтіненому) томі. Прив'язування секцій до сторінок з мудрованим відображенням потрібне для повнофункціональних систем як ОС, де воно виокристовується для захисту (секції лише на читання прикручуються до сторінок з відповідними атрибутами, Copy on write оптимізація, розділення секцій лише на читання/виконання між різними процесами (шо вимагає правильного відображення в їхні адресні простори) і багато чого іншого). Фірмваря має один адресний простір, і виконується в привілейованому режимі, тож це тут просто до лампочки.
Тепер нам треба і Dxe.exe робити relocatable, але його релокацію робитиме SEC, шо означає, нам треба додати туди відповідний кід.
Ну а покишо ми мучаємося з утилітою, ця бісова трансляція виявляється значно капризнішою, ніж про неї думалось.
Основна суть поправки, - тепер ми читаємо з SD картки CFV в пам'ять, і після невеличкої перевірки його голови, :D шукаємо в томі Dxe Core образ. Найшовши, ми там же прикладаємо до нього релокації - тобто виправляємо усі адреси, які зустрічаються в коді і даних - і передаємо на нього керування. Чи не круто?
Так CFV стає не лише сховищем, він буквально стає двигуном, який і працюватиме. Після невеличкого марафету, у вигляді релокацій. Дивіться, як воно візуалізується - оцей шматок в кілька десятків кілобайтів, може з сотню, стає "душею" машини на цей час, виконуючи інструкції прописані там, процесор (і компанія) втілюватимуть функціональність. Ось чого це називається software на противагу hardware. Шматок інформації стає "пристроєм", який шось справді робе, і лапки там тільки того, шо цей пристрій це не кремній а саме послідовність інформації. Шось тонке неощутіме. :D
  • 0

#140 _Ex

    STATUS_OK

  • Користувачі
  • PipPipPipPipPipPipPipPipPipPip
  • 1753 повідомлень
  • Стать:Чоловік
  • Місто:Бахмут, Південна Слобожанщина, Україна

Відправлено 18.11.2017 – 00:44

Отже, ми організували уже зчитування з SD картки, спочатку то було просто проба зчитати шось, тепер це, як і писалося вище, - зчитування 1-го сектора, де знаходиться заголовок CFV, перевіряння його (сигнатура, чексума), витягання звідтіля розміру тому, і дочитування решти. Виявилося, шо картка не хоче читати один сектор командою 18 (читання багатьох секторів), мовчить зараза, і контроллер пише респонс таймаут... Також не працює командою 17 з автоматичним відсиланням коанди 12 (стоп читання), пише "незаконна команда", ну гаразд, тут може вона й права, але в першому випадку - точно якийсь бзик. Тож ми таки вблагали її, додавши маніпуляцій в кід, який тепер шле або ту або іншу команду залежно від кількости блоків, які потрібно зчитати.
Отже CFV тепер в пам'яті. Зважаючи, шо ми надумали, як вже казалося, підготовувати виконувані образи на часі будування тому, робити їх XIP образами, execute in place - це означає, шо непотрібно робити релокацій завантажувальнику, в ролі якого тут виступає Sec фаза, все менше лишається до її стану, коли можна сказати, шо вона більш менш завершена. Звичайно колись ще треба додати читання з NAND, але це поки не горить, ми не чіпаємо нанд.
Шо лишається додати? Ґенерація HOB списка. Тут, після обмірковування, стало заманливо і це винести на час будування. Я написав код, який заливає цей список, і стало явно видно - це дуже статична фігня. Нашо щоразу, на кожному завантаженні машини, генерувати його, якшо можна зробити це раз, і покласти на SD картку, одразу за CFV? Тим паче, шо він маленький. Так і робитимемо. Цей список описує для Dxe фази - шо за алокації Sec фаза зробила, де знаходиться память, де знаходиться відображений в память CFV, і де лежить стек і скільки його.
Тепер треба лізти в CFV і шукати там файл Dxe Core, за його GUID'ом, і, розібравши/перевіривши його - стрибати на його точку входу, передаючи як аргумент адресу HOB списка. Оце якраз і є шо лишається зробити внутрі Sec. А ззовні її, треба доробляти генерацію PE і FV. Ці утиліти ще не готові і не видають потрібних вихідних файлів.
На цьому робота Sec фази завершена. До речі, назараз, її розмір склав 3845 байтів. Нагадаю, ми маємо жорсткий ліміт в 14 КБ. Пошук і розбирання dxe.exe додасть трохи. Читання нанду, думаю, додасть не мегше пари кілобайтів, наприклад модуль читання SD картки важить 1140 байтів.
А в Dxe, першим, шо слід робити, - це нарешті таки братися на менеджмент памяти. Лише потім вся решта.
  • 0



Кількість користувачів, що читають цю тему: 1

0 користувачів, 1 гостей, 0 анонімних