因此,您想在计算器上运行Windows 10吗? 好吧


Windows 10 IoT下的HP Prime G2

在HP Prime G2出现之前,人们只能梦想在标准计算器上启动Windows。 具有如此强大硬件的计算器从未进入市场。 更重要的是,惠普选择了ARMv7-A处理器! 本文讨论如何在设备上安装UEFI和ACPI。


HP Prime G2上的SoC规范。 SoC NXP i.MX 6ULL​​(Ultra Lite)具有单核Cortex A7处理器

以前的工作


我的朋友张文勤(Zephray)完成了GPIO和计算器规范的反向工程的基础工作 。 此外,他设法将正常工作的U-BootLinux 移植到计算器上。

根据TI-Planet的说法,计算器提供了大量的测试引脚,包括SD / MMC,JTAG和UART。

Sarah(winocm)研究了在Qemu平台上运行Windows RT的可能性。 到2019年,情况有所变化,但本文并没有失去其价值。

微软已经签署了一项恩智浦协议,为iMX SoC芯片上的Windows 10 IoT提供支持。 因此,从技术上讲,Windows 10 IoT应该可以在此计算器上运行(以及Windows on ARM)。

完善Windows系统要求


Microsoft Docs网站上列出了运行Windows 10系列操作系统的系统要求。 即使是最起码的要求也不仅仅是Linux:系统需要一个x86 / x64 / ARMv7 / AArch64处理器,至少256 MB的内存和2 GB的磁盘空间。 需要功能性UEFI固件,完整的ACPI和SMBIOS表。

在我们的情况下,设备上没有足够的空间(Windows也不支持Raw SLC NAND),但是您可以通过USB将启动设备连接到计算器。

Sarah列出了运行Windows的ARMv7的体系结构要求。 多年来,这些要求已经有所变化,现在是这样:

 系统处理器:具有VFPv3 + VFP HalfPrec的ARMv7-A兼容处理器,也适用VFPv4
内存:至少256 MB RAM(可能更少)
外围设备:
     -系统计时器(按体系结构或按供应商)
     -BCM2835 / 2836/2837上的ARM通用中断控制器(GIC)或Broadcom中断控制器,CPU和分配器接口。 如果系统中存在并声明了GIC,则需要GICv2及更高版本。
     -帧缓冲
     -支持UART或NS16550,BCM283x或供应商提供的支持(对于Qualcomm和NXP)
     -固件:UEFI 2.3或更高版本 

我们的计算器符合这些严格的要求。 但是,默认SoC的运行速度为396 MHz,低于400 MHz / 1 GHz的基本水平。 还报告了250 MB的系统内存,而具有UI的系统的最低要求为512 MB。 但是它正在加载!


据WinDbg的cpuinfo称,SoC以396 MHz运行

我认为您可以进一步降低要求。 如果我没记错的话,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 

具有浮点数硬件支持的编译器将引导加载程序的速度从大约30秒提高到4秒。 在ARMv7平台上,Windows声称支持VFPv3 +。

屏幕初始化以及一些I / O多路分配是在U-Boot中完成的。 现在,U-Boot不支持24 / 32bpp串行RGB LCD接口,因此我通过在Linux内核中实现iMX帧缓冲添加了串行RGB支持。 该代码尚不在向导中,但我稍后将其传递给该向导。



LCD似乎可以工作。 整个过程:

  1. 运行uboot。
  2. 查找屏幕背光的引脚。
  3. 查找用于SPI和LCD初始化序列的引脚。
  4. 找到I2C引脚,并通过I2C配置PMIC以获取正确的电压。


U-Boot中的串行RGB LCD接口演示

UEFI只需获取U-Boot分配的帧缓冲区并注册图形输出协议。 不幸的是,屏幕分辨率不能满足80 * 25控制台的最低要求,因此我通过添加新的40 * 12模式更改了控制台DXE组件。


EDK2组件声称屏幕分辨率不满足80 * 25控制台的最低要求。

在破解控制台的组件之前,我做了一些技巧,将640 * 480的分辨率固定为UEFI GOP协议。 该技巧还有助于从Windows引导管理器获取诊断信息,因为320 * 240的分辨率不足以显示错误代码。 我定期运行从帧缓冲区到文件系统的块传输(BLT),并将BMP文件保存到USB驱动器。


