起因是我突然想起,家里还有一台坏了屏幕的笔记本,性能一般,但拿来做软路由的话就很强了,安装并配置完成后,发现笔记本的BIOS里面居然没有来电自启,不过有个wake on lan in S5,可惜开启后测试并没有什么卵用,这玩意儿关机后直接把网卡的电都给断了;

无奈之下只好去动BIOS了,笔记本是炫龙A41L-541HN3,先去找炫龙官网下载BIOS,然后震惊的发现官网没了,回头一看,淘宝官方店也没了,竟是在不知不觉间倒闭了!?

想起炫龙是神舟的子品牌,又去神舟官网看看,然后理所当然的搜不到机型,再一看,和神舟的K610D-i5D3是同一个模具,那我去下载它的BIOS应该也是通用的,结果神舟新官网没有资料,去旧官网确实是搜到了,但只有驱动,没有BIOS,再一查,原来BIOS在独立的网页:神舟官方BIOS地址,结果,它也打不开了!!!网上也没搜到有说地址更新的, 捏麻麻的,要倒闭的节奏。

蓝天模具BIOS获取方法

然后想起神舟很多笔记本都是直接用的蓝天的BIOS,找了一下发现蓝天的BIOS没有直接放出来,而是通过ftp方式共享的,但BIOS的具体地址还需要猜......好在有大佬做了镜像站,虽然不是最新的,但好歹有个参考,提示要登录的话,密码和账户名都是repo,然后使用intel XTU工具可以读出具体的蓝天模具型号,根据模具型号在镜像站找到对应的EC和BIOS镜像文件编号,然后进去关键部分!!!这里很重要!!!

进入 ftp://ftp.clevo.com.tw/ALLBIOS/你的模具编号/要找的文件编号 

这个网页是蓝天官方存储最新的BIOS和EC的库,按照对应格式输入后,用相关的下载工具会弹出下载提示,如下示例。在镜像网站看到的最新BIOS是B10709.zip文件名,输的时候可以加一个数,变成B10710.zip,可以看到下载工具能爬到这个文件,然后再往后加,发现下载工具爬到这个文件没有大小,说明这个文件不存在,从而爬到最新的BIOS和EC版本。

作者:哔哩瞬 https://www.bilibili.com/read/cv3984863/ 出处:bilibili

尝试这个方法的时候发现XTU工具不支持我的笔记本,我也不知道具体的模具型号,直接NG
后面才发现用的不是蓝天模具,而是广达TWS模具,但他们没有放出BIOS......

修改并刷写本机BIOS

在上面的方法走不通后,只好把目光放回本地,使用intel的Flash Programming Tool来提取本机BIOS,但此工具并不是向下兼容的,需要根据自己的ME版本确定使用哪个版本的Flash Programming Tool,而Flash Programming Tool包含在Intel CSME System Tools中

版本错误则会在error.log内提示如下内容:

Error 39: PCH is not supported.

Error 620: Unknown hardware platform.

Error 9988: Internal Error. Unexpected error occurred.

FPT Operation Failed.

那么如何选择Intel CSME System Tools的版本(两种方法):
第一步:
1.进BIOS,BIOS里有个叫ME FW Version的东西,这个就是你的CSME的版本
BIOS
2.搜索引擎搜索“英特尔® Converged Security and Management Engine Version Detection Tool”,进入英特尔官网下载并运行,其中“英特尔管理引擎信息”中的版本就是CSME的版本
英特尔® Converged Security and Management Engine Version Detection Tool
第二步:
打开https://comsystem-tlt.ru/obzori/me-txe-region
根据你的CSME的版本选择你的tools的版本,例如我的CSME的版本是9.0.22.1467 那么我下载Intel ME System Tools v9.0 r1.rar就可以了

提取BIOS

创建一个backup.bat文件,写入如下内容后,保存并以管理员权限运行:

cd /d %~dp0
fptw64.exe -bios -d backup.fd

运行后应该会在当前目录生成一个backup.fd文件,这就是我们的备份BIOS

测试刷入BIOS

将前面获取的backup.fd文件复制一份,改名为setup.fd,再创建一个BIOS Flashing.bat文件,写入如下内容后,保存并以管理员权限运行:

cd /d %~dp0
fptw64.exe -bios -f setup.fd

如果窗口一闪而过,说明出错了,检查生成的error.log内容,我在这一步遇到报错如下:

Error 280: Failed to disable write protection for the BIOS space!

