NDS固件(firmware)及第三方自定义固件FlashMe相关历史梳理

一、前言

NDS固件(firmware)是任天堂的双屏多媒体互动系统Nintendo Dual Screen(简称NDS)的系统固件,存储于机身256KB/512KB的eeprom芯片中,用于引导校验加载游戏卡带,并提供设置语言、个性化昵称、界面颜色、时间等内容及主菜单界面的显示。它与机身的BIOS9、BIOS7共同组成了NDS运行游戏卡带的底层数据。
现如今在互联网上关于NDS固件的信息鱼龙混杂,其历史版本的相关内容混杂了大量的似是而非的错误或不完善的各种说法。
在经过对于各种资料的梳理,以及相关软件的代码挖掘分析,我得以理清关于固件版本的相关信息,并将此整理成文,以供目前或以后对此感兴趣的玩家或研究者检索参考。
本文仅讨论关于DS初代、DSlite的固件内容,dsi、3ds上的ds固件数据结构存在较大差异,不在本文讨论范围内。

二、NDS固件的结构

在对于固件版本的历史梳理之前,需要先对固件的结构进行介绍,因其结构中包含了对于版本判断有所帮助的相关数据线索。
这里摘取引用gbatek的相关资料:

Firmware Memory Map
  00000h-00029h  Firmware Header
  0002Ah-001FFh  Wifi Calibration
 -WORLD WIDE
  00200h-3F9FFh  Firmware Code/Data
  3FA00h-3FDFFh  Wifi Settings 1,2,3 (3FD00h-3FDFFh dummy)
  3FE00h-3FFFFh  User Settings 1,2
 -CHN [iQue] / KOR
  00200h-7F9FFh  Firmware Code/Data
  7FA00h-7FDFFh  Wifi Settings 1,2,3 (7FD00h-7FDFFh dummy)
  7FE00h-7FFFFh  User Settings 1,2

固件内容主要分为两大块内容,即固件核心数据固件私有数据。下文不会对固件结构的每一条内容都进行详细解释,仅对与本文主题关联较深的部分多着笔墨。

2.1 固件核心数据(Core data)

固件核心数据,包括位于固件开头的文件头00000h-00029h Firmware Header以及占据固件整个容量主体部分的核心程序00200h-3F9FFh Firmware Code/Data(256KB国际版固件)或00200h-7F9FFh Firmware Code/Data(512kb神游或韩版固件)。
这两部分的数据,是用于区分固件归属于不同版本的主要数据。将除这两部分外的数据全部填充0xFF,并裁剪末尾数据直到Firmware Code/Data的最后有效数据处,对其进行CRC-32/ISO-HDLC校验,得到的数据便是该固件版本的crc32校验值。
不同DS主机如果持有相同的固件版本,那么核心数据部分的2个内容必定是完全相同的。

2.1.1 固件文件头(Firmware Header)//00000h-00029h

Firmware Header (00000h-001FFh)
  Addr Size Expl.
  000h 2    part3 romaddr/8 (arm9 gui code) (LZ/huffman compression)
  002h 2    part4 romaddr/8 (arm7 wifi code) (LZ/huffman compression)
  004h 2    part3/4 CRC16 arm9/7 gui/wifi code
  006h 2    part1/2 CRC16 arm9/7 boot code
  008h 4    firmware identifier (usually nintendo "MAC",nn) (or nocash "XBOO")
            the 4th byte (nn) occassionally changes in different versions
  00Ch 2    part1 arm9 boot code romaddr/2^(2+shift1) (LZSS compressed)
  00Eh 2    part1 arm9 boot code 2800000h-ramaddr/2^(2+shift2)
  010h 2    part2 arm7 boot code romaddr/2^(2+shift3) (LZSS compressed)
  012h 2    part2 arm7 boot code 3810000h-ramaddr/2^(2+shift4)
  014h 2    shift amounts, bit0-2=shift1, bit3-5=shift2, bit6-8=shift3,
            bit9-11=shift4, bit12-15=firmware_chipsize/128K
  016h 2    part5 data/gfx romaddr/8 (LZ/huffman compression)
  018h 5    Firmware version built timestamp (BCD minute,hour,day,month,year)
  01Dh 1    Console type
              FFh=Nintendo DS
              20h=Nintendo DS-lite
              35h=KorDS-lite
              57h=Nintendo DSi (also iQueDSi)
              43h=iQueDS
              63h=iQueDS-lite
              01h=Nintendo Zone Box (Debug)
  01Eh 2    Unused (FFh-filled)
  020h 2    User Settings Offset (div8) (usually last 200h flash bytes)
  022h 4    Unknown
  026h 2    part5 CRC16 data/gfx
  028h 2    unused (FFh-filled)

