Last week I downloaded (but did not install) the iPhone OS 3.1.3 firmware for my 3GS. I wanted to have a copy of the firmware on hand, but didn't want to upgrade right away. I checked "Do not ask me again" and clicked Download Only. I thought that was the end of the matter.
Unfortunately, this Sunday, I plugged in my iPhone and left the room to grab some tea. When I returned, the iPhone was 50% of the way through the 3.1.3 firmware upgrade procedure. It did something I had no idea that it would do: it upgraded me without asking.
How frustrating! What's more, I didn't have a copy of 3.1.2 on-hand to downgrade to because iTunes automatically deleted the old firmware files and I was using default Time Machine settings; Time Machine does not normally back up ~/Library, the folder that contains the iTunes ipsw files.
Fortunately, I had several resources. First, because I had jailbroken my phone and registered my device signature with Jay Freeman's caching service, I knew I could downgrade my phone. As Jay and I discussed in this LiveChat from a few months back, Apple no longer allows you to freely downgrade your iPhone software. All firmware installations must be verified with Apple's signature servers.
By jailbreaking your phone and registering your device signature with Jay's system, you'll be able to bypass Apple's verification system and return to the firmware you prefer -- or at least to the earliest firmware whose signature you have stored on the caching site. To make this happen, you must both register your device and update your /etc/hosts file. Jay's site has complete instructions on how to comply.
Second, I could grab a copy of old firmware from sites like Felix Bruns' http://www.felixbruns.de/iPod/firmware/ and iClarified's http://www.iclarified.com/entry/index.php?enid=750. These sites provide Apple download links for old firmware releases. I downloaded a fresh copy of the 3.1.2 ipsw (iPhone software archive) and installed it onto my system. Using a standard option-restore trick, I was able to put that firmware onto my iPhone. iTunes verified the upgrade with Jay's server and installed it onto the device.
Note: If you receive the "The iPhone could not be restored. An unknown error occurred (3004)." error, make sure to quit iTunes and flush caches at the command line:
sudo dscacheutil -flushcache.
If your device updates properly, you will receive a 1015 error and your unit will now enter a semi-permanent recovery mode, the mode in which your device shows an iTunes logo and will not boot further. To proceed, you'll need to use iRecovery. Download a copy from this site. (It requires libusb, so read the entire post before running.) Run iRecovery from the command line and supply the -s flag. Wait for the "]" prompt, and do not type anything until you see that prompt appear.
Enter the following commands:
] setenv auto-boot true
After, you will return to the command line. Reboot your phone by pressing the home and sleep buttons for 10 seconds, per the instructions on the site, and your iPhone should boot back to standard 3.1.2.
Note: Be aware that this method does not downgrade your baseband. It remains at the 3.1.3 setting.
Thanks Jay Freeman, Sjoerd (aka WiFone), and Paul "PhoenixDev" Griffin