这说明BIOS开启了写入保护,通常台式机主板可以通过改变物理跳线短接位置解锁,或者进入BIOS,关闭BIOSWriteProtect或者BIOS Lock即可,可惜我这台是笔记本,不能短接跳线,BIOS里面也没有BIOSWriteProtect,后面通过其它方法找到了BIOS Lock,但它被放在隐藏的BIOS选项里,要关闭就得刷BIOS解锁隐藏选项,要刷BIOS就得先关闭写入保护,MD绝了

不过当时我没有测试刷写,所以就接着改下去了

检查BIOS文件,确认隐藏选项

使用EUVTOOL工具,打开H2OEZE-W-GUIx64.exe,选择File>Load image>setup.fd,再点击Setup,此时工具会展示此BIOS的模拟选项,应该和我们实际使用的BIOS页面选项相同,这时在窗口右下方有一个Suppress/Grayout的选项,默认是Auto,将其选为None,就可以无视隐藏菜单的判断语句,直接看到完整的BIOS选项了(就是在这里找到了来电自启-After G3 OnBIOS Lock),不过这里也只是临时看到,无法直接以这个状态保存到实际的BIOS中

部分笔记本屏蔽的比较简单的,可以在这个时候点击File>Export,就可以选择一个地址并设置输出文件名,得到一个txt文档,打开后可以看到此BIOS的所有选项和默认的值,可以通过修改*号的位置实现变更默认选项,这个时候直接Ctrl+F搜索Full Show来找到隐藏高级选项的总开关,修改默认选项从hideshow,保存txt后导入回去,再保存BIOS文件,管理员权限执行BIOS Flashing.bat,刷入BIOS,重启后进入BIOS应该就是解锁后到全菜单BIOS了,偶尔会有一些笔记本还需要按F9执行BIOS恢复默认才可以看见全菜单BIOS

导出模块

导出模块有两个方法
方法一:
使用LongSoft/UEFITool: UEFI firmware image viewer and editor
打开 UEFITools,首先点击左上角的 File>Open image File,打开setup.fd,我们首先要寻找After G3 On的位置,直接按 Ctrl+F 搜索,选择 “Text” 类型,搜索 “G3” (不含引号),可以看到Messages下有很多结果,这时随意选择一个双击,Structure下会显示它的具体位置,找到它的父集,应该是一个FE开头的GUID,选中它,右键Extract body…导出到你想要的地址并命名,我这里命名为01.fbd

方法二:
InsydeH2O使用H2OEZE-Win32.exe打开setup.fd,选择File>Load BIOS image from…>setup.fd,接下来导出模块:Components>Module>Export module,在Select module to export下选择要导出的模块,模块就是前面通过UEFITool确认的那个,在Export module to…下选择要输出的地址并设置好文件名,这里设置为01.ffs,最后点击Apply,弹出Successful表示成功

反编译模块

使用donovan6000/Universal-IFR-Extractor: Utility that can extract the internal forms represenation from both EFI and UEFI modules.
打开 Universal IFR Extractor.exe进行反编译,打开后在Module Location选择刚刚导出的01.ffs01.fbd模块,Protocol显示UEFI则正常,点击Extract,默认在原目录生成一个01 IFR.txt的文件,点击保存即可

使用16进制编辑器修改模块,实现解锁

打开01 IFR.txt,搜索原版BIOS中可以直接看到的任意一个菜单,比如Wake on Lan in S5,可以找到如下内容:

0x86A96         Grayout If: {19 82}
0x86A98             Variable 0x1D equals 0x2 {12 86 1D 00 02 00}
0x86A9E                 Variable 0x1C equals 0x1 {12 06 1C 00 01 00}
0x86AA4                 And {15 02}
0x86AA6                 Variable 0x37 equals 0x0 {12 06 37 00 00 00}
0x86AAC                 Or {16 02}
0x86AAE             End {29 02}
0x86AB0             Setting: Wake on LAN in S5, Variable: 0x214 {05 A6 28 00 29 00 11 00 34 12 14 02 00 10 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00}
0x86AD6                 Option: Disabled, Value: 0x0 (default) {09 0E 47 00 10 00 00 00 00 00 00 00 00 00}
0x86AE4                 Option: Enabled, Value: 0x1 {09 0E 48 00 00 00 01 00 00 00 00 00 00 00}
0x86AF2             End of Options {29 02}
0x86AF4         End If {29 02}

