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

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

GPT UEFI FAT

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

#61 Aquarius-ka

    Цьотка-з-Занзібару

  • Користувачі
  • PipPipPipPipPipPipPipPipPip
  • 928 повідомлень
  • Стать:Жінка
  • Місто:На тамтім боці

Відправлено 27.02.2017 – 00:14

Дякую за гостиннійсть, Ех-е, вибачайте, якщо що :) Про життя в теплих краях у мене є закинутий блог, може б і мені вернулось натхнення писати...
  • 2

#62 _Ex

    STATUS_OK

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

Відправлено 27.02.2017 – 00:15

Перегляд дописусерпиня (27.02.2017 – 00:09) писав:

Я не правильно спитала) Виправляюсь: а можна тут залишитися зі сковорідками? :)
Можна. Але з ними - мовчки. :lol:

Перегляд дописуAquarius-ka (27.02.2017 – 00:14) писав:

Дякую за гостиннійсть, Ех-е, вибачайте, якщо що :) Про життя в теплих краях у мене є закинутий блог, може б і мені вернулось натхнення писати...
О, о, - гарна ідея. Попишіть. А ми почитаємо.
  • 2

#63 Aquarius-ka

    Цьотка-з-Занзібару

  • Користувачі
  • PipPipPipPipPipPipPipPipPip
  • 928 повідомлень
  • Стать:Жінка
  • Місто:На тамтім боці

Відправлено 27.02.2017 – 21:11

Перегляд допису_Ex (27.02.2017 – 00:15) писав:

О, о, - гарна ідея. Попишіть. А ми почитаємо.
Дякую, Ех-е :) Ось стара розповідь про наші пригоди з ураганами:
http://asvichinska.b...mer-of-2004.htm
Я з радістю сприйму відгуки (у блозі), навіть критичні ( знаю, блог запущений та потребує графічного оновлення), ну і всякі інші, але без обзивалок, пліз ))
  • 2

#64 _Ex

    STATUS_OK

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

Відправлено 05.03.2017 – 14:38

Треную мій міпсівський асемблер. :brovy: хай як це звучить, там нема нічого нескромного. Ось наваяв функцію, яка друкуватиме в послідовний порт наші Хелло ворлд сповіщення. Звичайно, там вище ще купа ініціалізації, а це саме друк. Це найнайраніший принт, тож все дуже суворо. Код ясношо ще навіть не перевірявся на помилки. Після армівського асемблера, до міпсівського ще треба звикнути. шось легше шось важче, загалом все набагато простіше організоване на гастроентерологічному архітектурному рівні (наприклад контроллер переривань, це ж просто легкий подих вітерцю після штормів всіх тих APICів LAPICів SAPICів GICів, взагалі архітектура побудована значно простіше (окрім бісових delay slot'ів!!11), це одна з найстаріший RISC архітектур):
UartPutString:
	beq	$zero, $a0, 2f		/* s == 0? */
	li	$t0, UART4_BASE
1:	lbu	$a1, ($a0)
	beq	$zero, $a1, 2f		/* *s == 0? */
putc_:
	lw	$t1, UART_ULSR($t0)
	andi	$t1, ULSR_TDRQ
	beq	$zero, $t1, putc_	/* busy wait */
	nop
	sw	$a1, UART_UTHR($t0)	/* writing! */
	b	1b
	addiu	$a0, $a0, 1
2:
   jr	$ra
   nop
Це шматок SEC.S з йоду, міпсівської машини, пам'ятаєте? Тут мало SRAM'у (16 КБ, 14 доступно), точніше тут воно взагалі називається TCSM - tightly coupled shared memory. І його мало. Того наша Sec фаза має швидко ініціалізувати пам'ять (DDR3 тут) і грузити Dxe.exe - Dxe фундацію. Ось зараз ми розбираємося з UART`ом (а заодно з GPIO), а далі, треба нарешті братися за PLL, SDRAM ініціалізацію - центральну річ для цієї фази, і, через надто малий об'єм TCSM, треба ще вчитися читати з SD-картки, бо якшо перші версії Dxe.exe і влізуть в 14 КБ, то далі - точно ні. Треба одразу братися його робити так як воно має бути в повному юзабельному стані. Ну а TCSM ми звичайно використовуватимемо - для коду який має лишатися в суспенд режимах - тобто для наших заповітних мрій за ACPI і крутий павир мениджьминт. ^_^

Короткий опис, шо і як там робе? Функції передається вказівник на ASCII-рядок, нуль терминейтид, вона перевіряє чи цей вказівник не нуль. якшо нуль, функція мовчки виходе. далі круте цикл в якому на вході перевіряє чи символ не нуль (термінатор рядка). якшо нуль, виходе.
Саме писання робиться в UART4 (їх 5 в цьому соку), ми налаштовуємо RxD лінії TxD в GPIO (порт C), тобто призначаємо їм одну з функцій, які там розділені (максимум чотири функції на порт, не всі зайняті). Далі забороняємо UART4 модулю робити переривання. Вмикаємо FIFO-режим. І читаємо біт TDRQ (Transmit Data Request) в ULSR (UART Line Status Register) регістрі. Це ридонлі біт який каже (в FIFO-режимі), шо FIFO наполовину пуста. Якшо у нас заборонені переривання, і вимкнене DMA, тоді нам треба опитувати цей біт в активному циклі, шоб знати, шо ми можемо закинути в UTHR (UART Tranmist Hold Register) ще даних. Саме так ми й робимо - таке рішення можна дозволити лише на такому ранньому етапі і ненадовго. Далі треба вмикати переривання, або ще краще - DMA.
От, щойно ULSR.TDRQ виставлено, ми пишемо в UTHR - це врайт-онлі (і таке бува) регістр, така собі гаряча точка в FIFO - пишеш в нього символ, і він попада в FIFO.
Оце й увесь UART покишо. Дуже примітивно, але далі будуть самі пакращення.

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

  • 0

#65 _Ex

    STATUS_OK

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

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

whoops, а ось і ділей слоти дали про себе знати. коротше, ось оця послідовність:
		beq	 $zero, $a0, 2f		  /* s == 0? */
		li	  $t0, UART4_BASE
неправильна. стрибок (beq) це інструкція, яка має ділей слот - наступна інструкція буде виконана незалежно від того чи буде галуження взяте чи ні. Але лише одна інструкція лежить с слоті. А ми туди написали псевдоінструкцію - яка часто розгортається в більше, ніж одну інструкцію. Вона зручна, і навіть дозволяє оптимізацію яку вручну не зробиш (лише через це ми й використовуємо її, бо інакше миуникамо псевдоінструкцій). Але от вона має такі неприємні сайд ефекти. Спасіба асемблер попередив. Код угорі розгорнеться в шось таке:
		beq	 $zero, $a0, 2f		  /* s == 0? */
		lui	 $t0, %hi(UART4_BASE)
		ori	 $t0, %lo(UART4_BASE)

Нам в регістр $t0 треба загрузити всі 32-біти UART4_BASE. Це роблять дві інструкції. Одна пише горішні 16-бітів іммедіейта в горішні 16-бітів регістра. Друга долішні. Якшо галуження взяте, виконається тіке перша. Логічно це не правильно. Хоча по суті тут це не страшно, адже галуження тут береться в разі якшо адреса рядка = NULL, ми стрибаємо в край функції і виходимо. Просто треба розуміти, шо не завсіди це не страшно, треба пам'ятати, про оцю непросту взаємодію псевдоінструкцій з ділей слотами.
Ми викинули псевдоінструкцію тут і поставили отако расово повноцінно. Зато додали лишньої роботи (1 інструкцію перед перевіркою вказівника на нуль). Але це буд езайвим лише в разі якшо вказівник є NULL, а це помилка, не має траплятися. Расовоповноцінний варіант:
	lui	$t0, %hi(UART4_BASE)
	beq	$zero, $a0, 2f		/* s == 0? */
	ori	$t0, %lo(UART4_BASE)

Ну і про успіхи. :D код вже принаймні компілюється. Ми навіть зґенерували SEC блоб з нього. Потягнув він аж на 200 байтів. :lol: Початки стартового коду. Під спойлером весь код йодової SEC фази на цей час.
Прихований текст

якшо хоч хтось (хто знає міпсівський асемблер) уважно гляне на код, він побачить, шо смисла в ньому ще нема ніякого.) Я навіть у вхідну функцію ніякого виходу не додав. Так вона і заскочить в UartPutString.) Це того шо це WIP. Цілий вечір прошукав специфікацію на регістри, вже почав думати шо Акробат зі мною жартує зло. Виявилось я просто гальмо. Трохи ганьби і ось ми вже на порозі до найголовншого тут - ініціалізації пам'яти. :)

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

  • 0