固件头文件主要用于记录固件核心程序的5个组件在固件内部的偏移地址,以及CRC-16/MODBUS校验值,同时还记录了固件生成时的时间戳数据、该固件适用的NDS主机类型等信息。
其中位于06h-07h的part1/2(5个组件中的前两个组件)的连锁crc16校验值数据(连锁,指先以默认初始值FFFFh进行计算part1的crc16校验值,再将该结果作为初始值进行part2的crc16校验),是第三方固件程序中,常用来作为判断当前或原始官方固件版本的依据。
其中位于18h-1Ch的时间戳数据是用于判断固件版本的重要数据。时间戳数据是一串5字节的BCD格式的时间数据,如45 14 07 12 05,代表该固件的生成时间为2005年12月07日14时45分

2.1.2 固件核心程序(Firmware Code/Data)//00200h-3F9FFh 或 00200h-7F9FFh

在前文文件头的内容中有提及,核心程序主要由5个组件组成。它们分别是:

通常情况下,5个组件在固件内的顺序是按照12345排列,但也存在部分固件中,排列顺序有所变化的情况。
在第三方固件中,往往会替换part1、part2的数据,以跳转引导启动的代码,并将原始的part1、2在原数据前添加相关代码内容后,作为次级引导进行调用。
part1、2需要进行解密、解压两步骤,才能得到原始的程序数据。打包时同样需要进行压缩、加密,从而得到可放置于固件内的文件。
part3、4、5则仅需要进行解压,即可得到原始的程序数据。打包时需要进行压缩,从而得到可放置于固件内的文件。
part12和part345的解压缩,使用的是不同的解压缩方式。

2.2 固件私有数据(Private Data)

固件私有数据,包括位于头文件与核心程序中间的wifi校准数据Wifi Calibration,以及位于固件末尾的wifi接入点设置Wifi Settings和用户设置User Settings,这3块内容。其中,wifi校准数据Wifi Calibration属于该固件硬件出厂时由官方设置了每张固件硬件唯一的MAC地址,及其无线射频信号的调节设置。由于固件硬件包含了网络配置的核心物理模块及软件数据配置,所以在nds领域也称载有固件数据的这个硬件为网卡。

2.2.1 wifi校准数据(Wifi Calibration)//0002Ah-001FFh

Wifi Calibration/Settings (located directly after Firmware Header)
  Addr Size Expl.
  000h-029h Firmware Header (see previous chapter)
  02Ah 2    CRC16 (with initial value 0) of [2Ch..2Ch+config_length-1]
  02Ch 2    config_length (usually 0138h, ie. entries 2Ch..163h)
  02Eh 1    Unused        (00h)
  02Fh 1    Version (0=v1..v4, 3=v5, 5=v6..v7,6=W006,15=W015,24=W024,34=N3DS)
  030h 6    Unused        (00h-filled) (DS-Lite and DSi: FF,FF,FF,FF,FF,00)
  036h 6    48bit MAC address (v1-v5: 0009BFxxxxxx, v6-v7: 001656xxxxxx)
  03Ch 128h Radio Frequency setting
  164h 9Ch  Unused (FFh-filled) (Outside CRC16 region, with config_length=138h)