这段代码描述了一个条件判断块,它使用了一些操作码(Opcode)和变量,用于配置 Wake on LAN(WOL)在系统关机状态下的行为。具体来说:

  • 如果 Variable 0x1D 等于 0x2Variable 0x1C 等于 0x1Variable 0x37 等于 0x0,则执行相关的设置。
  • 这个设置涉及到 Wake on LAN 在 S5(系统关机状态)下的行为,其中 Variable 0x214 被设置为相应的值。
  • 有两个选项可供选择:Disabled(禁用)和 Enabled(启用),分别对应值 0x00x1

我们主要看第二行Variable 0x1D equals 0x2 {12 86 1D 00 02 00},复制这里的16进制内容12 86 1D 00 02 00,后面要用,再搜索G3,找到如下内容:

0x8D9CC         Grayout If: {19 82}
0x8D9CE             Variable 0x550 equals 0x1 {12 86 50 05 01 00}
0x8D9D4                 Variable 0x1D equals 0x2 {12 06 1D 00 02 00}
0x8D9DA                 Variable 0x1C equals 0x1 {12 06 1C 00 01 00}
0x8D9E0                 And {15 02}
0x8D9E2                 Or {16 02}
0x8D9E4             End {29 02}
0x8D9E6             Setting: After G3 On, Variable: 0x1EF {05 A6 E7 01 E8 01 25 01 34 12 EF 01 00 10 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00}
0x8DA0C                 Option: S0, Value: 0x0 (default) {09 0E E9 01 10 00 00 00 00 00 00 00 00 00}
0x8DA1A                 Option: S5, Value: 0x1 {09 0E EA 01 00 00 01 00 00 00 00 00 00 00}
0x8DA28                 Option: Last State, Value: 0x2 {09 0E EB 01 00 00 02 00 00 00 00 00 00 00}
0x8DA36             End of Options {29 02}
0x8DA38         End If {29 02}

以下是对每一行的解释:

  1. 0x8D9CC Grayout If: {19 82}:

    • 这是一个条件判断块的开始。代码将根据条件的满足与否来决定后续操作是否执行。条件 {19 82} 可能包含了对某个变量或变量的组合的测试。
  2. 0x8D9CE Variable 0x550 equals 0x1 {12 86 50 05 01 00}:

    • 如果变量 0x550 的值等于 0x1,则条件成立,执行条件块内的操作。
  3. 0x8D9D4 Variable 0x1D equals 0x2 {12 06 1D 00 02 00}:

    • 进一步的条件,要求变量 0x1D 的值等于 0x2
  4. 0x8D9DA Variable 0x1C equals 0x1 {12 06 1C 00 01 00}:

    • 另一个条件,要求变量 0x1C 的值等于 0x1
  5. 0x8D9E0 And {15 02}:

    • 逻辑运算符,表示前面的条件必须同时成立。
  6. 0x8D9E2 Or {16 02}:

    • 逻辑运算符,表示前面的条件中至少有一个必须成立。
  7. 0x8D9E4 End {29 02}:

    • 条件块的结束。
  8. 0x8D9E6 Setting: After G3 On, Variable: 0x1EF {05 A6 E7 01 E8 01 25 01 34 12 EF 01 00 10 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00}:

    • 如果条件块中的条件满足,将执行这个设置操作。它将 After G3 On 的设置与 Variable 0x1EF 相关联。
  9. 0x8DA0C Option: S0, Value: 0x0 (default) {09 0E E9 01 10 00 00 00 00 00 00 00 00 00}:

    • 设置中的选项,这里是 S0(系统全电源运行状态),默认选中,值是 0x0
  10. 0x8DA1A Option: S5, Value: 0x1 {09 0E EA 01 00 00 01 00 00 00 00 00 00 00}:

    • 设置中的选项,这里是 S5(系统关机状态),值为 0x1
  11. 0x8DA28 Option: Last State, Value: 0x2 {09 0E EB 01 00 00 02 00 00 00 00 00 00 00}:

    • 设置中的选项,这里是 Last State(上一次的状态),值为 0x2
  12. 0x8DA36 End of Options {29 02}:

    • 设置选项的结束。
  13. 0x8DA38 End If {29 02}:
    • 整个条件块的结束。

这段代码的目的是根据一系列条件来配置 After G3 On 的设置,具体是将其与某个变量(Variable 0x1EF)相关联,并设置不同的选项(S0、S5、Last State)的值,这取决于条件是否满足。在 ACPI 语言中,这样的代码通常用于定义电源管理策略。

看上去没什么问题,不用改,而前面我们已经通过EUVTOOL工具确认了After G3 OnChipset Configuration的子项,所以至少还要将Chipset Configuration解锁,搜索此项,找到如下内容

