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 ú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 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-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 * 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áficosApós conectar um novo modo, a qualidade da imagem é bastante aprimorada.
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ê-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 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á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
Bloco de notas na calculadora
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.