#66 _Ex

    STATUS_OK

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

Відправлено 16.03.2017 – 22:49

Великий практичний успіх досягнуто, панове: вперше наш код спричинив помітну для ока дію - він вже вміє перемикати LED. :D На йоді на платі є один діод, він завсіди світе коли плата живлена, але він світе або червоним або синім, залежно від певного сигналу - чи той хай чи лов. :) От є такий GPIO банк F, і там біт 15 визначає хай чи лов буде сигнал. Треба налаштувати правильно цей порт і записати туди 1 чи 0. Якшо нуль, то діод світитиме синім. червоним навпаки.
Довелось потріпати чимало нервів поки це запрацювало, ну це очікувано, але не менш нервово. Просто як і слід було очікувати, все в референсах наплутано. А саме, убутовий старт каже, шо треба виставляти біт, шоб було синє, ось кодес:
int board_early_init_f(void){
	    /* SYS_POWER_IND high (LED blue, VBUS on) */
	    gpio_direction_output(32 * 5 + 15, 1);
	    return 0;
}			
Як ви здогадалися, все навпаки. Прикол тут в тому, шо діод червоний на старті, такшо якшо ви думаєте шо виставляючи біт ви робитимете його синім, як каже комент вище, ви нічого не побачите. він як був червоним, так і залишився. думатимете шо ніхрєна не робе... так оце й я промудохався з цією кашою. все переплутано все. (це далеко не єдине, просто нема сил переказувати все).
Так ось, нарешті наш стартовий код виконався і дав помітні оку результати. тобто наш код завантажено (з SD картки) і передано на нього керування. Супер. Тепер він перемикає діод. Далі він має ініціалізувати UART - RxD і TxD піни, так само налаштовуючи GPIO як і з діодом (тіке банк C). Далі налаштовувати сам UART. Далі він має читати трійку регістрів пов'язаних з тактвомим сигналами (клоками) і PLL, і трансформувавши значення в рядки чисел, друкувати їх в послідовний порт. Разом з вітанням до світу. Але термінал мовчить. Тобто там ми накосячили. :D
Все ж, успіх є!
  • 0

#67 _Ex

    STATUS_OK

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

Відправлено 17.03.2017 – 21:49

Ну ось воно, панове - перший друк в послідовний порт. покишо лише дуже несміливі кроки. Внизу, отой рядок UefiUefi - це написав наш стартовий код. Все шо вище - то попередня сесія крепекса.
Радіємо, панове, радіємо:
Зображення
  • 0

#68 _Ex

    STATUS_OK

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

Відправлено 19.03.2017 – 16:08

Трохи прогресу, трохи красивше виведення. Нарешті ми можемо друкувати в послідовний порт нормально. Скриншот внизу. Виявилося, шо проблема була не з UART ініціалізацією чи неправильними функціями які друкують, той попередній скрин як виявилось надрукувався навіть функцією з жахливою помилкою всередині. :D З часом виявилося, шо проблема була в ... неправильній адресі на яку злінковано образ. Того будь які звернення до власних функцій, не робили. Це дуже "цікава" тема, яка відкриває певну специфіку документування в мануалі. Шоб не переказувати наболіле, чуваки зробили такий складний чип, а задокументувати його нормально полінилися. От і вийшло все навпаки. Пишуть сектор #0, а насправді - сектор #1. Пишуть рядок "MSPL", а насправді - "LPSM". Пишуть, шо адреса f4000000, а воно f4000a00... От воно і виходить "трохи" складніше. Коротше, вони просто сказали, шо TSCM починається на f4000000, і шо вона 16 КБ, але грузять вони тільки 14 КБ. Куди вони грузять вони не сказали. І чого вони пропускають два КБ. теж не сказали. І шо це має за наслідки, теж не сказали. Потім я вже здогадався зробити такий трюк - я вибрав команду в моєму коді, яка не є такою вже поширеною, я вибрав виставляння стеку, це друга інструкція в моєму коді, взяв її сигнатуру, тобто її кодування, і в самомому коді прокрутив усю пам'ять спочатку від f4000000 до f4000800, тобто перші 2 КБ. А потім наступні 2 КБ. Шукаючи цю сигнатуру в кожному слові (4 байти) TSCM, тобто шукаючи мою інструкцію. І я найшов її! На адресі f4000a08! Тобто в другому 2 КБ-ному сегменті TSCM, на позиції 512+8, очевидно ром-код грузе наш код на адресу другого сегменту, а не першого, і, надодачу хоча й перевіряє сектор 1 картки на отой рядок вище (насправді рядок задом наперед від того, шо вони пишуть в мануалі), але грузе він і сектор 0, тобто MBR сектор. А оскільки наша шукана інструкція друга, а всі інструкції 4 байти, і плюс та сигнатура задом наперед, теж чотири байти, - то, ясно, наша інструкція є на адресі a08 відносно бази TSCM. А образ злінкований на адресу f4000000 - тобто на початок першого сегменту.
Шерлок Голмс би позаздрив такому розслідуванню. І воно звичайно круто було вирішити цю проблему, я типу пишаюсь собою і всі діла, але ця інфа мала б бути записана в мануалі! А я б уже мав виставляти тактові частоти і ладити SDRAM. Теж було б чим попишатися. Ну', як є. Хлопці з Індженика, хай вам гикнеться за такий класний мануал, який ви написали.
Ну і пакращений скриншот. Оті цифри, то деякі регістри. Знову ж, оскільки документація не дуже охоче розкриває свої секрети, то ми не тіке вітаємо світ і Гаврилівну!11, а заодно вже взнаємо практично, шо ж там таки лежить. Якшо вони правильно описали, шо там має лежати, то ми сподіваємось в найближчий час виставити PLL для пам'яти зокрема і ініціалізувати її, тобто - SDRAM.
Зображення

Повідомлення відредагував _Ex: 19.03.2017 – 16:12

  • 0

#69 _Ex

    STATUS_OK

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

Відправлено 21.03.2017 – 22:03

Отже наш код вже вміє ініціалізувати PLL (phase locked loop, замкнена фазою петля :D) і перемикати (на ці PLL) джерела тактових сигналів кореневої логіки, :gryzin: тобто для процесора, його кеша 2-го рівня, AHB0 і AHB2 шин і їхніх дітей. Це, дуууже хардкорна частина ранньої ініціалізації - не коники з гімна ліпити. :) На йоді суть 4 PLL - APLL, MPLL, EPLL, VPLL. Ми ввімнкули і налаштували перші дві. Перша дає частоту процесору і кешу 2-го рівня. Друга - AHB0 і AHB2 шинам, а також DDR і периферії. У плл, є вихідна частота, а в контрольному регістрі CPM модуля (клок павир мениджьминт), є ділителі для процесора, кеша, згаданих шин і периферії. є і для DDR, в іншому регістрі, є ще багато регістрів для багато чого, але ми поки за це - чипсет так би мовити. Ми налаштували вихідну частоту APLL на 1200 МГц, MPLL - на 400 МГц. 1.2 ГГц - це схвалена максимальна частота для цього процесора. Але ми зробили її 200 МГц, цього хвате для ФВ. Кеш і згадані шини - на 100 МГц, перифіерійний ділитель виставили на 50 МГц. Пам'ять поки не ініціалізована. Це - самий ахтунг. Пік ахтунгу в ранній ініціалізації.
Не обійшлося без прикрих поимлок, але тішить, те, шо вдалося здогадатися за них, і зрозуміти чого ж воно не працювало.
Новий пакращений скриншот під спойлером. А от чого плата запускає наш код двічі - це й досі містерія. Він все запускає двічі, і убут теж. Навіть на відіа від інших чуваків видно шо діод ввімкнувшись, одразу вимикається, а потім знову вмикається. Хех, знати б кого спитати. Але нас це курвит і ми шукатимемо пояснення.
ЗІ. Енд єт, пліз, донт пей атеншн то май інгліш, іц авфул. :facepalm: аур праймері прайорити воз коуд коректнес, нот притті граматикс тхо. :)
Прихований текст

  • 0

#70 _Ex

    STATUS_OK

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

Відправлено 22.03.2017 – 17:41

