 HP Prime G2 no Windows 10 IoT
HP Prime G2 no Windows 10 IoTSó se podia sonhar em iniciar o Windows em uma calculadora padrão antes do advento do HP Prime G2. Uma calculadora em um hardware tão poderoso nunca entrou no mercado. E mais importante, a HP escolheu o processador ARMv7-A! Este artigo descreve como instalar o UEFI e o ACPI em um dispositivo.
 Especificações de SoC no HP Prime G2. O SoC NXP i.MX 6ULL (Ultra Lite) possui um processador Cortex A7 de núcleo único
Especificações de SoC no HP Prime G2. O SoC NXP i.MX 6ULL (Ultra Lite) possui um processador Cortex A7 de núcleo únicoTrabalho anterior
Meu amigo 
Wenqin Zhang (Zephray) fez o 
trabalho fundamental de engenharia reversa das especificações do GPIO e da calculadora. Além disso, ele 
conseguiu portar U-Boot e 
Linux para a calculadora.
De acordo com o 
TI-Planet , a calculadora fornece um grande número de pinos de teste, incluindo SD / MMC, JTAG e UART.
Sarah (winocm) estudou a possibilidade de executar o Windows RT na plataforma 
Qemu . Em 2019, algo mudou, mas o artigo não perdeu seu valor.
A Microsoft firmou um contrato NXP para fornecer suporte ao Windows 10 IoT em chips iMX SoC. Portanto, tecnicamente, o Windows 10 IoT deve funcionar nesta calculadora (assim como o Windows no ARM).
Refinar os requisitos de sistema do Windows
Os requisitos do sistema para executar a família de sistemas operacionais Windows 10 
estão listados no site do Microsoft Docs . Até os requisitos mais mínimos são mais que o Linux: o sistema precisa de um processador x86 / x64 / ARMv7 / AArch64, pelo menos 256 MB de memória e 2 GB de espaço em disco. Firmware UEFI funcional, tabelas ACPI e SMBIOS completas são necessárias.
No nosso caso, não há espaço suficiente no dispositivo (e o Windows também não suporta Raw SLC NAND), mas você pode conectar o dispositivo de inicialização via USB à calculadora.
Sarah lista os requisitos de arquitetura do ARMv7 para executar o Windows. Ao longo dos anos, os requisitos mudaram um pouco, eis a aparência deles no momento:
  Processador do sistema: o processador compatível com ARMv7-A com VFPv3 + VFP HalfPrec, VFPv4 também é adequado
 Memória: pelo menos 256 MB de RAM (provavelmente menos)
 Periféricos:
     - Temporizador do sistema (por arquitetura ou por fornecedor)
     - ARM Generic Interrupt Controller (GIC) ou Broadcom Interrupt Controller no BCM2835 / 2836/2837, CPU e interface do distribuidor.  Se o GIC estiver presente e declarado no sistema, o GICv2 e superior serão necessários.
     - framebuffer
     - Suporte para UART ou NS16550, BCM283x ou do fornecedor (no caso da Qualcomm e NXP)
     - Firmware: UEFI 2.3 ou superior Nossa calculadora atende a esses requisitos rigorosos. No entanto, o SoC padrão é executado em 396 MHz, que é menor que o nível base de 400 MHz / 1 GHz. Também são relatados 250 MB de memória do sistema, enquanto o requisito mínimo para um sistema com uma interface do usuário é de 512 MB. Mas está carregando!
 De acordo com o cpuinfo do WinDbg, o SoC roda a 396 MHz
De acordo com o cpuinfo do WinDbg, o SoC roda a 396 MHzEu acho que você pode reduzir ainda mais os requisitos. Se bem me lembro, o Windows Server Nano possui cerca de 150 MB de memória para inicializar nos sistemas amd64.
UEFI e ACPI
Eu escrevi várias vezes sobre 
implementações UEFI , então não há nada de novo aqui. Basicamente, o UEFI consiste em um conjunto de drivers de dispositivo e 
componentes do kernel 
TianoCore . As tabelas ACPI são copiadas do repositório do 
Windows IoT iMX Project Mu e aparadas.
UEFI inicializa a partir do 
U-Boot . O iMX, por padrão, não permite acesso à memória desalinhada, e isso causa muitos problemas nos estágios UEFI DXE e BDS, portanto, você deve habilitá-lo o mais rápido possível.
  mrc p15, 0, r0, c1, c0, 0
  bic r0, r0, # 2
  mcr p15, 0, r0, c1, c0, 0 