wifi校准数据主要用于记录本网卡唯一的MAC地址数据,以及RF射频信号的校准调节。
MAC地址可以进行刷写改成其他地址,但通常不建议这么做,避免与世界上不知道哪一个玩家的DS主机或乃至游戏领域外的其他网卡MAC地址冲突。
RF射频信号的校准调节是网卡能否正常使用无线联机以及wifi联网的核心内容。DS网卡上的RF芯片主要有两类,对应的校准数据结构也不相同。
如果两张网卡是同类型的RF芯片,那么互相刷入对方的RF校准数据,也可以正常进行联网,只是不一定是适配本芯片的最佳设置。
而如果两张网卡是不同类型的RF芯片,那么刷入对方的RF校准数据,则会导致网卡无法正常使用。
同样,如果这里填充为0xFF或者刷入其他不符合当前网卡RF芯片的校准数据结构的话,也一样无法使用无线功能。
简单来说,如果在未进行备份原始固件的情况下,刷入了其他玩家转储dump的固件数据,导致联网功能异常的话,那么可以通过替换成另一种类型的RF校准数据的模板,可以让网卡正常启用无线功能(只是模板里的校准数据,不如工厂里原生给该硬件调节的RF校准数据更贴合该网卡RF芯片的实际物理情况)。
该数据属于工厂级别出厂设置内容,不对玩家用户开放编辑。每张网卡固件里的这部分内容都是不相同的。

2.2.2 wifi接入点设置(Wifi Settings)//3FA00h-3FDFFh 或 7FA00h-7FDFFh

wifi接入点设置,或者说蜂窝网络、热点连接,即常规拥有wifi联机功能的nds游戏运行时,登录的3个接入点的信息,便存储于此处。
该数据属于玩家个人可主动配置修改的内容。

2.2.3 用户设置(User Settings)//3FE00h-3FFFFh 或 7FE00h-7FFFFh

DS开机时设置的语言、昵称、生日、颜色、触摸屏校准信息、主机时间等内容存储于此。
该数据属于玩家个人可主动配置修改的内容。

三、NDS官方固件版本

此处仅讨论零售版DS主机内的固件,不讨论原型机、调试机等设备的固件。

3.1 版本号的民间社区命名

在早年的DS社区内,由于固件内仅存在固件生成时的时间戳,而不存在版本号的命名字符串,故民间根据主机推出时板载的固件类型的先后顺序进行排列命名。DS初代(又称phat、饭盒机)包含5个版本v1-v5,DS Lite包含2个版本v6-v7。以下是民间社区命名的版本号与其内部时间戳的对应关系:

v1:             2004-10-05 11:07
v2:             2004-11-26 09:51
v3:             2005-02-28 08:51
v4:             2005-06-06 14:48
v5:             2005-12-07 14:45
v6 (Lite):      2006-02-05 21:33
v7 (Lite):      2006-03-08 11:19

在第三方固件的相关代码识别中,通过对于固件文件头06h-07h位置上part1/2的连锁crc16校验值数据进行识别,用以判断对应版本,以下是part12的crc16与民间社区版本号的对应关系:

v1:             0x2c7a
v2:             0xe0ce
v3:             0xbfba
v4:             0xdfc7
v5:             0x73b3
v6 (Lite):      0xe843
v7 (Lite):      0x0f1f

以上7个版本均为国际版固件。除此之外,还存在位于中国地区的iQue神游DS(含初代机和Lite机)、位于韩国的KorDS(仅Lite机为韩版独立固件,韩国地区DS初代机为使用国际版DS初代主机),由于早年社区对这些版本的关注度较低,以及获取不便,故基本不存在对于这些版本的民间社区命名。此处我仿照国际版命名方式对其进行临时命名。
iQue神游初代(又称phat、饭盒机)包含1个版本iQue_v1,iQue lite包含1个版本iQue_v2,韩版KorDS lite包含1个版本Kor_v1。以下是临时命名的版本号与其内部时间戳,及part12的crc16的对应关系:

iQue_v1:        2005-06-09 21:15
iQue_v2 (Lite): 2006-04-26 15:35
Kor_v1 (Lite):  2006-11-09 21:30
iQue_v1:        0xf96d
iQue_v2 (Lite): 0x87c4
Kor_v1 (Lite):  0x74f0

3.2 过时的版本号判断方式

早年存在一种无需额外设备转储固件检查数据,就能便捷判断版本号的方式,称之为PicoChat聊天室颜色法。
具体流程是:

判断对照为:

v1:             DS主机卡死
v2:             上下屏幕呈蓝色(0x3D06 #304078)
v3:             上下屏幕呈绿色(0x01E0 #007800)
v4:             上下屏幕呈黄色(0x03FF #F8F800)
v5:             上下屏幕呈紫色(0x741B #D800E8)

关于v6-v7网络上流传着错误的版本:

v6 (Lite):      上下屏幕呈深蓝色
v7 (Lite):      不卡死,一切正常

但实际测试情况是:

v6 (Lite):      上下屏幕呈紫色(0x741B #D800E8)
v7 (Lite):      上下屏幕呈紫色(0x741B #D800E8)

即,从v5开始之后的所有版本,均为紫色。也就是说,PicoChat聊天室颜色法仅适用于DS初代主机的5个版本进行判断(仅考虑零售时预装版本,不考虑玩家自己另行刷入lite固件或第三方固件的情况),而不适用于Lite起的版本判断。
以下附上神游及韩版的PicoChat聊天室颜色情况:

iQue_v1:        上下屏幕呈绿色(0x01E0 #007800)
iQue_v2 (Lite): 上下屏幕呈紫色(0x741B #D800E8)
Kor_v1 (Lite):  上下屏幕呈紫色(0x741B #D800E8)

3.3 版本号的官方命名

近年来,存在泄露的官方固件刷写程序 F-Writer v1.0K 和 F-Writer v3.0 (USG) (World) (Ver1.0)。通过对其内部的残留代码的分析,我们可以从中找到官方对不同固件的命名方式。
程序内存放的固件的内部路径名的格式,如:
/Ipl2/link/NTR_0512071445
/Ipl2/link/USG_0602052133
NTR为DS初代主机的代号,USG为DS lite主机的代号,后续跟着的为该固件的生成时间戳的数据。即
/Ipl2/link/[型号]_[时间戳]的形式为固件的文件名
同时,每一个路径名同时又指向了如下几个信息,如:

NTR
WORLD WIDE
/Ipl2/link/NTR_0512071445
Ver5.0
0x12071445
0x80F824E1
0x00002BCA
console
region
path
official version naming
timestamp
crc32
border color of F-writer

即数据结构为

机型(console)
区域(region)
rom内文件路径(path)
官方版本号(official version naming)
时间戳后8个数字(timestamp)
crc32
F-writer边框颜色(border color of F-writer)

F-writer边框颜色:

border color:
NTR-WORLD WIDE: 0x2BCA ( #50F050) green
NTR-CHN [iQue]: 0x14BC ( #E02828) red
USG-WORLD WIDE: 0x739C ( #E0E0E0) grey
USG-CHN [iQue]: 0x161C ( #E08028) orange
USG-NIS(L):     0x2D4E ( #705058) dustyrose
USG-KOR:        0x5042 ( #1010A0) blue

经过统计,我们得到了大部分零售版固件对应的官方版本号命名:

v4:             NTR-WORLD WIDE-Ver4.0
v5:             NTR-WORLD WIDE-Ver5.0
v6 (Lite):      USG-WORLD WIDE-Ver2.0 
v7 (Lite):      USG-WORLD WIDE-Ver3.0
iQue_v1:        NTR-CHN [iQue]-Ver1.0
iQue_v2 (Lite): USG-CHN [iQue]-Ver1.0C
Kor_v1 (Lite):  USG-KOR       -Ver1.0K

v1-v3的官方版本命名并未包含在F-Writer中,但根据v4,v5的对应官方命名为Ver4.0,Ver5.0,有较大概率v1-v3的命名方式也为Ver1.0-Ver3.0
故最终民间社区与官方命名的对照可以整理如下:

v1:             NTR-WORLD WIDE-Ver1.0(推测)
v2:             NTR-WORLD WIDE-Ver2.0(推测)
v3:             NTR-WORLD WIDE-Ver3.0(推测)
v4:             NTR-WORLD WIDE-Ver4.0
v5:             NTR-WORLD WIDE-Ver5.0
v6 (Lite):      USG-WORLD WIDE-Ver2.0 
v7 (Lite):      USG-WORLD WIDE-Ver3.0
iQue_v1:        NTR-CHN [iQue]-Ver1.0
iQue_v2 (Lite): USG-CHN [iQue]-Ver1.0C
Kor_v1 (Lite):  USG-KOR       -Ver1.0K

四、第三方自定义固件FlashMe

写在前头,FlashMe的v1-v8a版本编号,仅代表FlashMe这个第三方自定义固件自身的版本变化,与官方零售版固件的v1-v7不存在对应关系。
这是很多人会产生误区的地方,将FlashMe的版本认为跟官方固件的版本号是对应的进行更新,但其实并没有这种关联。

4.1 FlashMe的作用

FlashMe是一种基于官方固件进行修改的第三方固件。它的作用主要用于替代PassMe复杂的slot1引导,可以直接开机启动插在slot2端的ds烧录卡,同时还拥有移除downloadplay的rsa加密校验检测的作用,可以运行修改过但没有正确密钥签名的downloadplay程序。除此之外,FlashMe还在固件数据的较前端存放了救砖代码,可以在固件损坏、固件刷写不完整的情况下,只要前部救砖代码的数据还存在,就可以在开机时通过这段代码强行启动slot2的卡带,从而运行固件刷写软件来重新刷写完整固件。

4.2 FlashMe的版本

FlashMe的最新版本为v8a,支持ds饭盒机和dslite。
FlashMe的版本主要可以分为两个阶段。v0-v4为一个阶段,v5-v8a为第二个阶段。
v0,准确的说称之为Beta版本,目前不存在公开版本,因为Beta版本是需要玩家通过PassMe/WiFiMe运行官网提供的”getID.ds.gba”以生成与本机关联的序列号,再将序列号上传,以获取固件补丁程序 “玩家的序列号.ds.gba”,再运行该软件并短接SL1以刷入固件。
v1,是第一个公开的正式版本,基于官方固件v3(饭盒机使用)修改制作。随后v2、v3在同月较短时间内连续更新,其后的v4则过了几个月之后才更新。
v5是非常重大的一次更新,这是因为DS上首款使用了wifi功能的游戏——马里奥赛车DS出现了。在游戏发售前,媒体人员在官方展厅试玩时,发现使用刷过FlashMe的机子在在线游玩过该游戏后出现了砖机现象。Loopy随后跟进研究,最终发现Wifi设置会存放在固件末尾用户设置的前面的空位中。而这个空位,正是FlashMe相关组件存放的地方。Wifi设置覆盖了FlashMe的内容,导致出现了砖机情况。Loopy随即修复了这个问题,将FlashMe的相关组件往前挪动避开了Wifi设置区域。在随后游戏正式发售后,不出意外的,许多没关注这方面信息的未更新到最新版本FlashMe的玩家也因此中招了,迎来了一波砖机潮,促使玩家们纷纷更新了设备上的FlashMe。
随后的v7又是一个较为重要的节点,因为这个时候DS Lite发售了,区别于ds饭盒机,lite有自己的版本的固件,在背光调节上也存在不同。v7最初依旧只是基于官方饭盒固件v3制作,随后基于官方lite固件v6制作了针对lite版本的FlashMe,并更新了饭盒版本的FlashMe。饭盒版FlashMe与测试的lite版FlashMe一开始还是分开的,随后作者将两个版本整合到一起,通过对电源管理芯片的判断来检测设备是饭盒机还是Lite机,这时候依旧是称之为v7版本,此后的后续版本皆延续了一个刷写rom内包含了饭盒和lite的两种FlashMe固件。
在这里需要提及的是,饭盒DS国际版晚期出现了一种编号印为CPU20的主板(出厂预置官方v4或v5版本固件),这个主板拥有和lite相同的电源管理芯片,这意味着使用FlashMe刷写软件在这类饭盒机上使用时,会视作为lite版本,将lite的固件刷写入其中。这个主板最为人熟知的功能,就是它拥有和lite一样的可以进行4级调光的能力,尽管它搭载的仍旧是只支持有光和无光两种模式的v4或v5固件,但在使用部分r4烧录卡时,r4的调光设置可以调用到这个主板的4级调光。而如果直接刷入官方lite固件v6、v7或者刷入FlashMe v7及之后的版本(会识别成lite进行刷写基于官方v6固件修改的FlashMe),那么此时在主页面上就可以跟lite机型一样进行4级调光。
v7是最后支持初代slot2烧录卡的版本,v8及v8a提及因为安全问题,所以移除了mk2 mk3烧录卡的引导支持,DSLink烧录卡也是相似的引导机制,所以v8及之后的版本也无法启动DSLink。

4.3 FlashMe的发展

五、DS固件及破解时间线

为方便阅读,固件版本以民间命名方式描述

2004

2005

2006

2007

文章目录