Ramblings of a Tampa engineer

In November of this year (2021) we will hit 20 years since the release of the original Xbox. This console was full of vulnerabilities (or misconfiguration) from the software to the hardware and with such a low price point two decades ago for a computer - it was highly popular. For this post we are going to go into a lot of details regarding one mistake Microsoft made which was the A20.

All the discoveries and research belongs to The Xbox Linux Project and Michael Steil. Research was obtained between personal memory of the era, a talk and a paper from Steil who was known in the scene as mist.

Intel 8088 (1978) - Credit - CPUShack

So lets start with some history with some real old CPUs starting with the Intel 8088, which thanks to the CPUShack reminds us it started production in 1978 and lasted till 1998. This CPU had 20 physical address lines labeled A0 through A19 and each line represents a simple binary (0/1) so you can store 220 bytes or 1 MB of information.

A rough drawing of address lines to RAM (A0-A19) on an Intel 8088

However, the 4 registers (code segment - CS, data segment - DS, stack segment - SS and extra segment - ES) only had 16 bits. So some form of translation needed to occur to map 16 bit registers to physical address space of 20 bits. This is where the small calculation came to be: segment (shifted 4 bits) + offset = address.

Internal Address -> Physical Address

So I wrote up a quick example to show how addresses translate into a physical address. Since we are shifting 4 bits, we can easily do 24 (2*2*2*2) and get 16 decimal or 0x10 hex to multiple the address by.

The thing about this notation is you can represent physical addresses with so many possible internal address + offset pairs. So knowing the early Intel 8088 only had 1MB what would happen if you asked for the memory at segment - 0xF800, with offset 0x8000. I'll save the long math and just say you'll get the physical address at 0x00100000 which is over the limit of a 20 bit address. The last real value would be at location 0x000FFFFF, so the older generation CPUs just dropped any bit above the 20th.

So taking 0x00100000 would require a 21st bit, which doesn't exist on the Intel 8088 thus it gets dropped which ends up changing the location to 0x00000000. This is known commonly as a "wraparound" because the location wraps back around to the beginning (or end) depending on how you are reading the memory.

So the story gets interesting when you look at the history as a whole. For example, take the Intel 80286 which still rocked a 16 bit processor, but had 16 MB instead of 1 MB memory. This meant it had 24 address lines instead of 20, which wouldn't mean much except for when IBM started building the PC/AT (1984). The machine had additional memory, but broke compatibility with previous solutions that depended on the implicit "wraparound" that occurred when requesting memory outside the limitation of the address lines.

If you had trouble visualizing that, the image above should show the 20 address lines on the 8088, as well as laying the additional 4 address lines that the 80286 had above. So you can see it was not possible to represent a 21 digit binary number with only 20 lines.

So IBM probably panicked at this point - they can't swap microprocessors at this point, so they tweaked the motherboard by placing a gate on the A20 address line. So depending on signal given to the gate it could be thrown to 0, thus effectively mimicking the behavior of the older Intel 8088 if warranted. This could effectively swap the system between legacy behavior or the new.

I've attempted to build an over simplified drawing to depict this, since the image above incorrectly assumes the gate exists at the CPU level, when in 1984 it did not.

Another rough drawing of the IBM PC/AT

So I think you can see where this is going now. This feature which IBM started eventually moved into the CPU and started being included in a few of the later CPUs including the Pentium series.

The lucky original Xbox was packing a 32 bit 733 MHz Intel Pentium III processor, which indeed had this A20# Gate. So knowing the Xbox boots up (after some initialization) at 0xFFFFFFF0, if we ground the A20 line - the Xbox will instead boot at 0xFFEFFFF0. So once again another quick and dirty drawing to explain how this will affect the process.

A partial memory map of the original Xbox

So you can see a normal Xbox boots into the secure state of the ROM. This is the portion that sets up enough critical information to verify and run the 2nd boot-loader (2BL) which then proceeds to also verify and prepare the kernel. However, grounding the A20 line proceeds to boot the Xbox directly into flash.

This is not good for Microsoft from a security perspective. The system can now boot from flash with whatever was cleverly placed there. An added bonus that booting with the A20 line grounded keeps the secret ROM still on. So a small application written and placed into flash can be used to simply dump the secret ROM.

Listening to the talk by Michael Steil, he hinted that the Xbox Linux team kept this knowledge close to heart, but easily would have communicated it to the Xbox team had Microsoft wanted to communicate with the group.

With the 20 year anniversary nearing for the original Xbox - a few more deep dives into the past to come.

You’ve successfully subscribed to Connor Tumbleson
Welcome back! You’ve successfully signed in.
Great! You’ve successfully signed up.
Success! Your email is updated.
Your link has expired
Success! Check your email for magic link to sign-in.