Sie möchten Windows 10 auf einem Taschenrechner ausführen? okay


HP Prime G2 unter Windows 10 IoT

Man konnte nur träumen, Windows vor dem Aufkommen des HP Prime G2 auf einem Standardrechner zu starten. Ein Taschenrechner mit solch einer leistungsstarken Hardware ist noch nie auf den Markt gekommen. Und was noch wichtiger ist: HP hat sich für den ARMv7-A-Prozessor entschieden! Dieser Artikel beschreibt die Installation von UEFI und ACPI auf einem Gerät.


SoC-Spezifikationen für den HP Prime G2. SoC NXP i.MX 6ULL ​​(Ultra Lite) verfügt über einen Single-Core-Cortex-A7-Prozessor

Bisherige Arbeit


Mein Freund Wenqin Zhang (Zephray) erledigte die grundlegende Arbeit des Reverse Engineering der GPIO- und Rechnerspezifikationen. Außerdem gelang es ihm, funktionierendes U-Boot und Linux auf den Rechner zu portieren .

Laut TI-Planet bietet der Rechner eine große Anzahl von Teststiften, einschließlich SD / MMC, JTAG und UART.

Sarah (winocm) hat die Möglichkeit untersucht, Windows RT auf der Qemu- Plattform auszuführen . Bis 2019 hat sich etwas geändert, aber der Artikel hat nicht an Wert verloren.

Microsoft hat eine NXP-Vereinbarung zur Unterstützung von Windows 10 IoT auf iMX-SoC-Chips geschlossen. Aus technischen Gründen sollte Windows 10 IoT auf diesem Rechner funktionieren (ebenso wie Windows auf ARM).

Optimieren Sie die Windows-Systemanforderungen


Die Systemanforderungen für die Ausführung der Windows 10-Betriebssystemfamilie sind auf der Microsoft Docs-Website aufgeführt . Selbst die geringsten Anforderungen sind mehr als Linux: Das System benötigt einen x86 / x64 / ARMv7 / AArch64-Prozessor, mindestens 256 MB Arbeitsspeicher und 2 GB Festplattenspeicher. Funktionale UEFI-Firmware, vollständige ACPI- und SMBIOS-Tabellen sind erforderlich.

In unserem Fall ist nicht genügend Speicherplatz auf dem Gerät vorhanden (und Windows unterstützt auch kein Raw SLC NAND), aber Sie können das Startgerät über USB an den Taschenrechner anschließen.

Sarah listet die Architekturanforderungen für ARMv7 zum Ausführen von Windows auf. Im Laufe der Jahre haben sich die Anforderungen ein wenig geändert. So sehen sie derzeit aus:

  Systemprozessor: ARMv7-A-kompatibler Prozessor mit VFPv3 + VFP HalfPrec, VFPv4 ist ebenfalls geeignet
 Arbeitsspeicher: mindestens 256 MB RAM (wahrscheinlich weniger)
 Peripheriegeräte:
     - Systemtimer (entweder nach Architektur oder nach Hersteller)
     - GIC (ARM Generic Interrupt Controller) oder Broadcom Interrupt Controller auf BCM2835 / 2836/2837, CPU- und Distributor-Schnittstelle.  Wenn GIC im System vorhanden und deklariert ist, sind GICv2 und höher erforderlich.
     - Framebuffer
     - Unterstützung für UART oder NS16550, BCM283x oder vom Hersteller (im Fall von Qualcomm und NXP)
     - Firmware: UEFI 2.3 oder höher 

Unser Rechner erfüllt diese hohen Anforderungen. Der Standard-SoC arbeitet jedoch mit 396 MHz, was weniger als der Basispegel von 400 MHz / 1 GHz ist. Es werden auch 250 MB Systemspeicher gemeldet, während die Mindestanforderung für ein System mit einer Benutzeroberfläche 512 MB beträgt. Aber es wird geladen!


Laut cpuinfo von WinDbg läuft SoC mit 396 MHz

Ich denke, Sie können die Anforderungen weiter reduzieren. Wenn ich mich richtig erinnere, hat Windows Server Nano ungefähr 150 MB Speicher, um auf amd64-Systemen zu starten.

UEFI und ACPI


Ich habe mehrmals über UEFI-Implementierungen geschrieben , daher gibt es hier nichts Neues. Grundsätzlich besteht UEFI aus einer Reihe von Gerätetreibern und TianoCore-Kernelkomponenten . ACPI-Tabellen werden aus dem Windows IoT iMX Project Mu- Repository kopiert und zugeschnitten.