Трохи опинсорса. :lol: Мабуть же зацікавлений читач може схотіти побачити, як робе те, про шо ми писали в попередніх кількох дописах. для таких викладаю увесь вміст файлу SEC.S для йоду, за винятком заголовкових файлів, це було б забагато для форумного допису. але ті файли це для асемблерної програми, тож нічого крім #define'ів там нема. просто зручні імена, які ви бачите в коді визначені там. за ними стоять числа - адреси, зміщення, флажки, і інші значення.
ось так виглядає міпсівський асемблер, і це наша Sec фаза, яка покишо вміє те, шо ми показали в попередньому скріні (це майже, бо я трохи поприбирав, не змінивши логіки (сподіваюсь :lol:)):
Прихований текст

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

  • 0

#71 _Ex

    STATUS_OK

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

Відправлено 23.03.2017 – 15:47

Ніхто не хоче допомагати з вибором частоти таймера, ніхто не читає, аж обідно.
ну та й нехай (я знав, шо ця тема не збирає стадіони, навіть спеціальний форум для таких занять напівдохлий, і дописи переважно про gcc який не хоче бачити якісь хедери чи про GDT яку ясно шо нові кулхацкери одразу подужати не можуть).
шо ми вибрали покишо.
таймер, OST в нас може отримувати вхідний такт від RTC, EXTCLK чи PCLK. Перший - це для годинника, справжній час тобто, повільний лічильник. Другий це 48 МГц осцилятор, третій - це 50 МГц периферійний тактовий сигнал який дає нам щойно налаштована MPLL. Саме з використанням останнього менше всього мороки - нема обмежень. Ми вибрали його.
Тепер в таймері є внутрішня частота - як часто оновлюватиметься лічильник. Її визначає PRESCALE поле, яке може давати частоти які в 1, 4, 16, 64, 256 чи 1024 разів менші за вхідний такт. Тобто це ділитель. Ми поки вибрали 256. Тобто:
Fin = 50 000 000 Hz - вхідна частота таймера.
Ft = Fin/256 = 195 312.5 Hz - внутрішня частота таймера, частота оновлень лічильника.
Тепер нам треба вибрати компаранд, match, кількість одиниць лічильника через яку загориться переривання від таймера. Ця величина залежить від періода який ми хочемо. Ми вибрали 32 мс. Це 31.25 Гц (Fint). Очевидно:
match = Ft/Fint = 6250.
В підсумку, таймер тікає 195312.5 разів на секунду. Кожен 6250-й раз запалює переривання. Це значить шо пройшло 32 мс.
Тепер треба це все запрограмувати.
  • 0

#72 _Ex

    STATUS_OK

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

Відправлено 27.03.2017 – 16:38