Um compilador com suporte de hardware para flutuação acelera o carregador de inicialização de cerca de 30 a 4 segundos. Nas plataformas ARMv7, o Windows reivindica suporte para VFPv3 +.
A inicialização da tela, bem como algumas atribuições de E / S mux, são feitas no U-Boot. Agora, o U-Boot não suporta a interface LCD RGB serial de 24 / 32bpp, portanto, adicionei o suporte ao RGB serial através da implementação do buffer de quadros iMX no kernel do Linux. O código ainda não está no assistente, mas passarei lá mais tarde.

LCD parece funcionar. Todo o procedimento:
- Execute o uboot.
 
- Encontre um alfinete para a luz de fundo da tela.
 
- Encontre o pino para a sequência de inicialização SPI e LCD.
 
- Encontre o pino I2C e configure o PMIC via I2C para a voltagem correta.
 Demonstração da interface LCD RGB serial no U-Boot
Demonstração da interface LCD RGB serial no U-BootO UEFI simplesmente pega o buffer de quadros alocado pelo U-Boot e registra o Graphics Output Protocol. Infelizmente, a resolução da tela não atende aos requisitos mínimos do console 80 * 25; portanto, alterei os componentes do Console DXE adicionando um novo modo 40 * 12.
 O componente EDK2 afirma que a resolução da tela não atende aos requisitos mínimos do console 80 * 25
O componente EDK2 afirma que a resolução da tela não atende aos requisitos mínimos do console 80 * 25Antes de invadir os componentes do console, fiz um pequeno truque, corrigindo a resolução de 640 * 480 no protocolo UEFI GOP. O truque também ajudou a obter informações de diagnóstico do Gerenciador de Inicialização do Windows, porque a resolução 320 * 240 não é suficiente para exibir o código de erro. Executo periodicamente a transferência de bloco (BLT) do buffer de estrutura para o sistema de arquivos e salvo os arquivos BMP em uma unidade USB.
 Hack disponibiliza o modo 80 * 25 com alguns artefatos gráficos
Hack disponibiliza o modo 80 * 25 com alguns artefatos gráficosApós conectar um novo modo, a qualidade da imagem é bastante aprimorada.
 Modo 40 * 12
Modo 40 * 12 Modo 40 * 12
Modo 40 * 12Veja como é a mensagem do Windows Boot Manager com uma resolução de 320 * 240:

A primeira tentativa falha no estágio de serviços de inicialização UEFI. O código de erro não é visível devido à tela pequena.
 A transferência de bloco (BLT) do framebuffer permite salvar a mensagem em um arquivo de imagem e lê-la
A transferência de bloco (BLT) do framebuffer permite salvar a mensagem em um arquivo de imagem e lê-laEm relação ao suporte USB. Felizmente, o USB no iMX6 é totalmente compatível e o suporte está incluído nas versões recentes do Windows. Portanto, assim que configurei o controlador OTG no modo host e transferi a área MMIO para UEFI e Windows, ele funcionou magicamente sem problemas. Mas não encontramos VBus na porta OTG (assumimos que existe algum tipo de circuito DC-DC controlado por SoC ou PMIC, mas essa é apenas uma hipótese não verificada); portanto, para a operação correta, a porta deve ser alimentada por alguma fonte externa.
SMBIOS
Certifique-se de informar corretamente o tamanho da memória e as áreas de endereço no SMBIOS, ou o Windows começará a fazer coisas incrivelmente estranhas (tm).
 O depurador do Windows não pode ler a memória devido à configuração incorreta do SMBIOS
O depurador do Windows não pode ler a memória devido à configuração incorreta do SMBIOSTemporizador e extensões HAL
Parece que somos capazes de lidar com a configuração de memória (LPAE), mas provavelmente haverá algum outro problema. Ah sim ...