UEFI bootet vom U-Boot . iMX erlaubt standardmäßig keinen Zugriff auf nicht ausgerichteten Speicher. Dies verursacht viele Probleme in den UEFI DXE- und BDS-Phasen. Sie sollten ihn daher so bald wie möglich aktivieren.

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

Ein Compiler mit Hardware-Unterstützung für Float beschleunigt den Bootloader von ca. 30 auf 4 Sekunden. Windows behauptet, auf ARMv7-Plattformen VFPv3 + zu unterstützen.

Die Bildschirminitialisierung sowie einige I / O-Mux-Zuweisungen erfolgen in U-Boot. Jetzt unterstützt U-Boot die serielle RGB-LCD-Schnittstelle mit 24/32-Bit / s nicht. Deshalb habe ich die serielle RGB-Unterstützung durch die Implementierung des iMX-Framebuffers im Linux-Kernel hinzugefügt. Der Code ist noch nicht im Assistenten enthalten, aber ich werde ihn später dort weitergeben.



LCD scheint zu funktionieren. Die ganze Prozedur:

  1. Führen Sie uboot aus.
  2. Suchen Sie einen Stift für die Hintergrundbeleuchtung des Bildschirms.
  3. Finden Sie den Pin für die SPI- und LCD-Initialisierungssequenz.
  4. Suchen Sie den I2C-Pin und konfigurieren Sie den PMIC über I2C für die richtige Spannung.


Demonstration der seriellen RGB-LCD-Schnittstelle in U-Boot

UEFI verwendet einfach den von U-Boot zugewiesenen Framebuffer und registriert das Graphics Output Protocol. Leider entspricht die Bildschirmauflösung nicht den Mindestanforderungen der 80 * 25-Konsole. Daher habe ich die Console DXE-Komponenten durch Hinzufügen eines neuen 40 * 12-Modus geändert.


Die EDK2-Komponente behauptet, dass die Bildschirmauflösung nicht den Mindestanforderungen der 80 * 25-Konsole entspricht

Bevor ich die Komponenten der Konsole gehackt habe, habe ich einen kleinen Trick gemacht und die Auflösung von 640 * 480 im UEFI GOP-Protokoll korrigiert. Der Trick half auch dabei, Diagnoseinformationen vom Windows-Start-Manager abzurufen, da die Auflösung von 320 * 240 nicht ausreicht, um den Fehlercode anzuzeigen. Ich führe regelmäßig eine Blockübertragung (BLT) vom Framebuffer zum Dateisystem durch und speichere die BMP-Dateien auf einem USB-Laufwerk.


Hack stellt den 80 * 25-Modus mit einigen Grafikartefakten zur Verfügung

Nach dem Anschließen eines neuen Modus wird die Bildqualität erheblich verbessert.


40 * 12-Modus


40 * 12-Modus

So sieht die Windows-Start-Manager-Meldung bei einer Auflösung von 320 * 240 aus:



Der erste Versuch schlägt in der Phase der UEFI-Startdienste fehl. Der Fehlercode ist aufgrund des kleinen Bildschirms nicht sichtbar.


Mit der Blockübertragung (BLT) vom Framebuffer können Sie die Nachricht in einer Bilddatei speichern und lesen

In Bezug auf USB-Unterstützung. Glücklicherweise ist USB im iMX6 vollständig kompatibel und die Unterstützung ist in neueren Windows-Versionen enthalten. Sobald ich den OTG-Controller im Host-Modus konfiguriert und den MMIO-Bereich auf UEFI und Windows übertragen habe, funktioniert dies auf magische Weise ohne Probleme. Wir haben jedoch keinen VBus am OTG-Port gefunden (wir gehen davon aus, dass es eine Art DC-DC-Schaltkreis gibt, der von SoC oder PMIC gesteuert wird, dies ist jedoch nur eine nicht überprüfte Hypothese). Daher muss der Port für den korrekten Betrieb über eine externe Quelle mit Strom versorgt werden.

SMBIOS


Vergewissern Sie sich, dass Sie die Speichergröße und die Adressbereiche in SMBIOS korrekt angeben. Andernfalls führt Windows ungewöhnliche Aktionen aus (tm).


Windows-Debugger kann aufgrund falscher SMBIOS-Konfiguration keinen Speicher lesen

Timer und HAL Extensions


Wir scheinen in der Lage zu sein, mit der Speicherkonfiguration (LPAE) umzugehen, aber es wird wahrscheinlich ein anderes Problem geben. Oh ja…



Das bisherige Laden von Windows ist also erst in diesem Stadium.