трохи балаканини. перед наступом на SDRAM. всеодно шось голова крутиться сьогодні, нічого не робиться.
трохи опису про дальші плани. зараз ми робим початкову стадію ФВ, тут ми рухаємося (привіт полякам які можливо читають, чув у вас ця фраза викликає цікаві асоціації), рухаємося отже, в приниципі краще, ніж очікували - апаратура миготить діодами, клоки тікають, уарт пише. кул. але це все початки. далі все набагато складніше. тут ми просто взяли налаштували уарт на лише передавання, без переривань, без ДМА... Це можна довзволити лише в манесенькому блобі SEC фази. Уже в Dxe так неможна. Тим паче в HAL.
Ось роблячи цю дуже ранню ініціалізацію, тебе починають навідувати тривожні думки - ці всі пристрої тут, вони, їхня кількість, конфіґурування, є неналаштовуване, неперелічуване - non enumerable. це пагано. можна писати все вручну, витягаючи це з не дуже старанно написаного мануалу, вшиваючи це наглухо в твій код. так і будеш програмувати одну плату 15 років. треба ж система! ACPI. потужна вирвиочно потужна своєю психоделічною натурою, - ось вона нам треба. шоб ми мали організацію - ми за Індженик зробим на їхній SoC всі ці таблиці, які описуватимуть залізо, і вже наша HAL хоч більш менш однообразно оброблятиме це все - так ми не опинимось в ситуації, де ми на кожну плату матимемо вигадувати HAL. Хоч якась уніфікація. Ну не пише ж Майкрософт під кожну x86 плату HAL! А там плат хоч греблю гати - до Нептуна можна модельний ряд викласти.
Проблема в тому, шо крім ахтунговости ACPI самої по собі, ці платофрми як йодова, тобто SBC, ОПК, вони дуже ускладнюють уніфіковане представлення залізної конфігурації. не лише паганою документацією, а ще гірше - паганою організацією самої платформи.
От справді, на PC, теж суть неперелічувані пристрої, але їх там мало, а вся решта сидить на шинах, які вміють Plug and Play, які вміють перелічувати своїх дітей - PCI, USB. Тобто є жменька специфічних пристроїв, які треба "вшивати" в HAL, але більшість пристроїв обслуговується расовоповноцінним сучаним методом PnP менеджера. Дерево пристроїв динамічне і це дуже потужна властивість платформи.
Шо тут? На чому сидять OHCI/EHCI контроллери наприклад? eMMC/SD? NAND? Ethernet? HDMI? GPU? VPU? Тут все це є, але яка струкртура дерева пристроїв? Де це взяти? В мануалі є лише бази відображених в пам'ять регістрових наборів цих пристроїв. Наче все, шо треба, шоб їх програмувати. Але чогось бракує. Організації. Навіть про AHB шини, на яких сидить більшість згаданих компонентів нічого не згадується в мануалі. Чим ці шини є? Але і самі шини - дивлячись їхнє оверв'ю, там ти і близько не бачиш нічого такого як "енумерація", і подібна "фігня". Ну да, ділителі для частоти шин ти ж виставляв. Шо тобі ще треба?)
Тож вимальоується чимала проблема - представити цю кашу за допомогою ACPI таблиць. І писати свій HAL, який буде це використовувати.
Шо це за HAL? Оце і суть плани. Це Hardware Abstarction Layer нашої ОС. Я вже казав, це, ОС, є головна частина проєкту, фірмваря це важливий початковий підпроєкт. Копирсаючись з ініціалізацією, реально запускаючи код, стало ясно, шо не те, шо можна, але - потрібно одразу використовувати набуті знання і досвід і просто конкретну інформацію - шо оце тут робе так і не як інакше - треба одразу це нести у відповідну частину ОС, поки воно свіже і не випарилось, шоб не довелось винаходити і виясняти це знову колись. HAL це між іншого шинний драйвер (перелічувач) для всіх неперелічуваних наплатних пристроїв. Як ми вже сказали тут усе майже неперелічуване. :D Той же UART (їх там 5), хоча функціональний драйвер і буде винесений як окремий модуль, а хто створюватиме PDO для цих пристроїв, хто їх перелічуватиме? Хто керуватиме їхнім павир менеджьментом? Нема PCI! Які у нас кандидати на цю роль - бути переліченими HAL'ом? Усі кореневі контроллери, не тіке чипсетові фігні як контроллер пам'яти, переривань чи вачдог чи таймери. І тут уже не можна пропускати "на потім". Треба або точно і правильно увімкнути або точно і правильно вимкнути. Вимикати теж буде чимало чого - GPU, VPU - абсолютно незадокументовані наприклад. Це завдання за складністю і часом - на порядки важче нашого стартового коду.
Далі. Треба ж саме ядро писати. :lol: І Executive компоненти - до речі, шоб ви знали у нього, екзекутива тобто - це верхня частина ядра (логічно) псевдо - Ex.
Наша ОС є NT-подібна і має концепцію середовищних підсистем. Це там де живуть API під які написані різні програми. Ми вибрали робити дві ПС, підсистеми середовища. Перша обов'язкова (завсіди присутня, завсіди запускається на старті) - базова підсистема в дусі WinAPI, ясно шо. Але лише базовий набір - ми не подужаєм увесь той космос. Коротко - те, шо в kernel32.dll, advapi32.dll. Без графіки спочатку.
Друга ПС (необов'язкова, запускається на вимогу, якшо не сконфігурована інакше, має бути інстальована, може бути деінстальована), її вибір продиктований суто прагматичним фактором - під цей набір API написано дуже багато програм, які знаходяться у вільному доступі. Здогадались яка це ПС? Так, це POSIX. Ми не подужаєм писання всіх програм, і шоб наша систмеа була цікава іншим, ми маємо принести туди вже наявні програми (хоч які вони є). Посикс тут має перевагу, шо суть багато його відкритих імплементацій. Ми дивимся в бік BSD.
Далі, якшо проєкт получиться, треті сторони можуть імплементвати свої ПС. :D Або - додавати розширення до наявних - фреймворки (.NET, Java, або краще так - сісярп і жаба), графічні підсистеми, рівні сумісности (compatibility layers), останні наприклад, шоб ганяти бінарні модулі програм, написаних під якусь іншу ОС, яка має схожу, але несумісну ясношо імплементацію цього самого API. Це наприклад - рівнень сумісности для лінуксових застосунків. Шоб їх можна було ганяти на нашій посиксній підсистемі. Про ім'я цієї підстисеми. Я спочатку думав назвати її Nuxi, але потім передумав і назвав PussyX. :cool2: :lol: Так подобається ця назва мені! Вже ради цього, цю підсистему треба написати. Ну от я вже трохи посиксних хедерів зробив. :lol:

Повідомлення відредагував _Ex: 27.03.2017 – 16:40

  • 0

#73 _Ex

    STATUS_OK

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

Відправлено 27.03.2017 – 22:37

Підсистеми середовищ, ПС, це особистості ОС, personalities. Це те, шо баче пользун, це той дух, запах, філософія і решта інтиму, фетиш для дрокання все оте таке важливе для різних компутерних задротів. Як наприклад юніксоїди і їхня оболонка.
Для розробника ОС, це теж важлива частина. Майже те саме, шо для згаданих вище задротів. Просто він на це дивиться з іншого боку, :brovy: він має забезпечити, шоб та "особистість" працювала.
Вигадувати свій власний API - це круто, звичайно. Але. але. Це нікому більше не буде потрібно. Навіть теоретично. Треба якесь диво, шоб це когось зацікавило. Так зацікавило, шоб вони вивчили той API і написали тонни своїх програм під нього. Самому написати всі ті програми нереально. А от адаптувати наявний API - це знааачно практичніше. І теж дуже цікаво!
Зараз ще мало можна сказати деталей як ми все це робитимемо - треба більше взнати, більше продумати, більше зробити.
Але такі обриси. ПС складатиметься з кількох різних множин:
  • Бібліотеки підсистеми
  • Множина процесів-підтримувальників так би мовити.
  • Ядерна частина підсистеми.
Перша множина - бібліотеки, постачають інтерфейси (функції), API, цієї підсистеми, для клієнтів. вони завантажуватимуться в адресний простір кожного процесу, написаного використовувати цю підсистему, його потоки можуть викликати ці функції. Тут все ясно. Наприклад posix.dll і crt.dll - перша імплементує посикс-специфічні функції, друга - С-шний ран-тайм, який посикс включив в себе. Першу нам доведеться писати самим - вона сильно залежить від нашої ОС. Другу ми візьмемо вже наявні посиксні імплементації, наприклад NetBSD-шну, і, переробивши її, включимо в нашу PussyX. :D
Ці функції - це шлюз, до системних сервісів (викликів), які надає ядро. Тут PussyX може забезпечувати його в три різні способи, може вибирати найефективніший в кожному конкретному випадку:
  • Використовувати уже наявні функції з підсистеми за замовчуванням (це наша WinAPI-подібна ПС, ми її назвали Avril :D або AvAPI).
  • Використовувти "нативний" API, той, шо не залежить від ніяких підсистем і грає свою важливу роль в роботі юзер-спейсної частини ОС, це так, ntdll.dll, ви правильно здогадались. Власне це його головна роль - бути шлюзом в системні сервіси для підсистем. просто одні посиксні функції можливо матимуть вигоду використати роботу, яку вже зробила Avril ПС, далі та викликатиме нативну обгортку системного сервісу, тоді - перший варіант, а в інших випадках, - виклик може бути занадто специфічний для підсистеми, і його ефективніше буде імплементувати самому, обійшовши навіть ntdll.dll тоді - наступна категорія.
  • Служити шлюзом самим, викликати системні сервіси напряму. Очевидно цей шлях для дуже спеицифічних для посикса викликів. Тут бібліотека прямо викликатиме відповідний системний сервіс.
Далі, процеси підтримувачі. Це нативні процеси або процеси AvAPI, які забезпечують системний інтерфейс, який посиксні програми очікують від ОС. В найширшому сенсі цього слова - інтерфейс, все, шо не влазе в категорію API-шних функцій (які надаються категорією згори). Тобто. Наприклад модель організації файлової ієрархії. Хоч посикс і не диктує, які там папки мають бути, дуже мало він насправді диктує в цьому плані, але все ж, всі очікують певну модель файлової ієрархії в цьому середовищі. Це ж "філософія" та. Наприклад, внутрішньо ядро має простір імен (ПІ) об'єктного менеджера і сторонні ПІ туди вгружені - файловосистемні дерева, реєстр. А AvAPI-шна ПС робе звичне представлення томів - звичне для пользунів Windows, - тобто ліс дерев файлових ієрархій, кожен на своєму корені, якому дається буква і відділяється від решти шляху двокрапкою. А посикс хоче одне дерево. От оце треба забезпечити. Коротко кажучи, в обох випадках, обох ПС, підтримувальні процеси створюватимуть потрібні посилання на об'єкти в просторі імен об'єктного менеджера і воно робитиме. Грубо кажучи, для Avril, програма хоче написати в файл D:\Some\Path\somename.ext, за диском D: стоїть том/партиція, який/яка має об'єкт в ПІ об'єктного менеджера, шось накшталт \Devices\Volume3 або \Devices\{cafebabe-1011-d00d-cacafefe1342987c}, або взагалі \Devices\0000000f. підсистема створить зв'язок, ланку, між велновн іменем (напр D:) і волатіле іменем в ПІ об'єктного менеджера. Воно летке через PnP - витяг-засунув реалії, неможна покладатися ні на яку персистентність пристрою сховища, зокрема його, нема надії, шо він сидітиме на тому самому порті тощо. тож всі оті mmcblk0, sda, sdb - то кам'яний вік. А от посиксу треба, шоб той самий файл був як /some/path/somename.ext. Тут і чутливість до реєстру, і інші розділювачі шляху і один корінь для всіх дерев. <_< Це лише один однісінький аспект. А їх багато - відображення посикних атрибутів "дозволів" на рідну ACL базовану. А консоль! всі оті їхні tty - телетайпи тобто, ага 70-ті роки. Все, шо посиксні програми очікують в системі присутнім і саме так і не інакше має бути їм надано. І якшо програмні інтерфейси надають бібліотеки, то все різноманіття нюансів поза цим - надаватиметься процесами підтримувачами. Самі вони суть нативні процеси як сесійний менеджер (smss.exe), winlogon.exe, services.exe чи lsass.exe. Або взагалі AvAPI процеси. Як мінімум один такий має бути - pussyx.exe. От іще, "демони" оці, це служби. І вони такими і будуть. Але я майже не сумніваюсь, шо треба буде врахувати певні особливості для цих "демонічних" служб. Також старт - ми то вигадаємо як стартувати підтримувальників ПС, а от існують клієнти, тобто програми, які хочуть запускатися на старті зокрема, це більше належить до конфігурування системи, воно посиксом не диктується, і це таки робота для підтримувлаьників. Але всеодно там обов'язково спливуть речі, які користувачі хотітитимуть мати і які треба ще якось спеціально забезпечити. Єдине точно - наша посикс система НЕ покладатиметься на текстові файли конфіґурування. Лише реєстр. Це принципово. Знову, треба надати інтерфейс до цих сервісів на рівні API. Знову, це не є частиною посиксу, отже це може бути або просто використання advapi.dll з Avril, або якась мостова бібліотека чи служба. Насправді ще виясняти й виясняти. Тут варто наголосити - нас не цікавить відтворення того "як на лінуксі це роблять", нас цікавить забезпечення програмного середовища для програм, які написані за використанням POSIX API. Тож всі оті стартові скрипти, це механізм, не функціональінсть, нам треба забезпечити її, а механізми у нас для цього будуть свої. Стосовно посиксних сигналів і їхнього доставляння, тут APC використовуватиметься, і я не можу точно сказати ще, де саме це сидітиме. Ну ясно, шо ядерна частина в ядерній частині підсистеми (дивись нижче). А юзерна - скоріше за все в бібліотеці posix.dll.
Третя частина, ядерна. Драйвер-розширення, який забезпечуватиме додаткові системні сервіси, які нікому більше не потрібні але потрібні цій підсистемі. Наприклад знаменитий fork(), наше розширення якраз його й імплементуватиме, як який небудь PsxFork(). Розширення системних сервісів - це найефективнший механізм втілити таке. Драйвер реєструє свій набір системних сервісів (викликів), і обслуговує їх (ефективно). Сповіщає диспетчер системних сервісів, шо ось він надає ще трохи сервісів, виклики до яких теж тепер треба враховувати і обслуговувати (диспетчеризувати). Якшо підсистема не використовується, ця функціональність навіть не завантажена. Він же забезпечуватиме ядерну складову доставляння посиксних сигналів (роблячи їх з APC) і всю функціональність, яку можна забезпечити лише в ядрі, і якої ще там немає. Насправді, як і у випадку сигналів зроблених з APC, він слугуватиме мостом до наявної функціональности. Ясно? шо наприклад ми використовуватимемо той самий Security Reference Monitor, шо й решта, для безпеки, - ядерне розширення ПС робитиме відображення між тим, шо очікують його юзерспейсні клієнти і тим, шо очікує згаданий монітор. Концепутально це посиксний аналог win32k.sys, за винятком, шо останній - дуже дуже заклопотаний з графікою. наш еквівалент - avrilk.sys такою хнею не страждатиме покищо графіку не чіпатиме, так же як і posixk.sys. Але якшо графіка з'явиться, її ядерна складова піде в перший, очевидно. (Драйвери графічних адаптерів ясне діло - робитимуть своє). Просто графіка - це ж так складно, ми її згадуємо лише для повноти картини і шоб помріяти. :)
  • 0

#74 _Ex

    STATUS_OK

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

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

Кріатіф - ось шо я поки зробив в посиксній ПС. :lol: Рухається. з прискоренням, і ніякі сили на неї не діють.
Зображення

Повідомлення відредагував _Ex: 28.03.2017 – 01:07

  • 0

#75 _Ex

    STATUS_OK

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

Відправлено 28.03.2017 – 21:25

Ми вже торкалися трохи питання як і коли компоненти ПС запускатимуться в нормальному плині роботи системи, розглянемо це трохи деталізованіше.
Найясніше ситуація з бібліотеками ПС. Система завантажує їх в адресний простір кожного нового процесу, який їх потребує. Це видно через таблиці імпорту його виконуваних файлів. Тобто на часі створення, програміст має злінкувати (динамічно) свої програмні модулі з потрібними бібліотеками. Завантажувальник (програмний) на старті процесу, побачить це і обробить правильним чином. Формат виконуваних файлів - PE. Підтримка ELF також можлива як опція. Система не дублюватиме звичайно ці бібліотеки в пам'яті - всі RO і X секції (RO - read-only, X - execute) лежатимуть в фізичній пам'яті в одному екземплярі. Це між іншим означає, шо ефективність (по простору тут) для нас важливіша за "teh security" - ми збираємося завантажувати ці бібліотеки за напередвизначеними адресами, і не збираємося робити ASR - address space randomization. В часи коли захист від виконання підтримується на рівні керування пам'яттю, за допомогою спеціальних атрибутів сторінок, рандомізація адрес - це марнота марнот.
Ці бібліотеки розглядаються як "системні", тобто версіонування їхнє зав'язане на версію системи, на якій воно іде. Відмінність від звичайних системних бібліотек та, шо цей набір може бути не інстальований. Але якшо він інстальований - це системні бібліотеки. Тобто каші з купою несумісних версій не має бути за визначенням. Каша з версіями дозволена на рівні приватних бібліотек і системних "несистемних" бібліотек. :D Де система допомагатиме розв'язувати її за допомогою інсталяційного менеджера і маніфестів чи інших механізмів, які ще належить визначити. Але це не будуть XML-файли. Занадто великий оверхед від них. Для опису залежностей для файла чи пакета, треба вибрати простішу мову (.inf файли може?) і, до того ж, буде трансляція цього опису в якийсь бінарний формат, який і вбудовуватиметься в виконувані образи чи інсталяційні пакети, які слугуватимуть ефективним проводарем для лодаря чи інсталятора, - шо саме за компоненти цей файл чи пакет очікує мати як свої залежності.
Про "корову", тобто про копіювання на писанні. Якшо воно дійсно має вигоди, воно буде. Але логічно - кожна бібліотека має ридонли і неридонлі дані. Перші завсіди розділені між усіма, другі завсіди приватні. Бібліотеки з самого початку мають бути потоко-безпечними. Ніяких відхилень не може бути в принципі.

Далі про дві інші категорії - процеси-підтримки і ядерна частина.
Процеси підтримки скоріше за все будуть "нативними" процесами і запускатимуться сесійним менеджером (smss.exe). На старті системи. Це точно для ПС, які завсіди запускаються на старті (Avril). Для старту на вимогу, існуватиме подія "перемикач", яка зумовлюватиме процес старту ПС, який знову починатиметься з запуску процесів підтримки і ядерної частини, які підготовуватимуть інфраструктуру ПС, а потім лодарь продовжуватиме вантажити процес, який спричинив старт цієї ПС. Тобто "перемикачем" старту ПС сконфігурованих запусктися на вимогу є запуск будь-якого процесу який покладається на цю ПС. Але очікується, шо ПС які збираються бути активно використовуваними будуть налаштовані запускатися на старті системи. І навіть без цього - активне використання ПС фактично означатиме ранній запуск. Шо мається на увазі? Ну от уявіть ПС PussyX не налаштована запускатися на старті системи, але користувач її насправді активно використовує. Між іншим він налаштував якісь служби запускатися на початку сесії, і служби ці написані як залежні від цієї підсистеми. Без якихсь додаткових налаштувань, нативний процес services.exe, коли почне запускати служби на старті сесії, наштовхнувшись на службу, яка залежить від згаданої ПС, спричинить сесійний менеджер запустити її. Тож, система не потребує якогось спеціального налаштавуання для запуску ПС, механізму залежностей виконуваних файлів досить, але, як правильна поведінка, було б добре прописати ПС, яка використовується на авто-старт.
Ядерна частина ПС запускається тут же - сесійним менеджером, або через читання налаштування (авто-старт), або на запит від лодаря. Лодарь, розбираючи виконуваний файл на запуск, подивиться підсистему, від якої цей файл залежить, і, якшо ПС не інстальована, викине помилку, і термінує (обірве) новий процес. а якшо ця підсистема інстальована але не запущена, запитає сесійний менеджер її запустити, і чекатиме поки той запустить її; потім продовжить запуск модуля. Як він балакатиме з сесійним менеджером? Ну IPC! Міжпроцесна комунікація.
Тож, ви можете спричинити старт ПС починаючи від драйвера і процесів підтримки, з усіма завантаженнями - регістрових "роїв" для ПС між іншим і до завантаження (фізичного) бібліотек, навіть простим Хелловорлдом, скомпільованим як posix процес. :)

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

  • 0

