Tuesday, 19 July 2016

Upgrading WiFi on a Lenovo Ideapad Y500

I have been the happy owner of a Lenovo Ideapad Y500 laptop for a few years now. Recently I noticed that 5 GHz dual band WiFi cards are getting really cheap on eBay. Because my laptop only had a 2.4 GHz WiFi adaptor, and there are about 40 neighbours competing for a 2.4 GHz signal in my living room, I figured the time had come to get a new WiFi card.

While Lenovo uses standard mini-PCIe WiFi adaptors in this laptop, they combine it with a thing called a whitelist, apparently to prevent me as a so-far happy owner from turning this laptop into an illegal radio device. Unfortunately this would also force me to only use the hard-to-get Lenovo-approved WiFi cards, instead of better and much cheaper alternatives. But fortunately the whitelist is stored in the BIOS of the laptop, and the BIOS is stored in a flash chip. So in principle, I could change it.

A quick search across the Internet found an extensive community of people dealing with the whitelist phenomenon. There even was a hint of a tool to automatically patch a BIOS dump and generate a new version ready for flashing. But to make things more interesting, after googling every relevant term I could think of, I had to accept that it was not available as an easy download for me. My next plan was to get a dump of the BIOS and patch that myself to make it behave. 

Conceptually, this whitelist-thing can be fixed in two ways: make the computer ignore it, or put my new WiFi card on the list. As these things go, the former is the nicest and the latter the easiest. Removing the whitelist would need figuring out where the code sits that checks hardware against the whitelist and bypass it. This would have taken some serious effort with IDA, which I hadn't touched for years.  Changing the whitelist itself is potentially easier, assuming that the check is done against PCI IDs. But my Internet search had already turned up that this was the case, so in principle an s/APPROVED_ID/MY_ID/ would be all that was needed.

Getting the BIOS dump itself was straightforward using something called fpt.exe in FreeDOS. Unfortunately, since the 80s, BIOSes are compressed and checksummed and whatnot, so a tool is needed to deal with this before modifications can be made. The good news here is that such a tool exists: PhoenixTool.exe a.k.a. Andy's tool. The less good news: it errors out under wine, so we need a real Windows. The only copy of Windows in my house spends its marginal existence on a small part of the harddisk of the Lenovo laptop, only to be woken in cases of need like this one.

After an hour of overdue updating Windows, I downloaded PhoenixTool. Using it I managed to extract a MOD (essentially a BIOS section) file that contained the whitelist. After matching a list of Lenovo-approved cards and their PCI IDs against the bytes in the file, I knew what to change and where. 

After a few weeks of waiting, the new WiFi card fell on my doormat, fresh from China. I inserted the card in a mini-PCIe  to PCIe converter, put that in my desktop computer and used lspci to get the PCI IDs of the new card. Both the system and subsystem IDs were needed.

lspci data of the new WiFi card: ID=8086:08b1/8086:4160.

Using Jeex, I patched the IDs of a card that I do not own with the new one in the whitelist. I left in the ID of card that came with the laptop alone, just in case. Then back to Windows and PhoenixTool to replace the original mod with the hopefully improved one. After the replacement step, PhoenixTool had made a backup of my original BIOS file ("biosback.bin.old") and had minted a new "biosback.bin". 

Flashing the new BIOS proved tricky, as some kind of flash write protection was enabled and fpt.exe failed to update my new BIOS. The solution was using "prr.exe" that removed the protection. The next fpt run reported everything a-ok, so I hit the power button to switch off (FreeDOS, remember).

After restarting the laptop I went from a feeling of enthusiasm and suspense, via mild alarm, to full panic within a time span of about ten seconds. After the initial boot, the keyboard backlight switched off, the screen stayed blank and the fan started spinning at full speed. The only response of the laptop was a shrill beep when I removed the power plug, and the same beep when I put it back in. Bricked as it is called.

Some searching revealed that these laptops have a recovery mode ("Hurray"). The procedure to follow here is to remove the battery, unplug the power brick, insert an USB stick with a replacement BIOS image, press and hold a magic key combination, plug in the power brick, press the power button and only release the magic keys after 6 seconds or so. Important additional information here is what key combination, and what to name the replacement BIOS image. Searching the Internet revealed that the most likely  key-combo for a Lenovo ideapad laptop would be Fn+R. The name of the BIOS image was a bit more tricky. 

When loading the BIOS image in PhoenixTool before, a dialog box popped up stating something about recovery. At the time I did not know nor care, so I just clicked it away. As it turned out, this was crucial information for recovering from a bad flash: it was the name of the recovery BIOS image file! Now please remember that this laptop was the only computer capable of running windows in my house, so I had no way to run PhoenixTool.

Fortunately I am often a bit stupid, but I do have my moments. Before flashing the BIOS, I had copied all files related to this adventure to another system. And one of these was a log-file generated by the PhoenixTool. Somewhere in there it stated "Recovery Filenames are: QIWY3.bi?". Yoohooo!

So I got an official Lenovo BIOS update file for this laptop, I managed to extract a rom-file from the .exe, put it on a FAT-formatted USB stick as qiwy3.bin, plugged the stick in the laptop, and followed the recovery procedure. And oh joy, the light on the USB stick flashed, there was a pause, and then a series of long flashes, consistent with reading a large file from the stick. After that there was a few seconds pause, and the laptop rebooted..... And it was still stuck. I gave it one more try and got the same results. Time to think things through.

By now, I knew I could start the recovery, that the USB stick was recognised, and that the BIOS image file was read (most likely). So the observed behaviour was consistent with an invalid BIOS image. After reading, it would be checksummed or otherwise verified (the few seconds pause), it would be rejected, and the flashing code would reboot the laptop.

So another BIOS image was needed. But the one I tried was from the manufacturer's website, and I had no way to get something else. Except for the original BIOS image that I started with, that is. So I tried that one, and... success! I had a working laptop again. And, for future experiments, I had a proven method to recover from a bad flash. So all in all this counted as a victory of sorts.

The next step was to figure out what went wrong with patching my BIOS. More searching on the Internet was sometimes confusing (for example: "Never start from a BIOS dump" according to one expert, "Start from a BIOS dump" according to another). But it turned out that my approach of editing mod files was somehow wrong. The proven way to make the modifications was to have PhoenixTool split the BIOS image into ROM-files, modify these, and let it reassemble the BIOS again from the ROM files. 

Once I figured this out, everything went smooth. I found the ROM file to patch, made the change, let PhoenixTool reassemble the BIOS, flashed it, and everything worked as it should. The new WiFi card reaches 300 MBps at 5GHz, and even gets better speeds than the original card in the 2.4GHz band. And I got this nice experience to share with you on this blog.

So in the end, I consider this a success...

(I am thinking about adding Tux as a boot logo, but for now I decided to keep things as they are.)