Portanto, carregar o Windows até agora só chega a esse estágio.
 Se um timer do sistema adequado não for encontrado, o Windows se refere a algum endereço de memória suposto e inválido
Se um timer do sistema adequado não for encontrado, o Windows se refere a algum endereço de memória suposto e inválidoO Windows não inicializa se um controlador de interrupção ou um timer do sistema não for encontrado. A hora do sistema pode ser registrada usando a tabela GTDT (tabela de arquitetura ARM) ou extensões HAL por meio da tabela CSRT.
O iMX6ULL vem com três cronômetros: iMX GPT (Timer de finalidade genérica), EPIT (Timer periódico aprimorado) e Timer de arquitetura ARM. O último apareceu apenas no iMX6UL / ULL, enquanto os sistemas SoC anteriores do iMX6 funcionavam em kernels mais antigos, como o Cortex A15, sem o suporte de um cronômetro de arquitetura. A Microsoft implementou a extensão EPIT HAL para o timer do sistema, mas não foi carregada no início devido a uma incompatibilidade entre o identificador de hardware na tabela CSRT e a imagem do sistema (baixei o FFU anterior para o iMX6 Solo). Portanto, quando o cronômetro estiver indisponível, o Windows tentará desesperadamente inicializar o cronômetro pretendido e o sistema travará devido ao acesso inválido à memória.
A documentação do iMX6ULL menciona um cronômetro de arquitetura, mas sem detalhes sobre o procedimento de inicialização. O contador do timer pode ser inicializado com EDK2, mas o GIC PPI (por processador interrompido) não funcionará corretamente. No entanto, o Windows inicializa com êxito e usa um cronômetro na tabela GTDT.
O UEFI atualmente usa o cronômetro EPIT e o desativa ao transferir para o Windows. Por sua vez, o Windows inicializa o cronômetro GPT. Em algum momento posterior, a UEFI também pode mudar para GPT com o procedimento de inicialização adequado.
Alguns periféricos exigem a extensão HAL para o controlador Smart DMA (SDMA); não é muito difícil fazer o download.
Mostre-me como funciona!
  [Segurança] A imagem de terceiros [0] pode ser carregada após o EndOfDxe: 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: falha ao encontrar o intervalo 10000000 - 100EEFFF
  Carregando o driver em 0x0008E9D6000 EntryPoint = 0x0008E9E7511 bootmgfw.efi
  InstallProtocolInterface: BC62157E-3E33-4FEC-9920-2D3B36D750DF 8F28EB10
  ProtectUefiImageCommon - 0x8F257028
  0x000000008E9D6000 - 0x00000000000EF000
  InstallProtocolInterface: 752F3136-4E16-4FDC-A22A-E5F46812F4CA 8FBFF88C
  ConvertPages: falha ao encontrar o intervalo 102000 - 102FFF
  Desativando o timer do EPIT em ExitBootServicesEventSetUefiImageMemoryAttributes - 0x000000008F78A000 - 0x0000000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F787000 - 0x0000000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F784000 - 0x0000000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F77F000 - 0x0000000000005000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F77C000 - 0x0000000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F779000 - 0x0000000000003000 (0x0000000000000008) 
Se você se perguntar o quão lentamente ele carrega, cerca de três minutos e meio.
Vídeo com velocidade acelerada 2x:
Onde estão o Secure Boot e o TPM?
Isso é realmente opcional. Porém, como o OP-TEE suporta o iMX6 / 7/8, você pode executar o Secure Monitor no TrustZone (TZ) e implementar esses serviços por meio de chamadas (Secure Monitor Calls) do EL1 / PL1.
De fato, a implementação oficial do iMX Windows IoT vem com o OP-TEE, mas eu o ignorei para economizar memória.
E os motoristas?
O repositório do 
Windows 10 IoT BSP contém muitos drivers para o iMX6 / 7/8. O driver USB funciona imediatamente, como já mencionado. Para a calculadora, você também precisa de drivers e teclados de tela sensível ao toque.
Eles estão disponíveis na árvore do kernel do Linux, portanto, não deve ser muito difícil portá-los para o Windows.
Posso baixar o Windows RT 8.1?
Possivelmente . Atualização: o Windows RT 8.1 não inicializa, apenas versões posteriores. O Windows PE não inicializa no modo ramdisk porque 256 MB de memória não são suficientes. Não consegui iniciar o modo de inicialização simples, depois de listar os dispositivos (incluindo a unidade USB), ele entra em algum tipo de ciclo sem inicialização adicional.
 Windows Prime HP G2 carregado, que lançou um aplicativo de calculadora
