Искате ли да инсталирате Windows 10 на калкулатор? Хайде

Оригиналът е на Bingxing Wang

8
2397

За стартирането на Windows 10 на стандартен калкулатор можеше само да се мечтае до появата на HP Prime G2. Никога досега на пазара не е излизал калкулатор с толкова мощен хардуер. И което е по-важно, компанията HP е избрала в това устройство да се използва ARMv7-A процесор!

Нека да разгледаме как става инсталирането на UEFI и ACPI на подобно мобилно устройство.

Предишните проекти

Моят приятел Вансин Чжан (Zephray) свърши фундаменталната работа по реверсивното инженерство на GPIO и по вникване в подробностите и характерните особености на калкулатора. Освен това, той успя да портне за този калкулатор работещи U-Boot и Linux.

Според информацията на TI-Planet, в калкулатора има доста голям брой тестови пинове, включително SD/MMC, JTAG и UART.

Сара (winocm) изучи възможността за стартиране на Windows RT на Qemu платформата. През 2019 година настъпиха някои промени, но статията не е изгубила ценността си.

Знаем, че Microsoft е сключил договор с NXP за осигуряване поддръжката на Windows 10 IoT за iMX чиповете. Тоест, от техническа гледна точка Windows 10 IoT би трябвало да работи на този калкулатор, също както работи Windows 10 за ARM процесори.

Системните изисквания на Windows 10

Системните изисквания за стартирането на операционните системи от Windows фамилията са публикувани в сайта на Microsoft. Дори и най-минималните изисквания са по-високи от тези за инсталирането на Linux. Необходим е процесор x86/x64/ARMv7/AArch64, минимум 256 MB оперативна памет и 2 GB дисково пространство. Необходим е функционален UEFI фърмуер и запълнени ACPI и SMBIOS таблици.

В нашия случай калкулаторът няма толкова място, а и на всичкото отгоре Windows не поддържа Raw SLC NAND памет. Но към устройството може да бъде включен зареждащ USB стик.

Сара изрежда необходимите архитектурни особености на ARMv7 за стартирането на Windows 10. През изминалите години изискванията леко са променени и ето как изглеждат към днешен ден:

  • Процесор: ARMv7-A съвместим, с VFPv3+VFP HalfPrec, VFPv4
  • Памет: 256 MB, но може би ще може и с по-малко
  • Периферни устройства:
    • Системен таймер
    • ARM Generic Interrupt Controller (GIC) или Broadcom Interrupt Controller с BCM2835/2836/2837, както и Distributor Interface
    • Ако системата има и се декларира GIC, то това трябва да бъде GICv2 или по-нагоре
    • Буфер за кадрите
    • Поддръжка на UART или NS16550 и BCM283x, но може и от производителя – в нашия случай Qualcomm и NXP
    • Фърмуер: UEFI 2.3 и нагоре

Нашият калкулатор съответства на тези доста твърди изисквания. Само че използваната в него система върху чипа по подразбиране работи с тактова честота 396 MHz, а това е по-малко от базовото изискване за минимум 400 MHz или желателно поне 1 GHz. Калкулаторът има 250 MB оперативна памет, а минималното изискване за ОС с потребителски интерфейс е 512 MB. Но Windows 10 се зарежда!

Считам че може да се измисли нещо. Доколкото си спомням, на Windows Server Nano са му достатъчни около 150 MB, за да може да се зареди на amd64 системи.

UEFI и ACPI

Вече на няколко пъти писах за реализациите на UEFI и тук няма нищо ново. В основни линии UEFI се състои от комплект драйвери и компоненти на TianoCore ядрото. Таблиците ACPI могат да се изкопират от хранилището Windows IoT iMX Project Mu и да се намали техният обем.

UEFI се зарежда от U-Boot. iMX по подразбиране не позволява достъпа до неформатирана памет и това предизвиква много проблеми на етапите UEFI DXE и BDS, така че трябва да се включат колкото се може по-рано.

mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #2
mcr p15, 0, r0, c1, c0, 0

Компилаторът с хардуерна поддръжка на float ускорява зареждащата програма от 30 на 4 секунди. А за ARMv7 платформите Windows иска поддръжката на VFPv3+.

Инициализацията на екрана, както и задаването на някои стойности на I/O mux стават в U-Boot. Към днешен ден U-Boot не поддържа 24/32bpp Serial RGB LCD интерфейса и аз добавих поддръжката на Serial RGB чрез реализирането на кадровия буфер iMX в Linux ядрото. Този код още не е включен в стабилните версии на Linux Kernel, но съвсем скоро ще го предам за включване.

Ето че LCD започна да работи. Ето каква е цялата процедура:

  1. Стартиране на uboot
  2. Намиране на пина за подсветката на екрана
  3. Намиране на пина за SPI и последователността за инициализацията на LCD
  4. Намиране на пина за I2C и настройване на PMIC чрез I2C за подаване на правилното напрежение
Така работи Serial RGB LCD интерфейса в средата на U-Boot

UEFI просто взема буфера за кадри, заделен от U-Boot, и регистрира протокола за извеждане на графиката Graphics Output Protocol. За съжаление, резолюцията на екрана не удовлетворява минималните изисквания за конзола с 80х25 символа. Наложи се да променя Console DXE и да добавя нов текстов режим с резолюция 40х12 символа.

 

Преди по този начин да хакна този компонент на конзолата, регистрирах поддръжката на резолюция 640х480 в UEFI GOP. Този трик дава възможност за получаване на информация от boot мениджъра на Windows. Това е важно, понеже резолюцията 320х240 не е достатъчна за да се покаже кода на грешката.

Хакването дава режим 80х25, ни има допълнителни артефакти

След включването на новия режим качеството на изображението значително се повиши.

Режим 40х12
Отново режим 40х12 символа

А ето как изглежда едно от съобщенията на boot мениджъра на Windows при резолюция 320х240:

Първият опит се срива още на етапа на процеса на зареждането на UEFI. Но поради малкия екран не се вижда добре кодът на грешката.

По повод поддръжката на USB. За щастие, USB в iMX6 изцяло съответства на стандарта, като тази поддръжка е включена в последните версии на Windows. И ето, че след като зададох OTG да работи в режим на хост и подадох MMIO областта към UEFI и Windows, всичко тръгна без проблеми. Но ние не можахме да намерим VBus на OTG и за коректната работа на този порт се налага да се подава външно напрежение.

SMBIOS

Необходимо е да се убедим, че в SMBIOS правилно се съобщават размера на паметта и адресните области. В противен случай Windows започва да се държи твърде странно ™.

Таймерът и разширенията на HAL

Струва ми се, че много добре се справихме с конфигурацията на паметта (LPAE), но със сигурност ще се появи някой друг проблем. О да…

И така, зареждането на Windows стига само до следния етап:

Ако не бъде открит подходящ системен таймер, Windows се обръща към някакъв предполагаем таймер и към недопустим адрес на паметта

Windows няма да се зареди, ако не намери контролер на прекъсванията или системен таймер. Но системното време може да се регистрира с помощта на GTDT таблицата (таблица от ARM архитектурата) или чрез HAL разширение с помощта на CSRT таблица.

iMX6ULL има три таймера: iMX GPT (Generic Purpose Timer), EPIT (Enhanced Periodic Timer) и ARM Architectural Timer. Последният се появи чак в iMX6UL/ULL, докато предишните системи върху чипа iMX6 работеха със старите процесорни ядра като Cortex A15 без поддръжката на таймер към архитектурата на процесора. Специално за системния таймер Microsoft реализира разширението EPIT HAL, но в началото то не пожела да се зарежда поради несъответствието на идентификатора за хардуерното оборудване с CSRT таблицата. Ето защо, когато таймерът е недостъпен, Windows отчаяно се опитва да инициализира предполагаемия таймер и системата крашва поради осъществяването на недопустим достъп до паметта.