#76 _Ex

    STATUS_OK

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

Відправлено 29.03.2017 – 00:13

І ще про один аспект ПС. Всі вони, окрім Avril, можуть бути інстальованими або деінстальованими. З т.з. процесу інсталяції, ПС - це звичайний пакет інсталяції, - набір різних файлів, які описаним чином треба записати на інсталяційну "ціль" - постійне сховище, призначене бути місцем знаходження функціональности, яку цей пакет надає. З т.з. системи, інсталяція ПС це шось більше, ніж інсталяція програмного пакету. І шось менше, за інсталяцію самої ОС. :) Інтерактивна чи скриптована версії цього процесу в багатьому нагадуватимуть відповідну інсталяцію ОС.
ПС потребуватиме два типу місця на цільовому сховищі. Одне для самої ПС як такої, а інше - простір для програм і користувацьких даних, прив'язаних по цієї ПС. Адже ПС - це і програмне середовище для програм, і системна сутність, яка надає своїм користувачам ресурси - дисковий простір і власне сам компутер, вона ж забезпечує характерний для себе інтерфейс з користувачами, наприклад оперує поняттями користувачів, сесій тощо. Все це потребує постійного сховища між іншим.
Перша частина інсталяції (класова). Це частина ОС і компоненти йтимуть у відповідні системні місця - драйвер ітиме в папку для драйверів, його inf файли - в папку для inf файлів. І так далі. Реєстрові налаштування підуть у відповідні місця - для сесійного менеджера, logon системи, служб. Це сама ПС, її двигун - клас, це набір програм, які забезпечують ПС але самі нею не є (не споживають але надають цей функціонал).
Другий тип (зразковий, клієнтський), його вміст і структура залежить вже від "філософії" ПС і він визначає її, ПС, інстанціацію - тобто це чиясь посиксна інсталяція з усім, шо то має на увазі, як на рівні тамошніх програм так і користувачів. Мінімум, який необхідний від системи для цієї частини - це окрема директорія - яка слугуватиме коренем для всього, шо ця ПС зберігатиме для своїх клієнтів - програм і користувачів. Але, хорошим тоном би було дати трохи більше, не робити каші. Того, для нормального, повноцінного встановлення ПС, краще буде виділити принаймні 1 окрему партицію. Зручно всім - і системі, і ПС, і користувачам. В випадку PussyX, така партиція була б "коренем" посиксної ф/с ієрархії (rootfs в їхній термінології, вони файловими системами називають і типи фс, і їхні конкретні зразки. ми так не робимо і останні називаємо ф/с деревами (піддеревами, гілками), чи ієрархіями, тоді як перше - це саме фс: "файлова система NTFS" для нас - це саме файлова система типу NTFS - клас, а конкртений зразок, який сидить на якомусь томі, і має цей тип, це дерево, чи ф/с ієрархія (яке/яка має тип NTFS)).
Як уже було сказано, Avril ПС представляє сховища як набір "дисків" - майже все як в Віндовс. Майже, бо існують певні відмінності в іменуванні коренів, - у нас не лише букви дисків можуть використовуватися, якшо хтось хоче - може використовувати свій "лейбл" також, наприклад MyLabel:\Some\Path\somefile.ext
або, навіть, у випадку GPT-партиціонованих дисків, де на кожному диску (і фізично всьому і на його окремих партиціях) існують унікальні GUID-імена, може використовувати їх, знову якшо треба. Одним з приколів цієї схеми є наприклад можливість знайти той самий фізичний диск - гуйди партицій на ньому мають бути глобально унікальними (ева). Наприклад:
{b16b00b5-cafe-babe-d00dfeed12345678}:\Some\Path\somefile.ext
Це екзотика, і скоріше за все, всі використовуватимуть звичайні букви. Це так звані добре-відомі імена. Тут теж є відмінність від DOS/Windows стилю. Оскільки у нас нема легасі, пов'язаної з флопі-дисками, ми використовуватимемо букви A і B як і решту. Але, диск A: - завсіди зарезервовано для UEFI системної партиції (у випадку, якшо система має більше, ніж 1 системну партицію, то - для тієї, з якої відбулось запуск OS Loader'а, який нас завантажив). І вона переважно буде доступна лише на читання. Диск B: ми хотіли зарезервувати для бутової партиції - тобто для партиції, де лежить інсталяція ОС. І гарно виходить - B: - boot partition (volume). Але тут цей смаколик зіштовхнувся з іншою традицією, яку теж цікаво підтримувати - називати інсталяційну партицію, бутову, диском C: Поки як такого цілісного коду системи не існує, це ще не вирішено. Але якшо диск B: не буде зайнятий під бутовий том системи, він буде доступний користувачу для звичайного користування (на Віндовс теж так можна, але будьте готові до цікавинок як довжелезні затримки в юзерському інтерфейсі при перших зверненнях до тому, іноді, - якийсь код всеодно явно чекає на флопі диск, той повільний).
Також, в цій схемі, якшо користувач під'єднає наприклад 8 ТБ-ний диск і вирішить зробити там коло сотні томів, то, наша схема при закінченні алфавіту, іменуватиме томи аналогічно до ексцельових клітинок (ну це я так думаю, шо аналогічно - нубас в ексцелі детектед, зустрічайте :lol: ) Тобто, після диску Z: ітиме AA:, AB:, AC:, ... , ZX:, ZY:, ZZ:, ...AAA:, ... , Z..n..Z: - де n - максимальна довжина лейбла мінус 2. Максимальна довжина лейбла - 15 символів. Має вистачити! :D
Тобто перший диск
A:
останній
ZZZZZZZZZZZZZZZ:
Цей ліміт легко розширюється подовженням максимуму двожини лейбла.
Якшо подивитись, то схема тут одна (ну дві, якшо з "прямими" гуйдовими):
label ':'
'{' 8-DigitHex '-' 4-DigitHex '-' 4-DigitHex '-' 16-DigitHex '}' ':'