Hack提供了80 * 25模式并带有一些图形工件

连接新模式后,图像质量会大大提高。


40 * 12模式


40 * 12模式

这是分辨率为320 * 240的Windows启动管理器消息的外观:



第一次尝试在UEFI引导服务阶段失败。 由于屏幕较小,错误代码不可见。


来自帧缓冲区的块传输(BLT)使您可以将消息保存到图像文件并读取

关于USB支持。 幸运的是,iMX6中的USB完全兼容,并且在Windows的最新版本中都包括支持。 因此,一旦我在主机模式下配置了OTG控制器并将MMIO区域转移到UEFI和Windows,它就会神奇地工作而不会出现问题。 但是我们没有在OTG端口上找到VBus(我们假设存在某种由SoC或PMIC控制的DC-DC电路,但这只是未经验证的假设),因此,为了正确操作,该端口需要通过一些外部电源供电。

BIOS


请确保您正确告知SMBIOS中的内存大小和地址区域,否则Windows将开始执行令人难以置信的奇怪事情(tm)。


Windows调试器由于错误的SMBIOS配置而无法读取内存

计时器和HAL扩展


我们似乎能够处理内存配置(LPAE),但可能还会有其他问题。 哦是的



因此,到目前为止,加载Windows仅达到此阶段。


如果找不到合适的系统计时器,则Windows将引用一些假定的无效内存地址

如果找不到中断控制器或系统计时器,则Windows无法启动。 可以使用GTDT表(ARM体系结构表)或通过CSRT表的HAL扩展来注册系统时间。

iMX6ULL带有三个计时器:iMX GPT(通用计时器),EPIT(增强型定期计时器)和ARM体系结构计时器。 后者仅出现在iMX6UL / ULL中,而先前的iMX6 SoC系统可在诸如Cortex A15之类的较早内核上工作,而无需架构计时器的支持。 Microsoft为系统计时器实现了EPIT HAL扩展,但是由于CSRT表中的硬件标识符与系统映像之间不匹配,所以一开始它没有加载(我为iMX6 Solo下载了较早的FFU)。 因此,当计时器不可用时,Windows将拼命尝试初始化预期的计时器,并且由于无效的内存访问,系统将崩溃。

iMX6ULL文档提到了体系结构计时器,但没有有关初始化过程的详细信息。 可以使用EDK2初始化计时器计数器,但是GIC PPI(每处理器中断)将无法正常工作。 但是,Windows成功初始化并通过GTDT表使用计时器。

UEFI当前使用EPIT计时器,并在传输到Windows时将其禁用。 依次,Windows初始化GPT计时器。 稍后,UEFI也可以使用适当的初始化过程切换到GPT。

某些外围设备需要Smart DMA(SDMA)控制器的HAL扩展;下载起来并不难。

告诉我它是如何工作的!


  [安全性]第三方映像[0]可以在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。
 安装协议接口:5B1B31A1-9562-11D2-8E3F-00A0C969723B 8F257028
  ConvertPages:找不到范围10000000-100EEFFF
 在0x0008E9D6000 EntryPoint处加载驱动程序= 0x0008E9E7511 bootmgfw.efi
 安装协议接口:BC62157E-3E33-4FEC-9920-2D3B36D750DF 8F28EB10
  ProtectUefiImageCommon-0x8F257028
  0x000000008E9D6000-0x00000000000EF000
 安装协议接口:752F3136-4E16-4FDC-A22A-E5F46812F4CA 8FBFF88C
  ConvertPages:找不到范围102000-102FFF
 在ExitBootServicesEventSetUefiImageMemoryAttributes上禁用EPIT计时器-0x000000008F78A000-0x0000000000003000(0x0000000000000008)
  SetUefiImageMemoryAttributes-0x000000008F787000-0x0000000000003000(0x0000000000000008)
  SetUefiImageMemoryAttributes-0x000000008F784000-0x0000000000003000(0x0000000000000008)
  SetUefiImageMemoryAttributes-0x000000008F77F000-0x0000000000005000(0x0000000000000008)
  SetUefiImageMemoryAttributes-0x000000008F77C000-0x0000000000003000(0x0000000000000008)
  SetUefiImageMemoryAttributes-0x000000008F779000-0x0000000000003000(0x0000000000000008) 