Wenn kein geeigneter Systemzeitgeber gefunden wird, verweist Windows auf eine vermutete und ungültige Speicheradresse

Windows bootet nicht, wenn kein Interrupt-Controller oder System-Timer gefunden wird. Die Systemzeit kann mithilfe der GTDT-Tabelle (ARM-Architekturtabelle) oder der HAL-Erweiterungen über die CSRT-Tabelle registriert werden.

iMX6ULL wird mit drei Timern geliefert: iMX GPT (Generic Purpose Timer), EPIT (Enhanced Periodic Timer) und ARM Architectural Timer. Letzteres erschien nur in iMX6UL / ULL, während frühere iMX6-SoC-Systeme auf älteren Kernels wie dem Cortex A15 ohne die Unterstützung eines Architektur-Timers arbeiteten. Microsoft hat die EPIT HAL-Erweiterung für den System-Timer implementiert, sie wurde jedoch zunächst nicht geladen, da die Hardware-ID in der CSRT-Tabelle und das System-Image nicht übereinstimmen (ich habe die frühere FFU für iMX6 Solo heruntergeladen). Wenn der Zeitgeber nicht verfügbar ist, versucht Windows daher verzweifelt, den beabsichtigten Zeitgeber zu initialisieren, und das System stürzt aufgrund eines ungültigen Speicherzugriffs ab.

In der iMX6ULL-Dokumentation wird ein Architektur-Timer erwähnt, jedoch ohne Details zum Initialisierungsvorgang. Der Timerzähler kann mit EDK2 initialisiert werden, die GIC-PPI (Per Processor Interrupt) funktioniert jedoch nicht ordnungsgemäß. Windows wird jedoch erfolgreich initialisiert und verwendet einen Zeitgeber über die GTDT-Tabelle.

UEFI verwendet derzeit den EPIT-Timer und deaktiviert ihn bei der Übertragung auf Windows. Windows wiederum initialisiert den GPT-Timer. Zu einem späteren Zeitpunkt kann UEFI auch mit der richtigen Initialisierungsprozedur zu GPT wechseln.

Für einige Peripheriegeräte ist die HAL-Erweiterung für den Smart DMA (SDMA) -Controller erforderlich, deren Download nicht allzu schwierig ist.

Zeig mir wie es geht!


  [Sicherheit] Drittanbieter-Image [0] kann nach EndOfDxe geladen werden: VenHw (0D51905B-B77E-452A-A2C0-ECA0CC8D514A, 004118020000000000) / USB (0x0.0x0) / USB (0x2.0x0) / HD (1, GPT, F9ADAEA9-E8DE-4291-B191-5DABA6DC1215.0x800.0x100000) / \ efi \ boot \ bootarm.efi.
  InstallProtocolInterface: 5B1B31A1-9562-11D2-8E3F-00A0C969723B 8F257028
  ConvertPages: Der Bereich 10000000 - 100EEFFF konnte nicht gefunden werden
  Laden des Treibers bei 0x0008E9D6000 EntryPoint = 0x0008E9E7511 bootmgfw.efi
  InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 8F28EB10
  ProtectUefiImageCommon - 0x8F257028
  0x000000008E9D6000 - 0x00000000000EF000
  InstallProtocolInterface: 752F3136-4E16-4FDC-A22A-E5F46812F4CA 8FBFF88C
  ConvertPages: Bereich 102000 - 102FFF konnte nicht gefunden werden
  EPIT-Timer für ExitBootServicesEventSetUefiImageMemoryAttributes deaktivieren - 0x000000008F78A000 - 0x00000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F787000 - 0x00000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F784000 - 0x00000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F77F000 - 0x00000000005000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F77C000 - 0x00000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F779000 - 0x00000000003000 (0x0000000000000008) 

Wenn Sie sich fragen, wie langsam es lädt, dann ungefähr dreieinhalb Minuten.

Video mit beschleunigter Geschwindigkeit 2x:


Wo ist Secure Boot und TPM?


Dies ist eigentlich optional. Da OP-TEE jedoch iMX6 / 7/8 unterstützt, können Sie Secure Monitor in TrustZone (TZ) ausführen und diese Dienste über Anrufe (Secure Monitor Calls) von EL1 / PL1 aus implementieren.

Tatsächlich wird die offizielle Implementierung von iMX Windows IoT mit OP-TEE geliefert, aber ich habe es aus Gründen der Speichersparung ignoriert.

Was ist mit Fahrern?


Das Windows 10 IoT BSP- Repository enthält viele Treiber für iMX6 / 7/8. Der USB-Treiber funktioniert, wie bereits erwähnt, sofort. Für den Taschenrechner benötigen Sie außerdem Touchscreen-Treiber und Tastaturen.