де label:
label == (1-15)Char
Char == [A-Za-z0-9] | '_'

Лескичний порядок: _, 0-9, A-Z (регістр-нечутлива система)
Тож насправді перший диск це
_:

Просто букви - це добре-відомі лейбли, і вони найзручніші. І система використовує їх за замовчуванням, дотримуючись лише тих двох правил (A - системна партиція, B або C - бутова). Але поважає користувацькі преференції. Аліаси теж можна створювати. Але це не звільнить зарезервованих літерних позначень або літерних позначень які уже виділені.
PussyX навпаки, все садове на один корінь. І він безіменний. Так от, оцей корінь - це та друга частина сховища, яку інсталяція ПС займає. Назвімо його клієнтська частина інсталяції. Туди будуть покладені як користувацькі дані, так і посиксні програми, і все, шо вони очікують. Навідміну від самої ПС (з бібліотеками), які власне не є posix-програмами чи модулями (вони суть системними модулями, або програмним пакетом під AvAPI, залежно від імплементації), всі програмні інсталяції на цю ПС очікуються саме сюди - на клієнтську ділянку. Тож якшо треба /bin/bash, він там і буде. Це більше для зручности всіх. Погоджуєтеся, шо окрема партиція чи набір партицій для ПС-ної інсталяції - це зручніше, ніж пхати це все в якусь папку на диску C?
З точки зору дефолтної ПС, і її користувачів, вони цю нову ПС можуть побачити як шось, шо нікого не чіпає і нікому не заважає. В випадку рознесености інсталяції. Подивившись через підсистмений TUI - тесктовий інтерфейс (графіка - це дуже складно :() це буде наприклад том D:, і вони бачитимуть шось таке: D:\bin\bash.exe чи D:\home\kalamar\ZeJehypetskichBohiv.txt. :lol: А посиксні користувачі бачитимуть /bin/bash.exe і /home/kalamar/ZaJehypetskichBohiv.txt
За винятком кількох директорій в клієнтській ділянці, які слугуватимуть інтерфейсом між ПС і ОС, наприклад - профілі користувачів, місця де зберігатимуться реєстрові рої, специфічні лише для цієї ПС, а також непосиксні дані гібридних програм (концепція не забороняє програмі покладатися на більше ніж 1 ПС), вся ця ділянка цілком і повністю в керуванні посиксом і його духом. Шо ознчає, шо і виглядати воно буде так же. Але нагадаємо, шо хоч ми й не можемо заборонити використовувати текстові файли для конфігурування, всі наші посиксні програми, використовуватимуть реєстр для цього.

Про користувачів. Це концепція рівня системи. Не ПС. Але ПС теж оперують цим поняттям. Отже треба мапування. Між системними і ПС користувачами.
На інсталяції, а ми про неї, ПС задаватиме специфічні для себе питання щодо користувачів, і відображатиме це на системне представлення. Avril ПС оперує користувачми як їх бачить ОС. Логічно - це рідна ПС. :) З інших, ми маємо лише посиксну. І в ній нема якоїсь великої різниці в концепції користувачів і груп від рідної, NT-поідбної. ПС інсталяція робитиме все, шо Posix вимагає. А далі, запитає про можливо потрібні відображення, якшо автоматично це відображення не дуже розв'язується. Зараз ми покишо бачимо лише одне таке і воно лише опціональне і нескладне (ми так зараз думаємо). Посикс має поняття рута. Це адміністратор для всього, шо ПС поставе в свою клієнтську ділянку. За замовчуванням, цей користувач не матиме адміністративних прав на рівні всієї системи. Але якшо користувач, який інсталює цю ПС, а це може бути лише адміністратор системи, хоче надати посиксному руту адміністративні права на всю систему, він може це зробити. Найочевидніший шлях - це відобразити вже наявного адміністратора на рута. Тоді остінній це просто псевдо, аліас адміністратора для посикса. бо останній очікує наявність такого користувача. Система безпеки Віндовс, а саме її ми намагатимемось відтворити, - дуже потужна. Вона дає змогу з легкістю відобразити усі уніксові атрибути безпеки на свої.


Про дублювання функціональности. Воно можливе за наявности більше, ніж однієї ПС. Але це не недолік дизайну, це природна властивість мання більше ніж одного програмного середовища. Вся мета концепції ПС - це використати уже створене наявне програмне середовище. Воно є складна система, і воно має свої закони. І воно ж дає функціонал. Отже якшо ми взяли дві ПС, ми принесли їхні закони і функціонал, який вони надають. З порядкуванням різницею законів возитиметься якраз імплементація підтримки багатьох ПС. А функціонал - це те, ради чого вони, ПС, сюди принесені. Його дублювання - очевидне тут. Адже програмні середовища - самодостатні сутності в плані надавання функціоналу.
І навіть так, ми маємо засоби для пом'якшення дублювання. По-перше, ми маємо привілейовану ПС, в тому сенсі, шо вона завсіди є і на неї завсіди можна покластися. Отже, інші ПС можуть використовувати її функціонал і не дублювати його. Служачи мостом до нього для своїх клієнтів. Це особливо валідно в плані служб, які забезпечують стандартні протоколи. Наприклад - FTP, NTP, криптографія. Але також на рівні інтерфейсів - аж до шлюзування в системні сервіси - бібліотека ПС може, якшо баче в цьому перевагу, - використовувати уже наявні засоби - Native API і Avril API.
Це дає змогу всім опціональним ПС розгрузити свою імплементацію і не дублювати вже наявне.
  • 0