如果您想知道它加载的速度有多慢,那么大约三分半钟。

视频以2倍加速速度播放:


安全启动和TPM在哪里?


这实际上是可选的。 但是由于OP-TEE支持iMX6 / 7/8,因此您可以在TrustZone(TZ)中运行安全监视器,并通过来自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仅在更高版本下将不启动。 由于256 MB的内存不足,Windows PE将无法以虚拟磁盘模式启动。 在列出设备(包括USB驱动器)后,它进入某种循环而没有进一步初始化,因此我无法启动平面启动模式。


装有HP Prime G2的Windows,启动了计算器应用程序


计算器上的记事本


计算器上的记事本试图发送文本进行打印。

但是我也想启动Linux!


有两种选择:

  • 只需使用U-Boot启动zImage,设备树和initrd。
  • 将FD,MpPark和FrameBuffer存储区移至系统内存的顶部,在较低的存储区中留出128 MB的可用空间。

通过GRUB或直接从EFISTUB下载Linux。 一切都正常加载,这是日志的一部分:

  EFI存根:退出启动服务并安装虚拟地址映射...
 在ExitBootServicesEventSetUefiImageMemoryAttributes上禁用EPIT计时器-0x000000008F97B000-0x0000000000003000(0x0000000000000008)
  SetUefiImageMemoryAttributes-0x000000008F978000-0x0000000000003000(0x0000000000000008)
  SetUefiImageMemoryAttributes-0x000000008F973000-0x0000000000005000(0x0000000000000008)
  SetUefiImageMemoryAttributes-0x000000008F970000-0x0000000000003000(0x0000000000000008)
  SetUefiImageMemoryAttributes-0x000000008F96D000-0x0000000000003000(0x0000000000000008)
  SetUefiImageMemoryAttributes-0x000000008F96A000-0x0000000000003000(0x0000000000000008)
 在物理CPU 0x0上引导Linux
  Linux版本4.14.98-g371433a62906-dirty(imbushuo @ bc-macbookpro)(gcc版本7.4.1 20181213 [linaro-7.4-2019.02修订版56ec6f6b99cc167ff0c2f8e1a2eed33b1edc85d4](Linaro GCC 7.4-2019.02):#2 PREEM美国东部时间2019年29日
  CPU:ARMv7处理器[410fc075]版本5(ARMv7),cr = 10c53c7d
  CPU:可用的div指令:修补分区代码
  CPU:PIPT / VIPT非混叠数据高速缓存,VIPT混叠指令高速缓存
  OF:fdt:机器型号:HP Prime G2计算器
 内存策略:数据缓存写回
  efi:从FDT获取EFI参数:
  efi:EDK II的EFI v2.70
  efi:ACPI 2.0 = 0x8f49b000 SMBIOS = 0x8f9a8000 SMBIOS 3.0 = 0x8f9a6000
  OF:保留的内存:无法为节点'linux,cma'分配内存
  CPU:所有CPU在SVC模式下启动。
 建立了1个区域列表,并进行了移动分组。 总页数:64516
 内核命令行:zImage.efi root = / dev / ram0 rw initrd = / rootfs.cpio.gz dtb = / imx6ull-14x14-prime.dtb 

如果使用NXP Linux配置,这将使内核崩溃,因为它会从设备树或某些预定义的配置参数中读取initrd内存地址,并且,当然initrd会加载到UEFI中的其他位置。 有必要删除这些参数并使配置更加通用。

但是为什么呢?


人们谈论在不同设备上运行Windows,因此我想在年底之前对它们进行拖曳。

那其他项目呢? 接下来是什么?


这项工作将继续。 您还需要实现一些驱动程序,使用内置NAND实现UEFI引导,为计算器实现UEFI引导用户友好界面,并研究从我的UEFI加载HP PPL股票操作系统的可能性。

Source: https://habr.com/ru/post/zh-CN477250/


All Articles