0x868CF         Suppress If: {0A 82}
0x868D1             Variable 0x1E equals 0x40 {12 86 1E 00 40 00}
0x868D7                 Not {17 02}
0x868D9             End {29 02}
0x868DB             Ref: Chipset Configuration, Variable: 0xFFFF {0F 0F 74 00 75 00 07 00 00 00 FF FF 00 27 00}
0x868EA         End If {29 02}

以下是对每一行的解释:

  1. 0x868CF Suppress If: {0A 82}:

    • 这是一个条件判断块的开始。代码将根据条件的满足与否来决定是否执行后续操作。条件 {0A 82} 可能包含了对某个变量或变量的组合的测试。
  2. 0x868D1 Variable 0x1E equals 0x40 {12 86 1E 00 40 00}:

    • 如果变量 0x1E 的值等于 0x40,则条件成立,执行条件块内的操作。
  3. 0x868D7 Not {17 02}:

    • 逻辑运算符,表示对前面条件的取反。
  4. 0x868D9 End {29 02}:

    • 条件块的结束。
  5. 0x868DB Ref: Chipset Configuration, Variable: 0xFFFF {0F 0F 74 00 75 00 07 00 00 00 FF FF 00 27 00}:

    • 引用操作,这里是引用了 Chipset Configuration 中的某个变量(Variable: 0xFFFF)。
  6. 0x868EA End If {29 02}:
    • 整个条件块的结束。

这段代码的逻辑是,如果变量 0x1E 的值不等于 0x40,则执行引用操作,引用了 Chipset Configuration 中的 Variable: 0xFFFF,即不隐藏选项。

那么参考0x868D1 Variable 0x1E equals 0x40 {12 86 1E 00 40 00},我们可以使用前面复制的16进制数来替换掉这里的12 86 1E 00 40 00,当然,需要使用16进制编辑器在01.ffs里修改,推荐使用免费的HxD编辑器

打开后,使用Ctrl+G跳转到变量所在的行868D1,看到值为12 86 1E 00 40 00,修改为12 86 1D 00 02 00,保存后就可以进行替换模块了

替换模块为修改后的

和之前导出时差不多,同样是两个方法

方法一:
打开 UEFITools,首先点击左上角的 File>Open image File,打开setup.fd,还是找到之前那个模块,右键Replace body…,选择修改好的01.fbd进行替换,再保存BIOS修改即可

方法二:
使用H2OEZE-Win32.exe打开setup.fd,选择File>Load BIOS image from…>setup.fd,接下来替换模块:Components>Module>Replace module,在Select module to replace下选择之前导出的模块,在Load module from…下选择刚刚修改好的01.ffs,最后点击Apply,弹出Successful后,需要再点击File>Save进行BIOS保存

检查修改后的BIOS

再次使用EUVTOOL工具,打开修改后的setup.fd,再点击Setup,检查BIOS是否按修改正常工作,避免刷入BIOS芯片后导致无法开机,若到那一步,只有使用编程器刷写BIOS了,烧了BIOS芯片的话,还有可能会遇到同型号的新芯片安装后无法工作的问题,这是因为部分厂商为了安全,锁定了一板一BIOS芯片,这样就只能返厂送修了,像我这台笔记本,厂商都无了,那就是直接宣布死刑

正式刷写BIOS

管理员权限运行之前创建的BIOS Flashing.bat,等待刷入后重启进入BIOS即可

END

如果一切正常,这时候应该就解锁BIOS了,但我倒在了最后的刷写上,BIOS的写入保护在这台笔记本上也许可以参考国外论坛的这篇帖子:[Guide] Unlock Intel Flash Descriptor Read/Write Access Permissions for SPI Servicing进行解锁,但仔细看了一下,觉得风险太大,那么最后只能通过编程器物理绕过,但那样的话又是新的风险和复杂的手工,而我只是想实现来电自启而已,不值得搞这么复杂

要动主板的话,还不如直接改开机键来的简单且安全,参考B站教程:为老主板添加来电自动开机功能-解决BIOS无来电开机选项_哔哩哔哩_bilibili,而且这样改甚至可以上单片机搞远程管理,不过那就是后话了,现在我还是使用虚拟机搭建软路由吧,不用这么操心,效果也不差,就是这个笔记本又闲置了


版权属于:本文为原创文章,版权归 AUK CL 所有。
文章地址: https://aukcl.win/archives/674/
所有原创文章由知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
您可以自由转载或修改,但禁止一切形式的商业使用,同时,务必请注明原文地址及作者信息。

Last modification:November 23, 2023
如果觉得我的文章对你有用,请随意赞赏