#77 _Ex

    STATUS_OK

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

Відправлено 29.03.2017 – 20:55

Освіжімо трохи поточний стан речей в стартовому коді для йоду.
Ми скасували Pei.
На цій стадії (розробницькій) уся ФВ хоститься на SD картці (NAND не чіпаємо).
Sec фаза - це неформатований бінарник, написаний цілком на асемблері, який
  • дуже базово ініціалізує процесор (дрібниця (порівняно з світовою революцією), але - не зроблено)
  • виставляє стек в TSCM, яким не користується :lol:
  • читає ревізію плати (потрібно для ініціалізації SDRAM, на першій - Hynix, на другій Samsung, стандарти!)
  • робе LED синім
  • налаштовує UART4
  • пише туди вітання
  • пише ревізію
  • налаштовує і запускає PLL (APLL і MPLL)
  • виставляє ділителі для CPU, L2, AHB0, AHB2, PCLK
  • налаштовує і запускає OS таймер - без переривань, поки, просто лічильник
  • ініціалізує SDRAM (не зроблено)
  • тестує SRDAM (не зроблено)
  • налаштовує SD контроллер (не зроблено)
  • читає з картки сектор на позиції за SEC блобом (FV заголовок) (не зроблено)
  • находе файл Dxe.exe (ядро UEFI, Dxe фундація) (не зроблено)
  • читає решту секторів файла Dxe.exe в пам'ять (не зроблено)
  • завантажує Dxe.exe (як виконуваний модуль, згадайте обговорення цього раніше) (не зроблено)
  • будує HOB список (HOB - jack hand off block, список структур для Dxe, які описують карту пам'яті) (не зроблено)
  • стрибає в DxeEntryPoint() (не стрибає поки)
Dxe має реініціалізувати таймер, шоб він вже давав переривання, і ініціалізувати контроллер переривань1 для цього. І має зайнятися розгортанням UEFI сервісів, які частково написані, але там роботи й роботи. Також - треба завантажувати "платформні" Dxe драйвери, які обслуговуватимуть всю роботу з залізом. Тут же підключається ACPI - завантажити таблиці. І драйвери і таблиці - ще писати.
Плюс - Dxe.exe - це PE файл, вже не так просто перевести як у випадку з голим бінарником Sec.sys, треба писати утиліту. Також - утиліту, яка робе FV образ і кладе туди наші файли. Ми казали за це раніше. Просто в контексіт мурана, ну але так вийшло, шо йод виявився першим.

1 - як ви знаєте, NT використовує концепцію IRQL - Interrupt Request Level - рівень запиту переривання, це пріоритетизація переривань, яка маскує менш привілейовані переривання і переривання цього рівня, поки обробник возиться з обробкою переривання. Тобто пріоритетніші переривання можуть перервати переривання, а такі самі і менш пріоритетні за це - не можуть. От вам і скоромовка для тренування вимови, накшталт Клари з коралами.
UEFI теж має схожу концепцію, але для серіалізації "завдань" всередині своєї однопотокової сутности - TPL, Task Priority Level. Сучасні контроллери переривань підтримують цю пріоритетизацію переривань. Яким же було моє здивування, коли я побачив в процесорі IPL поле, яке 1 в 1 збігається з концепцією IRQL'ів! Міпс процесор підтримує це. А потім згадав, mips архітектура була де-факто першою, на яку написали NT, бо Інтелівський RISC N10 мав якісь серйозні затримки з наявністю, потім з роботою, отже вони, команда NT, переключились на mips. Ну і alpha, яка теж мала цю концепцію - вона зроблена по образу mips і теж була однією з перших цілей для NT. Тож у нас є потужний базис розгортання системи рівнів привілеїв в обробці переривань з підтримкою цього на рівні процесора. Mips архітектура прихильна до цієї системи. Між іншим чи знали ви, шо alpha процесор анонсувався і рекламувався як NT-ready? :)

Повідомлення відредагував _Ex: 29.03.2017 – 20:57

  • 0

#78 _Ex

    STATUS_OK

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

Відправлено 30.03.2017 – 16:11

трохи гемору. CI20, наша міпсівська плата, йод іде в кількох ревізіях. в трьох. перша була зелена, це була роздача для дивилопирів, перша ластівка. потім вона стала пурпурова (як пара йоду), саме таку мені подарували. а потім вийшла ще одна пакращена версія, теж пурпурова, але вже прямокутна, перші дві були непрямокутні. в цій останній додали ресет-кнопку, ще 4 LED'и, порозсовували певні компоненти, шоб вони з вайваєм і блютусом не займалися антагонізмом, шоб не інтерферіювали. :)
для розробки покишо сенс має така зміна - між зеленою і пурпуровою версіями змінилися модулі пам'яти, я вже казав за це, спочатку був Hynix, далі Samsung.
Є можливість взнати ревізію плати читаючи певні GPIO порти, неймлі - банк C, порти 18,19 дають або b_11 (3) або b_01 (1) - перше ревізія 1, друге - ревізія 2. Була надія за допомогою цього розрізнити між модулями. Саме так робе убут. І от, він геморой. Наша плата вертає 3, хоч і має гнусмасівські модулі! Хто б сумнівався. Звичайно, версій то власне три а не дві, і оте читання портів то перевірка чи є там pulldown резистор чи нема. до того, які модулі пам'яті на платі, це має дуууже опосередкований стосунок. просто була надія прив'язати це. але наша плата очевидно не має тих пулдавн резисторів як і зелена, але має гнусмаівські модулі як і прямокутна... а якже убут? та каша, насправді і не старається робити динамічну перевірку, у них там компіляційний макрос вибирає яка пам'ять, тобто убут зібраний на Хайникс ініціалізуватиме пам'ять як хайниксову, незалежно яка вона там насправді. Такшо їхня перевірка ревізії, це просто пшик. Я помітив цю дивну річ на старій вже стертій версії убута на моїй платі. Коли він грузився, він писав, шо пам'ять Хайникс. Але ж вона не Хайникс. Новіша версія просто нічого не пише. Просто убут має конфігурацію часу будування. І там треба визначити або оце CONFIG_SYS_DDR3_K4B2G0846Q або оце CONFIG_SYS_DDR3_H5TQ2G83CFR. Це налаштування часу компіляції, воно впаде під час неї, якшо ви не визначите один з цим макросів, це нема нічого спільного з динамічним конфігуруванням в часі виконання. В часі виконання, він бере ревізію, і якшо вона == 2 (сире значення є 1), ініціалізує структуру з параметрами налаштування пам'яти, взяту з гнусмасівської версії, в будь якому іншому братиме конфігурацію для хайниксу.
тобто, в результаті, гнусмасівська пам'ять робе на хайниксівських налаштуваннях, бачите - конфігурування вдалося! все виставлене навпаки до задуманого, але воно робе. або я не правильно прочитав GPIO. Це малойворіно, там все чітко і ясно.

А ми хотіли зробити динамічну конфігурацію, шоб наш код бігав на всіх версіях, і на зеленій теж. Ну, бачите, убут конфігурує пам'ять Б як пам'ять А і воно робе. Як то кажуть - nailed it! :D
Тепер просто братимемо спочатку налаштування для самсунга (ми то бачим, шо чипи самсунгівські), а потім хайниксові налаштування. і якшо робитимуть обидва, залишимо і ті і ті дані. більшість плат має бути з самсугнівською пам'яттю. остання надія на OTP, може там можна розрізнити якось. От же ж.

Повідомлення відредагував _Ex: 30.03.2017 – 16:14

  • 0

#79 _Ex

    STATUS_OK

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

Відправлено 30.03.2017 – 19:29

Я коли не прийду сюди, завсіди є ще якийсь "гість". гість, захади, не саромся, пиши шо небудь, бачиш, я й так тут один дрюкаю по клаві, цілком виправдовуючи назву теми. :D
  • 0

#80 _Ex

    STATUS_OK

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

Відправлено 30.03.2017 – 22:00

Спробуємо задокументувати цю гнітючу фігню під назвою SDRAM ініціалізація. У позаминулому дописі ми згадували параметри залежні від конктретного вендора модулів пам'яти. які, сплутались і роблять. ось структура яка заливається конкретними значеннями які різні для різних модулів:
typedef struct _JZ_DDR_CONF{
	UINT32	Timing1;
	UINT32	Timing2;
	UINT32	Timing3;
	UINT32	Timing4;
	UINT32	Timing5;
	UINT32	Timing6;

	/* PHY control */
	UINT32	Mr0;
	UINT32	Mr1;

	UINT32	PhyTr0;		/* PHY timing registers */
	UINT32	PhyTr1;
	UINT32	PhyTr2;

	UINT32	Dtpr0;		/* DRAM Timing Parameter registers */
	UINT32	Dtpr1;
	UINT32	Dtpr2;

	UINT32	PullUpImp;	/* PHY pullup and pulldown impedance */
	UINT32	PullDownImp;
}JZ_DDR_CONF, *PJZ_DDR_CONF;
PHY не задокументований взагалі. :(
Шо різниться?
В регістрі TIMING2:
S:	TIMING2.tRAS == 15
H:	TIMING2.tRAS == 16
tRAS це - "ACTIVE to PRECHARGE command period to the same bank". Значення в полях це в штуках tCK.

В регістрі TIMING3:
S:	TIMING3.tRC == 21
H:	TIMING3.tRC == 22
tRC це "ACTIVE to ACTIVE command period to the same bank".

В регістрі TIMING4:
S:	TIMING4.tRFC == 31
H:	TIMING4.tRFC == 42

S:	TIMING4.tMINSR == 9
H:	TIMING4.tMINSR == 7

S:	TIMING4.tXP == 8
H:	TIMING4.tXP == 3
tRFC - "AUTO-REFRESH command period."
Цитата з манулу:

Цитата

tRFC defines the minimum delay after an AUTO-REFRESH command. During tRFC period, no command can be issued to DDR memory. Delay Time = 2 * (tRFC + 1).
Далі іде таблиця де значенням в цьому 6-бітному співставляються штуки tCK.
[000000]	1
[000001]	3
[000010]	5
[000011]	7
Далі іде отака загальна формула:
------ 2 * (tRFC + 1) - де tRFC це 6-бітне значення зліва
а далі - продовження краю значень, і, несподівано:
[111101]	125 tCK.
[111110]	127 tCK.
[111111]	129 tCK.
:facepalm:
По-перше якшо T = 2(tRFC + 1), то напр tRFC = 0 -> T = 2, а не 1, tRFC=1, T=4, а не 3, tRFC=2, T=6, а не 5,
тобто мабуть таки T = 2(tRFC + 1) - 1 = 2tRFC + 1
По-друге, 111111 це 63, по формулі 2tRFC + 2, T = 128, по другій формулі, за якою явно виведена верхня частина, T = 127. Не попали ні туди ні туди. :angry:
Гаразд, візьмімо формулу T=2tRFC + 1.
Як бачимо, тайминги відрізняються конкретно.
T = 63 tCK samsung
T = 85 tCK hynix
Шо каже інджениковий BSP код:

samsung
#define DDR_tRFC 160 /* AUTO-REFRESH command period. DDR3 - ns*/

hynix
#define DDR_tRFC 215 /* AUTO-REFRESH command period. DDR3 - ns*/
tCK вони отако в наносекунди переводять:

Цитата

* tCK – one DDR memory clock cycle, typical tCK value is 7.5 ns (133MHz clock).
Тобто:
160 / 7.5 = 21.333 = 21
215 / 7.5 = 28.667 = 29
Але шо це? tRFC як значення для модуля, чи як значення поля яке ще кодується тією чарівною формулою, яку вони наплутали. Тобто в тих термінах, це T чи tRFC? Мабуть це T. Тобто їм дали тайминги наносекундах, а це їхнє відображення на tCK=7.5 нс.
Отже оте поле буде:
tRFC = (T - 1) / 2.
tRFC = 10
tRFC = 14
А у нас там шо? 31 і 42. Мило.
А якшо tCK == 2.5 нс?
160/2.5 = 64, tRFC = 31.5
215/2.5 = 86, tRFC = 42.5
Упсі. Схоже убутівці рішили, шо треба брати частоту == 400 МГц.

Далі
tMINSR - "Minimum Self-Refresh / Deep-Power-Down time."
Те саме, шо і з симовлом вище. для самсунга це 80 нс, для хайникса 60. Формула тут - (i + 1)*8 + 1, де i - значення поля.
Ми вже знаємо шо у нас tCK=2.5 нс. Насправді, я виставив в 200МГц, це tCK=5нс. Але номінальна частота 400 МГц. Ясно, шо якшо ми виходимо з параметрів заданих в нс, і перераховуємо їх в штуки тактів, і довжина в нс цих тактів у нас занижена, то вийде шо в нс інтервали будуть розтягнуті вдвічі, це має бути нестрашно. тут інтуїтивно ясно, шо коротше не можна. ну і нарешті, в нормальній роботі частота буде 400 МГц.
Отже. Для 80 нс - 80/2.5 = 32, тепер код, t = 8i + 9, i = (t - 9)/8,
T=80, t=32, i=2.875
T=60, t=24, i=1.875
А у нас шо 9 і 7 відповідно. Отже це були не опеньки не наносекунди. вгадуймо шо ж це. може це кількість tCK?
Тоді:
t=80, i=8.875
t=60, i=6.375
Вже ближче.
А якшо припустити, шо індженик знову не осилив загальну формулу і вона отака t = (i + 1)*8, то i = (t - 8)/8
t=80, i=9
t=60, i=6.5
^_^

Далі tXP - "EXIT-POWER-DOWN to next valid command period."

Цитата

tXP defines the EXIT-POWER-DOWN to next valid command period to all banks.
Це трьохбітне поле, і убут налаштовує так - для самсунга - 8, для хайникса - 3. Так, друзі, якшо ви читаєте, і вам це справді цікаво, ви правильно думаєте, убут пише 8 в трьохбітне поле. Оскільки весь регістр 32-бітний, а записування якогось поля відбувається зсувами і OR-енням, то 8, в ці три біти запише 0, і, як, бонус, виставе в 1, сусідній біт зліва. Це помилка ясно. Нащастя для убута, той біт який він помилково виставляє, біт 12, він "зарезервований", і писання туди не матимуть ані сенсу ані наслдіків. мабуть. Нуль в цьому полі, означатиме 1 tCK, тут формула проста - значення поля == значенню символа, а якшо значення поля == 0, то символ == 1. Індженик визначає таку диво хвормулу для задавання цього поля:
для самсунга
#define DDR_tXP DDR_MAX(3, 6000) /* DDR3 only: Exit active power down to any valid command, ns*/

для хайникса
#define DDR_tXP 3
Оце диво DDR_MAX(3, 6000), мабуть має вибрати більше між 3-ма циклами або кількістю циклів яке вийде з 6000 пс, очевидно.
У нас є 7.5 нс, як думає індженик, і є 2.5 нс, як буде з 400 МГц тактом. Тобто це або max(3, 0.8) або max(3, 2.4). В обох випадках виходе 3. Але убут нащитав 8. По суті він виставляє мінімально можливий інтервал в 1 такт, замість трьох. Шо мабуть може призводити до помилок і уповільнення. Тобто тут має бути 3 в обох полях.

В регістрі TIMING6:
S:	TIMING6.tFAW == 12
H:	TIMING6.tFAW == 20
tFAW - "4-active command window."
Для самсунга Ingenic визначає 30, для хайникса - 50, tCK. І ніяких кодувань нема. А от в убута оця чортівня. Шо робить?

Далі іде ще більше різниці і ще менше інформації, бо це взагалі не задокументовані регістри DDR PHY контроллера.
/* PHY timing registers */
S:	PhyTr1 = 0x02230d40
H:	PhyTr1 = 0x02d30d40

/* DRAM Timing Parameter registers */
S:
Dtpr0 = 0x2a8f6690
Dtpr1 = 0x00400860

H:
Dtpr0 = 0x2c906690
Dtpr1 = 0x005608a0

/* PHY pullup and pulldown impedance */
S:
PullUpImp = 0x0b
PullDownImp = 0x0b

H:
PullUpImp = 0x0e
PullDownImp = 0x0e
І нічого не можна сказати, шо це за різниця і чого вона така.
Це підсумок різниці. Тепер ще треба перевірити і однакові поля, бо як ми бачимо убут робе помилки. Треба звірити убутові параметри з інджениковими. Вони скопійовані прямо в убутовому коді, тобто останній брав свої значення звідтіля, але ж бачите, помилки є. А от звідкіля він брав оті значення для PHY ніде не написано.
  • 0



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

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


Магазин кубиков Рубика Cubes.in.ua