You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've taken to reversing the Thinkpad BIOS and EC flashing procedure recently. (Side note: if there was something missing or unknown like the F12 action byte, I could probably take a look)
This has been rather fruitful and the MEC1618 perfectly lines up with what I'm observing in the assembly (so I wonder what is the actual difference?), and I've even identified that this EC definition could mostly be applied to X230.
That aside, here's a somewhat vague overview of the process on the BIOS' side:
Assert that the command has completed (SMB_STS[7] == 1)
Initialise flasher
Since the embedded flash cannot be written to while executed, a small program must be sideloaded onto the EC's RAM which can then update the embedded flash
Preparation
Pad the code to the nearest -2 mod 8th byte
Append the CRC16_CCITT_FALSE checksum
Ensure the payload is smaller than 1000h bytes, as it will be written to 63000h
Encrypt the payload using Blowfish in CBC mode with the following parameters:
Key: 964C64A9FE22DB7A4AFE9FD50A84FB0A6126E3D7A21986D8B8FB49913A9691BB
IV: 243F6A8885A308D3
Upload
Send command CFh to EC
Receive one byte from EC data port and assert that it is 88h
Send 55h to EC data port
Send payload length as big-endian short to EC data port
Send encrypted payload to EC data port
The official flasher program does the following:
Disable the watchdog timer by setting the 0th bit of the WDT control register (WDT_CONTROL @ F00404h) to 0
Copy Blowfish keys passed to it by the EC firmware at entrypoint call
Allow Register Control by setting the 0th bit of the embedded flash configuration register (FLASH_CONFIG @ FF3910h) to 1
Enable Register Control by setting the 0th bit of the embedded flash command register (FLASH_COMMAND @ FF3908h) to 1
Expose 3 new EC commands
Erase: F0h <sector index 1b>
Note: a sector in MEC is 2048 bytes
Toggle flash access by setting the 8th bit (EEPROM_Access) of FLASH_CONFIG to 1
Check the status of the flash address FIFO by reading the 2nd bit (Address_Full) of the embedded flash status register (FLASH_STATUS @ FF390Ch)
If full, return error status FEh over EC data
Check the mode of the embedded flash controller by reading the bits 0 and 1 (Flash_Mode) of FLASH_STATUS
If the flash controller is not on standby (0), return error status FEh over EC data
Switch to erase mode by setting Flash_Mode to 3
Erase the specified sector by writing it to bits 17 through 11 inclusive of the embedded flash address register (FLASH_ADDRESS @ FF3904h)
Wait until the 0th bit (Busy) of FLASH_STATUS is 0
Change the mode of the embedded flash controller to standby
Return success status F9h over EC data
Write: F1h <address 3b> <length 1b>
Ensure that length is less than or equal to 0x80
Read length-bytes of data
If a portion of data is within an encrypted region, decrypt using the initialised Blowfish keys
Extend the CRC16_CCITT_FALSE checksum with each byte of data unless the flash address is 2FFFCh, at which point it compares the checksum
If the checksum fails, set the previous byte to 0xaf(?)
Toggle flash access
If there is an error (1 in any of bits 8 through 10 of the embedded flash status register), return error status FCh over EC data
Switch to burst and program mode by setting bits 1 and 2 of the embedded flash command register to 1
Wait until the flash address FIFO is not full
Write the address to FLASH_ADDRESS
Wait until the flash controller is not busy
For every 4 bytes of data
Write to the flash data FIFO register (FLASH_DATA @ FF3900h)
Wait until the flash controller is not busy
Disable burst mode and switch to standby mode by clearing the first 3 bits of the embedded flash command register
Return success status FAh over EC data
Reset: F9h
Send success status F9h over EC data
Disable Register Control
Disallow Register Control
Reload the watchdog timer, writing 0005h to the WDT load register (F00400h)
Enable the watchdog timer while clearing its status (1st bit to 1).
Start the watchdog timer by writing 01h to the WDT kick Register (F00408h)
With the low interval, the EC is forcefully reset by the watchdog timer
Default handler returns invalid status FFh over EC data
Flash firmware
For each sector 0 through 95, call Erase command
For each sector 0 through 95:
For each 80-byte chunk, call Write command
If an error status is returned, redo once:
Read an EC data byte (status) and assert it is FDh
Call Erase command on the current sector
Call unknown command (F4h) and assert a return status of FAh
Restart writing from the first chunk
Clear the 6th bit of CMOS register 45h and update the CMOS checksum
Call Reset command
Call several unknown UEFI interfaces
One appears to be modifying a byte variable
Call gRS->ResetSystem
This analysis was done on the last modifiable version, so there are signature checks not documented here; I suspect that they are done on BIOS side before uploading to EC though. The unknown EC commands may only be applicable to other Lenovo lines
I'll look at making a PR for docs/ outlining the above, but one could hypothetically develop an alternative EC flash for use with corebooted systems which does not implement the Lenovo update processes, eliminating the need for DOSFLASH or reverting to official BIOS to patch EC.
The text was updated successfully, but these errors were encountered:
I've taken to reversing the Thinkpad BIOS and EC flashing procedure recently. (Side note: if there was something missing or unknown like the F12 action byte, I could probably take a look)
This has been rather fruitful and the MEC1618 perfectly lines up with what I'm observing in the assembly (so I wonder what is the actual difference?), and I've even identified that this EC definition could mostly be applied to X230.
That aside, here's a somewhat vague overview of the process on the BIOS' side:
5A 84 65 60 47
Since the embedded flash cannot be written to while executed, a small program must be sideloaded onto the EC's RAM which can then update the embedded flash
Key: 964C64A9FE22DB7A4AFE9FD50A84FB0A6126E3D7A21986D8B8FB49913A9691BB
IV: 243F6A8885A308D3
The official flasher program does the following:
This analysis was done on the last modifiable version, so there are signature checks not documented here; I suspect that they are done on BIOS side before uploading to EC though. The unknown EC commands may only be applicable to other Lenovo lines
I'll look at making a PR for
docs/
outlining the above, but one could hypothetically develop an alternative EC flash for use with corebooted systems which does not implement the Lenovo update processes, eliminating the need for DOSFLASH or reverting to official BIOS to patch EC.The text was updated successfully, but these errors were encountered: