SPI FLASH Recovery/XO-1.5 Partial
Jump to navigation
Jump to search
Problem Description
An XO-1.5 was unable to boot:
- the display backlight was on, the display was white, with no XO icon,
- there was no startup sound,
- the power button was able to turn the laptop off.
Analysis
- the serial console was attached and showed:
+ Forthmacs Type 'i' to interrupt stand-init sequence No DSDT Unimplemented package interface procedure ok █
- the system responded to commands:
ok banner OLPC D7, 1 GiB memory installed, No internal storage, S/N SHC016013D1 OpenFirmware Q3B13 EC Firmware Ver:2.2.10 2014-01-09 04:04:33 UTC ok █
- the No DSDT means the dropin dsdt could not be located,
- the dropin table was dumped:
ok .dropins Name Data Offset Length Expansion Checksum reset 20 218b 0 d3c3b resume 21cc 711 0 2fd9e paging 2900 128 0 65c7 inflate 2a48 1cb9 0 df243 firmware 4724 54d70 e2310 2c9c328 class0c0300 594b4 2a01 4ed8 1505f4 class0c0320 5bed8 3c5b 6fb4 1e0343 usb,class9 5fb54 70c 0 2683e ok █
- the abbreviated table suggests that the corruption begins at around 0x60000, which corresponds to 0x70000 in the SPI Flash,
- the Flash block size is 0x10000,
- the SPI Flash was dumped as verification,
no-page : .flash use-spi-flash flash-write-enable /flash 0 do flash-buf i + /chunk i flash-read i .x (cr /chunk +loop cr flash-buf /flash dump cr flash-write-disable ; .flash
- analysis of the dump against production .rom files showed that Q3C07 was present for 0x00000 to 0x6ffff, with Q3B03 for 0x70000 to 0xfffff.
Root Cause
- power to the laptop was removed by the user during the firmware upgrade to 12.1.0, bricking the laptop.
Tooling
- the affected XO-1.5, the target,
- a serial adapter,
- a Linux system to be used as a serial terminal, the host,
- the screen and pv packages,
- an image file containing the latter part of the new firmware version:
$ dd if=q3c07.rom bs=1 skip=458752 of=q3c07-0x70000-0xfffff.rom $ md5sum q3c07-0x70000-0xfffff.rom da1a1ef3339c016953b4cdb8032050aa q3c07-0x70000-0xfffff.rom
- a repair program for loading to the firmware:
h# 70000 value borken \ point from which the SPI Flash is damaged flash-buf borken + value borken-buf /flash borken - value /borken : .md5 ( md5$ -- ) \ display an md5sum result push-hex bounds ?do i c@ <# u# u# u#> type loop pop-base ; : take ( -- ) \ load buffer from host over serial use-spi-flash flash-write-enable ." ready for transmission" cr borken-buf /borken bounds do ukey i c! loop d# 1000 ms ." received md5 " borken-buf /borken $md5digest1 .md5 cr ; : debork \ write only the section to be repaired \ from write-firmware flash-buf borken + mfg-data-offset borken write-flash-range flash-buf mfg-data-end-offset + /flash mfg-data-end-offset write-flash-range \ from verify-firmware flash-buf borken + mfg-data-offset borken verify-flash-range flash-buf mfg-data-end-offset + /flash mfg-data-end-offset verify-flash-range ; : commit flash-write-disable ; \ reboots
- a pv command line prepared for sending the image file:
pv --force -i 0.25 -B 128 q3c07-0x70000-0xfffff.rom > /dev/ttyUSB0
Reproducer
- flash Q3C07 normally,
- use the tooling to flash the latter part of Q3B03.
Solution
- power on the target, and press 'i' to interact, and observe the response, which must be:
+ Forthmacs Type 'i' to interrupt stand-init sequence Interacting ok █
- download the repair program into the target, type dl on the host terminal and press enter:
ok dl Ready for download. Send file then type ^D █
- copy and paste the repair program into the host terminal, then type Control-D, the target must respond only with the prompt:
ok █
- download the image file into the target; type take on the host terminal and press enter, the target must respond thus:
ok take SPI FLASH is type 13 - Spansion, Winbond, or ST ready for transmission █
- use the pv command line to send the image file, and observe the response, which must be:
received md5 da1a1ef3339c016953b4cdb8032050aa ok █
- check that the md5sum matches before proceeding,
- write the image to the SPI Flash device, type debork and press enter, the target must respond thus:
ok debork Writing d0000 Writing f0000 Verifying d0000 Verifying f0000 ok █
- check that there were no errors,
- commit the change and reboot, type commit and press enter, the target must respond thus:
ok commit Restarting... + Forthmacs Type 'i' to interrupt stand-init sequence USB2 devices: USB1 devices: OLPC D7, 1 GiB memory installed, 4 GB internal storage, S/N SHC016013D1 OpenFirmware Q3C07 EC Firmware Ver:2.2.10 2014-01-09 04:35:15 UTC Type the Esc key to interrupt automatic startup 2 █
- check that the laptop starts up correctly.