Operating system retrofit: How Windows XP comes to the i486

Windows XP is long outdated, and Intel’s 80486 (or i486 for short) – at least as a processor for PCs – is even longer outdated. Microsoft was of this opinion back in 2001, when Windows XP was released, and demanded at least a Pentium. But some enthusiasts did not want to accept this, and a few years ago there was already a first attemptto get Windows XP running on an i486. But that didn’t seem to work. A hobbyist from Germany has now managed to adapt it. We’ll explain the details.








In a forum the user Dietmar documented his work and discussed it with other users. In total, the discussion extends over 20 pages, but the actual problem is quickly described: Windows XP uses the assembler command CMPXCHG8Bthe Intel only introduced with Pentium. Although both the i486 and the Pentium are 32-bit processors, CMPXCHG8B with 64-bit values.

The instruction is an atomic operation that summarizes a relatively complex behavior in one processor instruction. CMPXCHG8B reads a 64-bit value from memory and compares it with the contents of two registers. If the two values ​​match, the contents of two other registers are written to the memory address; if not, the contents of the two registers with the comparison value are overwritten with the value from memory. All atomic operations work according to this pattern.

Complex command prevents chaos

Atomic operations are used to coordinate multiple threads running programs at the same time. Sometimes these different programs need to modify the same area of ​​memory. Atomic operations prevent one thread from modifying a value while another is also working with it.




This is necessary even with only one processor core, because the operating system assigns it to the individual threads for a certain time. When the time has expired, it takes the processor away from the thread again – the so-called preemptive multitaskingIf the functionality of an atomic operation were composed of individual instructions, the following situation could arise: Thread A first carries out the comparison. It comes to the conclusion that it can overwrite the memory location, but is then interrupted and Thread B changes the value. If Thread A continues working, it is working with outdated data.

In the forum you can find example code from several kernel functions for working with linked lists: ExInterlockedFlushSList marks a list as empty. Its data structure consists of a 32-bit pointer to the first element and a 16-bit value for the number of elements in the list. The other 16 bits do not seem to be allowed to be changed. When emptying, it is important that the pointer and the number of elements are set to 0 in one step – for this, CMPXCHG8B used.

However, the command can be replaced, and that is exactly what Dietmar did.


source site