Windows Prime HP G2 carregado, que lançou um aplicativo de calculadora Bloco de notas na calculadora
Bloco de notas na calculadora O bloco de notas na calculadora está tentando enviar texto para impressão.
O bloco de notas na calculadora está tentando enviar texto para impressão.Mas também quero inicializar o Linux!
Existem duas opções:
- Basta usar o U-Boot para inicializar o zImage, a árvore de dispositivos e o initrd.
 
- Mova as áreas de memória FD, MpPark e FrameBuffer para a parte superior da memória do sistema, deixando 128 MB livres na área de memória inferior.
Faça o download do Linux via GRUB ou diretamente do EFISTUB. Tudo está carregando normalmente, aqui está um fragmento do log:
  Stub EFI: Saindo dos serviços de inicialização e instalando o mapa de endereço virtual ...
  Desativando o timer do EPIT em ExitBootServicesEventSetUefiImageMemoryAttributes - 0x000000008F97B000 - 0x0000000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F978000 - 0x0000000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F973000 - 0x0000000000005000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F970000 - 0x0000000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F96D000 - 0x0000000000003000 (0x0000000000000008)
  SetUefiImageMemoryAttributes - 0x000000008F96A000 - 0x0000000000003000 (0x0000000000000008)
  Inicializando o Linux na CPU física 0x0
  Versão do Linux 4.14.98-g371433a62906-dirty (imbushuo @ bc-macbookpro) (versão gcc 7.4.1 20181213 [linaro-7.4-2019.02 revisão 56ec6f6b99cc167ff0c2f8e1a2eed33b1edc85d4] (Linaro GCC 7.4-2019.02): # 2 PREEM 29 EST 2019
  CPU: Processador ARMv7 [410fc075] revisão 5 (ARMv7), cr = 10c53c7d
  CPU: div instruções disponíveis: patching code code
  CPU: cache de dados sem serrilhado PIPT / VIPT, cache de instruções com aliasing VIPT
  OF: fdt: Modelo da máquina: Calculadora HP Prime G2
  Política de memória: write-back do cache de dados
  efi: Obtendo parâmetros EFI do FDT:
  efi: EFI v2.70 por EDK II
  efi: ACPI 2.0 = 0x8f49b000 SMBIOS = 0x8f9a8000 SMBIOS 3.0 = 0x8f9a6000
  OF: mem reservado: falha ao alocar memória para o nó 'linux, cma'
  CPU: todas as CPUs iniciadas no modo SVC.
  Construiu 1 zonelists, agrupamento de mobilidade.  Total de páginas: 64516
  Linha de comando do kernel: zImage.efi root = / dev / ram0 rw initrd = / rootfs.cpio.gz dtb = / imx6ull-14x14-prime.dtb 
Se você usar a configuração do NXP Linux, isso causará um travamento no kernel, porque ele lê o endereço de memória initrd da árvore de dispositivos ou alguns parâmetros de configuração predefinidos e, é claro, o initrd é carregado em outro lugar na UEFI. É necessário remover esses parâmetros e tornar a configuração mais universal.
Mas porque?
As pessoas falam sobre a execução do Windows em dispositivos diferentes, então eu quero controlá-los antes do final do ano.
E outros projetos? O que vem a seguir?
O trabalho continuará. Você também precisa implementar alguns drivers, obter a inicialização UEFI com o NAND integrado, implementar a interface amigável de inicialização UEFI da calculadora e estudar a possibilidade de carregar o sistema operacional de estoque HP PPL da minha UEFI.