Calibration
During factory setup, the Switch goes through calibration and the generated data from this process is written to two NAND user partitions (PRODINFO and PRODINFOF).
CalibrationBinary
This is "nn::cal::CalibrationBinary".
This is a raw binary blob containing the main calibration data, which ranges from hardware IDs to system keys.
Offset | Size | Description |
---|---|---|
0x0 | 0x4 | MagicNumber ("CAL0") |
0x4 | 0x4 | Version |
0x8 | 0x4 | BodySize (size of calibration data starting at offset 0x40) |
0xC | 0x2 | Model |
0xE | 0x2 | UpdateCount (increases each time calibration data is installed) |
0x20 | 0x20 | BodyHash (SHA256 hash calculated over calibration data) |
0x40 | 0x1E | ConfigurationId1 |
0x60 | 0x20 | Reserved |
0x80 | 0x4 | WlanCountryCodesNum |
0x84 | 0x4 | WlanCountryCodesLastIndex |
0x88 | 0x180 | WlanCountryCodes |
0x210 | 0x6 | WlanMacAddress |
0x220 | 0x6 | BdAddress |
0x230 | 0x6 | AccelerometerOffset |
0x238 | 0x6 | AccelerometerScale |
0x240 | 0x6 | GyroscopeOffset |
0x248 | 0x6 | GyroscopeScale |
0x250 | 0x18 | SerialNumber |
0x270 | 0x30 | EccP256DeviceKey (unused) |
0x2B0 | 0x180 | EccP256DeviceCertificate (unused) |
0x440 | 0x30 | EccB233DeviceKey (unused) |
0x480 | 0x180 | EccB233DeviceCertificate |
0x610 | 0x30 | EccP256ETicketKey (unused) |
0x650 | 0x180 | EccP256ETicketCertificate (unused) |
0x7E0 | 0x30 | EccB233ETicketKey (unused) |
0x820 | 0x180 | EccB233ETicketCertificate (unused) |
0x9B0 | 0x110 | SslKey (unused) |
0xAD0 | 0x4 | SslCertificateSize |
0xAE0 | 0x800 | SslCertificate (only SslCertificateSize bytes are used) |
0x12E0 | 0x20 | SslCertificateHash (SHA256 over the SSL certificate) |
0x1300 | 0x1000 | RandomNumber |
0x2300 | 0x20 | RandomNumberHash (SHA256 over the random data block) |
0x2320 | 0x110 | GameCardKey (unused) |
0x2440 | 0x400 | GameCardCertificate |
0x2840 | 0x20 | GameCardCertificateHash (SHA256 over the GameCard certificate) |
0x2860 | 0x220 | Rsa2048ETicketKey (unused) |
0x2A90 | 0x240 | Rsa2048ETicketCertificate |
0x2CE0 | 0x18 | BatteryLot |
0x2D00 | 0x800 | SpeakerCalibrationValue (only 0x5A bytes are used) |
0x3510 | 0x4 | RegionCode |
0x3520 | 0x50 | AmiiboKey |
0x3580 | 0x14 | AmiiboEcqvCertificate |
0x35A0 | 0x70 | AmiiboEcdsaCertificate |
0x3620 | 0x40 | AmiiboEcqvBlsKey |
0x3670 | 0x20 | AmiiboEcqvBlsCertificate |
0x36A0 | 0x90 | AmiiboEcqvBlsRootCertificate |
0x3740 | 0x4 | ProductModel |
0x3750 | 0x6 | ColorVariation |
0x3760 | 0xC | LcdBacklightBrightnessMapping |
0x3770 | 0x50 | ExtendedEccB233DeviceKey |
0x37D0 | 0x50 | ExtendedEccP256ETicketKey (unused) |
0x3830 | 0x50 | ExtendedEccB233ETicketKey (unused) |
0x3890 | 0x240 | ExtendedRsa2048ETicketKey |
0x3AE0 | 0x130 | ExtendedSslKey |
0x3C20 | 0x130 | ExtendedGameCardKey |
0x3D60 | 0x4 | LcdVendorId |
0x3D70 | 0x240 | [5.0.0+] ExtendedRsa2048DeviceKey |
0x3FC0 | 0x240 | [5.0.0+] Rsa2048DeviceCertificate |
0x4210 | 0x1 | [5.0.0+] UsbTypeCPowerSourceCircuitVersion |
0x4220 | 0x4 | [9.0.0+] HousingSubColor |
0x4230 | 0x4 | [9.0.0+] HousingBezelColor |
0x4240 | 0x4 | [9.0.0+] HousingMainColor1 |
0x4250 | 0x4 | [9.0.0+] HousingMainColor2 |
0x4260 | 0x4 | [9.0.0+] HousingMainColor3 |
0x4270 | 0x1 | [9.0.0+] AnalogStickModuleTypeL |
0x4280 | 0x12 | [9.0.0+] AnalogStickModelParameterL |
0x42A0 | 0x9 | [9.0.0+] AnalogStickFactoryCalibrationL |
0x42B0 | 0x1 | [9.0.0+] AnalogStickModuleTypeR |
0x42C0 | 0x12 | [9.0.0+] AnalogStickModelParameterR |
0x42E0 | 0x9 | [9.0.0+] AnalogStickFactoryCalibrationR |
0x42F0 | 0x1 | [9.0.0+] ConsoleSixAxisSensorModuleType |
0x4300 | 0x6 | [9.0.0+] ConsoleSixAxisSensorHorizontalOffset |
0x4310 | 0x1 | [6.0.0+] BatteryVersion |
0x4320 | 0x1 | [10.0.0+] TouchIcVendorId |
0x4330 | 0x4 | [9.0.0+] ColorModel |
0x4340 | 0x1 | [10.0.0+] ConsoleSixAxisSensorMountType |
ProductModel
This is "nn::cal::ProductModel".
Value | Description |
---|---|
0 | Invalid |
1 | Nx |
2 | Copper |
3 | Iowa |
4 | Hoag |
5 | Calcio |
6 | Aula |
Error detection
Each block of raw calibration data (with the exception of blocks with SHA256 hashes) is padded to 16 bytes, being the last 2 bytes a CRC-16 over said block.
XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX 00 00 00 00 00 00 00 00 00 00 00 00 00 00 YY YY XX == data 00 == padding YY == crc
The CRC-16 is generated as follows:
unsigned int crc_16_table[16] = { 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 }; unsigned short int get_crc_16 (char *p, int n) { unsigned short int crc = 0x55AA; int r; while (n-- > 0) { r = crc_16_table[crc & 0xF]; crc = (crc >> 4) & 0x0FFF; crc = crc ^ r ^ crc_16_table[*p & 0xF]; r = crc_16_table[crc & 0xF]; crc = (crc >> 4) & 0x0FFF; crc = crc ^ r ^ crc_16_table[(*p >> 4) & 0xF]; p++; } return(crc); }
CalibrationFile
This is "nn::cal::CalibrationFile".
This is a FAT12 compliant filesystem mainly used to keep calibration logs and other assorted files.
├── Certifications │ └── WirelessCertification.png └── ptd ├── DeviceIdWithEmsBit.dat ├── Ecid.dat ├── prodCode.dat └── log ├── Process_asm1.log ├── Process_board1.log ├── TestFlagLine.log ├── TestFlagQc.log ├── AGING │ └── Sequence.log ├── BOARD_TEST │ └── Sequence.log ├── BOARD_WIRELESS │ └── Sequence.log ├── FINAL_CHECK │ └── Sequence.log ├── LCD_AND_KEY │ └── Sequence.log └── USB_AND_HP └── Sequence.log
DeviceIdWithEmsBit
Contains a 0x10-byte uppercase hex string, identical to the DeviceId in the DeviceCert.