Sie sind im Linux-Kernelbaum verfügbar, daher sollte es nicht zu schwierig sein, sie auf Windows zu portieren.

Kann ich Windows RT 8.1 herunterladen?


Möglicherweise . Update: Windows RT 8.1 startet nicht, nur spätere Versionen. Windows PE startet nicht im Ramdisk-Modus, da 256 MB Arbeitsspeicher nicht ausreichen. Ich konnte den Flat-Boot-Modus nicht starten, da er nach dem Auflisten der Geräte (einschließlich des USB-Laufwerks) ohne weitere Initialisierung in einen bestimmten Zyklus übergeht.


HP Prime G2 lud Windows, das eine Taschenrechneranwendung startete


Notizblock auf Taschenrechner


Notepad auf dem Taschenrechner versucht, Text zum Drucken zu senden.

Aber ich möchte auch Linux booten!


Es gibt zwei Möglichkeiten:

  • Verwenden Sie einfach U-Boot, um zImage, den Gerätebaum und initrd zu starten.
  • Verschieben Sie die Speicherbereiche FD, MpPark und FrameBuffer in den oberen Bereich des Systemspeichers, und lassen Sie im unteren Speicherbereich 128 MB frei.

Laden Sie Linux über GRUB oder direkt von EFISTUB herunter. Alles wird normal geladen, hier ist ein Fragment des Protokolls:

  EFI-Stub: Beenden der Startdienste und Installieren der virtuellen Adresszuordnung ...
  EPIT-Timer für ExitBootServicesEventSetUefiImageMemoryAttributes deaktivieren - 0x000000008F97B000 - 0x00000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F978000 - 0x00000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F973000 - 0x00000000005000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F970000 - 0x00000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F96D000 - 0x00000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F96A000 - 0x00000000003000 (0x0000000000000008)
  Booten von Linux auf physischer CPU 0x0
  Linux-Version 4.14.98-g371433a62906-dirty (imbushuo @ bc-macbookpro) (gcc-Version 7.4.1 20181213 [linaro-7.4-2019.02 Revision 56ec6f6b99cc167ff0c2f8e1a2eed33b1edc85d4] (Linaro GCC 7.4-2019.02): # 2 PREEM 29 EST 2019
  CPU: ARMv7-Prozessor [410fc075] Revision 5 (ARMv7), cr = 10c53c7d
  CPU: Div-Anweisungen verfügbar: Patchen des Divisionscodes
  CPU: PIPT / VIPT-Nonaliasing-Datencache, VIPT-Aliasing-Anweisungscache
  OF: fdt: Maschinenmodell: HP Prime G2-Rechner
  Speicherrichtlinie: Rückschreiben des Datencaches
  efi: EFI-Parameter von FDT abrufen:
  efi: EFI v2.70 von EDK II
  efi: ACPI 2.0 = 0x8f49b000 SMBIOS = 0x8f9a8000 SMBIOS 3.0 = 0x8f9a6000
  OF: reserviertes mem: konnte keinen Speicher für den Knoten 'linux, cma' reservieren
  CPU: Alle im SVC-Modus gestarteten CPUs.
  Errichtet 1 Zonenlisten, Mobilitätsgruppierung auf.  Gesamtseiten: 64516
  Kernel-Befehlszeile: zImage.efi root = / dev / ram0 rw initrd = / rootfs.cpio.gz dtb = / imx6ull-14x14-prime.dtb 

Wenn Sie die NXP Linux-Konfiguration verwenden, stürzt der Kernel ab, da er die initrd-Speicheradresse aus dem Gerätebaum oder einigen vordefinierten Konfigurationsparametern liest und initrd natürlich an einer anderen Stelle in UEFI geladen wird. Es ist notwendig, diese Parameter zu entfernen und die Konfiguration universeller zu gestalten.

Aber warum?


Die Leute reden davon, Windows auf verschiedenen Geräten laufen zu lassen, deshalb möchte ich sie noch vor Jahresende testen.

Was ist mit anderen Projekten? Was weiter?


Die Arbeit wird fortgesetzt. Sie müssen auch einige Treiber implementieren, das Laden von UEFI mit integriertem NAND durchführen, eine benutzerfreundliche Benutzeroberfläche zum Laden von UEFI für den Taschenrechner implementieren und die Möglichkeit des Ladens des HP PPL-Betriebssystems von meinem UEFI untersuchen.

Source: https://habr.com/ru/post/de477250/


All Articles