Lenovo x230 keyboard and bios pause

This will be fun. I will test the keyboards with a multimeter and several things will be posted but this might not end well for the x230. I am even thinking on buying a second hand x220 to hack a x230.

I’ve seen many things about UEFI, SMM and bizarre hacks and they make me feel nostalgic and happy at the same time. I don’t particularly care about security and I think it is a waste of time like solving puzzles but I like solving puzzles.

I can not even follow the ultra detailed posts by Dmytro Oleksiuk now but I am enjoying them and since I have not the required knodledge to continue this at a decent speed and it is interesting, I will learn.


PD: I could just go to coreboot sources and start from there but I am enjoying this.

Lenovo X230 and Lenovo X220 keyboard bios hack part 3

I Downloaded G2ET95WW, G2ET96WW and G2ET94WW Lenovo Bioses for the x230.They all have changes on the BIOS but no changes on the Embedded Controller firmware.

They’ve two important files $01D3000.FL1 and $01D3000.FL2 (and several files from 306a4.HSH to 306a9.HSH

I’ve no idea what they do yet. I’ve seen that the file $01D3000.FL2 is the same for all of them so the code for the embedded controller has to be there. It seems it is there with other stuff so I downloaded a BIOS unpacker to see if I was lucky.

I downloaded Phoenix Bios Editor but it was not able to open the file. It said “Invalid ROM lenght!

There are many underground bios related pages on the web but the most friendly site is bios-mods. So I choose that one to begin with.

Then I realized that what others at bios-mods were using was Phonenixtool 1.90 for Lenovos so I downloaded Andy’s Phoenixtool256 and this one was able to generate a SLIC.LOG and create a folder named DUMP with lots of files.

Maybe the extractor didn’t even touch the embedded controller but now I’ve to look what do I have.




I found those two threads at bios-mods interesting:


UPDATE: My reasoning might have been wrong.
If what coreboot said regarding the bios placement is true the .FL2 file might have nothing to do with the Embedded Controller after all. I’ll check it later. I have no time until this afternoon.

“X230 has 2 flash chips of 8M and 4M. They’re concatenated to one virtual flash chip of 12M which is itself subdivided in roughly in 3 parts:
Descriptor (12K)
ME firmware (5M-12K)
System flash (7M)”

I guess I’ll have to look at the embedded controller datasheet and the x230 schematics first. Well, it is going to be slow. At least I am enjoying the quest but I would prefer to have the keyboard working.

Coreboot doesn’t even list this embedded controller yet. I’ll update the page once I have more info but I already have a bit more here about it than in the coreboot web page.

MAC addresses and the Normerell conspiracy

Some companies try to generate random MAC addresses on uboot without even having an official oui address space. Then most of the times they find the entropy is very low.

Usually a board device ID can be used in those cases (the flash or eeprom serial number). And in the worst cases some companies (specially Chinese ones, I found several) use MAC address-es belonging to Normerell, a French company that went backrupt and didn’t give back their address space.

echo 00:00:11:`od /dev/urandom -w3 -tx1 -An | head -n 1 | sed -e 's/ //' -e 's/ /:/g'`



The official MAC address ranges can be looked at here:


What most people seem to forget (or don’t know) is that you can use perfectly legal private MAC address ranges and even U-boot comes with a simple generator for them.


“Universally administered and locally administered addresses are distinguished by setting the second-least-significant bit of the most significant byte of the address. This bit is also referred to as the U/L bit, short for Universal/Local, which identifies how the address is administered. If the bit is 0, the address is universally administered. If it is 1, the address is locally administered. In the example address 06-00-00-00-00-00 the most significant byte is 06 (hex), the binary form of which is 00000110, where the second-least-significant bit is 1. Therefore, it is a locally administered address.”

private mac address
Practical uses:

~/U-Boot/tools $ cat gen_eth_addr.c
/* (C) Copyright 2001
* Murray Jensen
GPLv2 bla bla bla...
#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "time.h"

main(int argc, char *argv[])
unsigned long ethaddr_low, ethaddr_high;

srandom(time(0) | getpid());

* setting the 2nd LSB in the most significant byte of
* the address makes it a locally administered ethernet
* address
ethaddr_high = (random() & 0xfeff) | 0x0200;
ethaddr_low = random();

ethaddr_high >> 8, ethaddr_high & 0xff,
ethaddr_low >> 24, (ethaddr_low >> 16) & 0xff,
(ethaddr_low >> 8) & 0xff, ethaddr_low & 0xff);

return (0);

Still people make the same mistakes again and again…
The Uboot community was always against it but even big companies like Marvel choose to do it their way (getting pseudo aleatory numbers from undocumented registers).



mkdir mi_marvell

git clone git://git.marvell.com/u-boot-kw.git/

mi_marvell/u-boot-kw/drivers/net $ vim kirkwood_egiga.c

while (!eth_getenv_enetaddr(s, dev->enetaddr)) {
/* Generate Ramdom MAC addresses if not set */
sprintf(buf, “00:50:43:%02x:%02x:%02x”,
get_random_hex(), get_random_hex(),
setenv(s, buf);

commit 4efb77d41f9c5d93f0f92dda60e742
Author: Prafulla Wadaskar
Date: Sat Jun 20 11:01:53 2009 +0200


soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are reserved regs and
* Does not have names at this moment (no errata available)

* Generates Ramdom hex number reading some time varient system registers
* and using md5 algorithm
unsigned char get_random_hex(void)
int i;
u32 inbuf[BUFLEN];
u8 outbuf[BUFLEN];

* in case of 88F6281/88F6192 A0,
* Bit7 need to reset to generate random values in KW_REG_UNDOC_0x1470
* Soc reg offsets KW_REG_UNDOC_0x1470 and KW_REG_UNDOC_0x1478 are reserved regs and
* Does not have names at this moment (no errata available)
writel(readl(KW_REG_UNDOC_0x1478) & ~(1 << 7), KW_REG_UNDOC_0x1478);
for (i = 0; i < BUFLEN; i++) {
inbuf[i] = readl(KW_REG_UNDOC_0x1470);
md5((u8 *) inbuf, (BUFLEN * sizeof(u32)), outbuf);
return outbuf[outbuf[7] % 0x0f];

Lenovo X220 and Lenovo X230 keyboard connector candidates – part 3

cucumber eyesI got an schematic in English/Chinese and it says the connector on the motherboard is a JAE-CONN40A-1-U1GP

but I have not found any other reference to it and it seems it cannot be bought alone (without a motherboard on ebay or similar)

If this schematic turns out to be true a lot of info can be obtained from it.


The internal name for the Lenovo x230 seems to be Dasher-2 and Winstron developed the schematics. They somehow got leaked.  I still wish I had a connector to map the keyboard table/keys without breaking it but I’ll manage somehow. With all the info available many things seem possible now.

Well, the internal name of the Lenovo x220 is Dasher-1 and the schematic is here:

It seems the x230 uses an 8051 and a x220 uses an H8S/2113 (page61) so it won’t be super easy to extract keyboard code tables from their embedded controller update blobs but I continue in my quest.

I had to share this. Searching for dasher-2 I found the next paper and anyone familiarized with Víktor Pelevin will find it amusing. Please give me another cucumber: https://www.lsuagcenter.com/NR/rdonlyres/9BD67509-BDB8-4E77-9A6F-E96F0A783DC5/81387/B844StakedCucumberProduction.pdf
…”In fall 1983, ‘Dasher II’ cucumber was planted in a randomized complete block ”