好奇宝宝在这个时代如何跟着 AI 学习
背景
最近在家里给 Broadwell 老机器(5代酷睿)+ 华硕 Z97 主板插上了一张 NVIDIA V100 32G 显卡。BIOS 给 PCIe RC 分配的 64-bit Prefetchable BAR 地址空间只有 15G,导致VRAM BAR 需要 32G 分配不出来,驱动直接报错。
跟着 AI 进行了一番折腾成功解决,但作为好奇宝宝,整件事情让我百思不得其解,随后我跟着 AI 一探究竟学到了好多。
技术细节
首先,是我自己发现了问题根源(在 /proc/iomem 可以看到 PCIe RC 分配的地址空间)。随后去了 RebarUEFI 的 README 发现了他们的 Patch 有如下描述:“Increase MMIO space from 8-16GB to full usage of 512GB/39-bit range (Haswell/Broadwell).” 这正是我需要的东西。
随后,README 里也给了一个不用刷 BIOS 的 DSDT Patch 的选项,我懂设备树但是完全不懂 ACPI ,更不懂 DSDT,我就让 AI 自己干,毕竟这个只是在启动的时候給内核做一个 Override ,并非刷 BIOS 这样的高风险操作,随后 AI 自己就解决了,我一重启,真的有了 256G 的 BAR 空间,32G 显存放得下了,GPU 也能正常工作了。
思考
可能很多人到这里,事情就结束了,毕竟我们已经达成了 /goal make gpu working。但作为好奇宝宝,我想看一下原理,毕竟我稍微懂点 SoC 搭建,也在 AMD FPGA 玩过 XDMA 配置过 PCIe,于是我看了下 AI 帮我 Patch 的东西,瞬间惊呆了:
之前的 DSDT 长这样:
If ((OSYS >= 0x07D9)) // "Is the OS Windows 2009 or newer?" (Linux claims yes)
{
If ((M64L == Zero))
{
... window length = 0 ... // above-4G decoding disabled in BIOS setup
}
Else
{
CreateQWordField (BUF0, \_SB.PCI0._Y1E._LEN, M2LN)
CreateQWordField (BUF0, \_SB.PCI0._Y1E._MIN, M2MN)
CreateQWordField (BUF0, \_SB.PCI0._Y1E._MAX, M2MX)
M2LN = M64L // length <- value set by BIOS
M2MN = M64B // base <- value set by BIOS
M2MX = ((M2MN + M2LN) - One)
}
Return (BUF0)
}
这里的 M64L 和 M64B 也就是 BIOS 给 64-bit Prefetchable BAR 分配的空间。
然后 AI 干的 Patch 非常简单:
M2MN = M64B // base: keep the BIOS value (0xC00000000)
M2LN = (0x0000004000000000 - M2MN) // length: everything from base up to 256 GiB
M2MX = ((M2MN + M2LN) - One)
直接把 Length 改成 256GB
我当时的内心只有:
这样居然能工作?
然后我跟着 AI 学习了一下为什么,最后发现,这居然是 Intel Client CPU 的 System Agent 地址路由的特性的 Hack。
我继续问了下 AI
AI 直接给我甩出来了一堆我不懂的词。但让我直接看到了一个关键:所有不在内存地址区域的请求,都会路由给 PCIe RC,而且几乎我见过的所有 Client CPU,也都只有一个 PCIe RC。
OK,这就解释了为什么这样是工作的,直接改变大小之后,那一段地址后面也恰好没有别的设备地址会冲突,System Agent 会直接路由给 RC。
那么,只要 DSDT 告诉内核,这段地址是给 PCIe BAR 的,内核也会对 BIOS 还没分配的 PCIe BAR 地址重新分配到这段空间,这就全都工作了!
很难想象,如果没有 AI,我要花多长时间才能得到这个 LLM 权重里直接就有的信息。
继续好奇,一定得 Patch DSDT 吗?
虽然工作了,但我觉得 DSDT Patch 是一件很脏的事情,现在的原理是 GRUB 把 DSDT 直接喂给内核,如果哪天硬件发生巨大的变动,或是 BIOS 升级,可能直接导致机器起不来,需要进行一些手动维护。
随后我继续问 AI
结果 AI 果然告诉了我一个内核的选项 pci=nocrs,这会让内核忽略 ACPI DSDT 提供的 current resource settings ,里面有地址空间信息,
我试了一下,取消 DSDT Patch,GPU继续成功工作!这方法比 Patch DSDT 干净多了!
继续好奇,这个新选项在多 RC 的机器可以工作吗?
AI 给了答案,而且看历史也很有意思
总结
虽然只是做一个简单的运维工作,但是在 AI 的帮助下,让我知道了好多东西!