В документацията на iMX6ULL се споменава за архитектурен таймер, но без подробности как се инициализира. Броячът на таймера може да се инициализира с помощта на EDK2 код, но GIC PPI (Per Processor Interrupt) не иска да работи коректно. Но за наше учудване, Windows успешно инициализира и използва този таймер, като всичко прави чрез GTDT таблицата.

Виждаме, че в един момент UEFI използва EPIT и го изключва при започване работата на Windows. От своя страна Windows инициализира GPT таймера. В един по-късен момент UEFI също започва да използва GPT таймера, като това става със съответна процедура за инициализация.

Да добавя, че някои периферни устройства изискват HAL разширение за Smart DMA (SDMA) контролера, но това не е трудно да се направи.

Да погледнем как работи всичко това

[Security] 3rd party image[0] can be loaded after EndOfDxe: VenHw(0D51905B-B77E-452A-A2C0-ECA0CC8D514A,004118020000000000)/USB(0x0,0x0)/USB(0x2,0x0)/HD(1,GPT,F9ADAEA9-E8DE-4291-B191-5DABA6DC1215,0x800,0x100000)/efibootbootarm.efi.
InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 8F257028
ConvertPages: failed to find range 10000000 - 100EEFFF
Loading driver at 0x0008E9D6000 EntryPoint=0x0008E9E7511 bootmgfw.efi
InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 8F28EB10
ProtectUefiImageCommon - 0x8F257028
0x000000008E9D6000 - 0x00000000000EF000
InstallProtocolInterface: 752F3136-4E16-4FDC-A22A-E5F46812F4CA 8FBFF88C
ConvertPages: failed to find range 102000 - 102FFF
Disabling EPIT timer on ExitBootServicesEventSetUefiImageMemoryAttributes - 0x000000008F78A000 - 0x0000000000003000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000008F787000 - 0x0000000000003000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000008F784000 - 0x0000000000003000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000008F77F000 - 0x0000000000005000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000008F77C000 - 0x0000000000003000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000008F779000 - 0x0000000000003000 (0x0000000000000008)

Ако ви е интересно колко бавно става зареждането, то това става за около три и половина минути.

Ето го и видеото, в което скоростта е увеличена два пъти.

А къде са Secure Boot и TPM?

Всъщност, те не са задължителни. Но тъй като OP-TEE поддържа iMX6/7/8, то е възможно да се стартира Secure Monitor в TrustZone (TZ) и тези процеси да се реализират чрез Secure Monitor Calls извикванията от EL1/PL1.

Всъщност, официалната реализация на iMX Windows IoT се предоставя с OP-TEE, но аз я игнорирах за икономия на памет.

Какво да кажем за драйверите?

В хранилището Windows 10 IoT BSP са записани немалък брой драйвери за iMX6/7/8. Драйверът за USB веднага започва да работи. Само че за калкулатора са необходими и драйвери за сензорния екран и за клавиатурата.

Тези драйвери ги има в хранилищата на Linux ядрото и не е трудно да бъдат портнати към Windows.

Може ли да се зареди Windows RT 8.1?

Може би. Обновено: Windows RT 8.1 не се зарежда, а само по-късните версии. Windows PE не успява да се зареди в режим ramdisk, понеже 256 MB оперативна памет са недостатъчни. Така и не успях да реализирам flat boot режима, включително и за USB стика – започва безкраен цикъл без инициализацията да продължи. Но ето няколко интересни примера от по-късните версии на тази ОС:

 

Но аз иска да заредя и Linux на този калкулатор!

Има два варианта:

  • Използване на U-Boot за зареждането на zImage, дървовидния списък на устройствата и initrd
  • Да се премести областта на паметта с FD, MpPark и FrameBuffer в горната част на системната памет и по този начин да се оставят свободни 128 MB в долната част на паметта

Така може да се зареди Linux чрез GRUB или непосредствено от EFISTUB. Ако всичко се зарежда както трябва, ето как трябва да изглежда фрагмент на лог журнала:

EFI stub: Exiting boot services and installing virtual address map…
Disabling EPIT timer on ExitBootServicesEventSetUefiImageMemoryAttributes - 0x000000008F97B000 - 0x0000000000003000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000008F978000 - 0x0000000000003000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000008F973000 - 0x0000000000005000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000008F970000 - 0x0000000000003000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000008F96D000 - 0x0000000000003000 (0x0000000000000008)
SetUefiImageMemoryAttributes - 0x000000008F96A000 - 0x0000000000003000 (0x0000000000000008)
Booting Linux on physical CPU 0x0
Linux version 4.14.98-g371433a62906-dirty ([email protected]) (gcc version 7.4.1 20181213 [linaro-7.4-2019.02 revision 56ec6f6b99cc167ff0c2f8e1a2eed33b1edc85d4] (Linaro GCC 7.4-2019.02)) #2 PREEMPT Thu Nov 14 03:10:29 EST 2019
CPU: ARMv7 Processor [410fc075] revision 5 (ARMv7), cr=10c53c7d
CPU: div instructions available: patching division code
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
OF: fdt: Machine model: HP Prime G2 Calculator
Memory policy: Data cache writeback
efi: Getting EFI parameters from FDT:
efi: EFI v2.70 by EDK II
efi: ACPI 2.0=0x8f49b000 SMBIOS=0x8f9a8000 SMBIOS 3.0=0x8f9a6000
OF: reserved mem: failed to allocate memory for node 'linux,cma'
CPU: All CPU(s) started in SVC mode.
Built 1 zonelists, mobility grouping on. Total pages: 64516
Kernel command line: zImage.efi root=/dev/ram0 rw initrd=/rootfs.cpio.gz dtb=/imx6ull-14x14-prime.dtb

Ако използвате NXP Linux конфигурация, то това ще срине Linux ядрото, понеже се чете initrd адрес на паметта от дървовидния списък с устройствата и от някои твърдо зададени параметри на конфигурацията. И разбира се, initrd се зарежда още на ранен етап – някъде в UEFI. Трябва да се махнат тези параметри и конфигурацията да стане по-универсална.

Защо е нужно всичко това?

Хората твърде много приказват и се хвалят, че са стартирали Windows на най-различни устройства. А аз по този начин мога да ги тролвам поне до края на годината.

Какви са следващите проекти?

Работата продължава. Необходимо е да се реализират още някои драйвери, за да се осъществи зареждането на UEFI от вградената в калкулатора NAND памет. Може да се реализира удобен потребителски интерфейс за калкулатора за зареждането на UEFI и да се изучат възможностите на зареждането на ОС HP PPL от моя UEFI.

Благодарности

Този проект е частично взет от Windows 10 IoT BSP на Microsoft за SoC NXP платформи. Искам да благодаря и на приятеля си, че ми изпрати своя Prime G2 с вече запоени UART линии, подходящи за дебъгване.

8
ДОБАВИ КОМЕНТАР

avatar
5 Коментари
3 Отговори на коментарите
0 Последователи
 
Коментарът с най-много реакции
Най-горещият коментар
  Абонирай се  
нови стари оценка
Извести ме за
Тралала
Тралала

Браво! Полезна и интересна статия – поне за мен.
Хубав ден.

пипи
пипи

Да бе да ми забива и калкулатора, ей сега!

disable windows update
disable windows update

И за къв чеп ми е виндовс на калкулатор или калкулатор с виндовс?

ллл
ллл

За да си пуснеш calc.exe от Windows. Друго си е 🙂

Dave
Dave

ллл, а най смешното е че calc.exe на уиндоус 10 зарежда 5 пъти по банто от същото на 7…

УжасТ!
УжасТ!

Заглавието на новината трябва да е: „Вирус 10 вече заразява и калкулатори“ :)))

U4en
U4en

„За стартирането на Windows 10 на стандартен калкулатор можеше само да се мечтае“ ………. ако си психично болен.

Мартин
Мартин

Това показва,че 10-ката е доста по олекотена от предходните версии на уиндоус.