x86 上的 BIOS 重写

BIOS rewrite on x86

我的问题很简单,但我找不到答案。

如何写入BIOS内存芯片?

好吧,要将数据写入 x86 上的 IO 设备(或实际上任何其他设备),进程似乎总是通过端口映射或内存映射 IO 访问 IO 设备。对我来说,现代 BIOS 闪存芯片是 IO 设备,如果它是可写的,那么它必须经过那个过程。 Coreboot 是 PC BIOS 的开源替代品,但是,我相信它使用 flashrom 用其代码实际重写 BIOS 芯片,而 flashrom 是专有的,所以我想知道为什么写 BIOS 如此困难以至于我找不到关于如何实际操作的可靠答案。

x86 市场上有两种设备:有标准接口的和没有标准接口的。你的情况属于第二类。

要写入闪存 ROM,您只需将特定命令发送到特定地址。
假设你有这个 1KB 的 ROM 芯片,它响应从 000h 到 0fffh 的读取请求。然而,您可以发送写入请求,但芯片甚至不会考虑它们。您不能像读取 F-ROM 那样容易地写入 F-ROM。
您必须通过将 55h 写入地址 AAh 来发送写入命令,然后发送要刷新的页面,然后写入数据。这是一个专有接口(正在努力对其进行标准化),我对其进行了简化,省略了理论上不相关的部分。

所以你只需要将写命令发送到ROM芯片即可。
问题是ROM芯片不在CPU旁边,它超出了所谓的桥接器,通常是一个桥接器。
在 x86 架构中,芯片组是芯片的地狱,它是设备之间的集线器路由请求(最近已经分散,但像 ROM 之类的设备仍然只连接到曾经称为南桥的芯片)。 您,CPU 程序员,通过内存和 IO 地址 space 中的请求与芯片组通信。

默认情况下,芯片组不会让写入到达闪存 rom,您必须通过 setting/clearing 芯片组寄存器(内存映射或 PCI(e) 寄存器)中的某些位来启用它 space).这是专有接口。

如果你很幸运并且你的芯片组有足够的文档记录(就像英特尔的那样)让你知道如何允许写入到达 ROM,你必须弄清楚这个请求是如何路由的。
网桥并不总是透明的,它们执行地址转换,例如,您可以写入 8123h,而网桥可能会将地址更改为 0123h。
对于闪存 ROM 前面的桥(这是一个带有 SIO 芯片的 LPC 桥,现在是 SPI 桥)肯定会发生这种情况,因为 ROM 只是一个普通芯片,在 0h - xxxxxxxxxh 范围内响应,而来自CPU透视它映射在最顶端的4GB。所以你还必须弄清楚 ROM 的基地址是什么,这又是芯片组特定的,也是 ROM 特定的,因为它取决于 ROM 的大小(芯片组让你从固定数量的不同基地址中进行选择)。

刷新 BIOS 并不难,我这样做只是为了好玩,它非常不可移植,以至于每种计算机型号可能需要不同的程序来完成。它也需要你的芯片组数据表,这并不像你想象的那么普遍。

如果您想获得更实用的想法,可以在此处下载英特尔 X99 PCH 数据表 (http://www.intel.com/content/www/us/en/chipsets/x99-chipset-pch-datasheet.html) 并查看 SPI 章节。