Javascript PC Emulator - Technical Notes
By Fabrice Bellard - May 23, 2011
This PC emulator is written in Javascript. The emulated hardware
consists in the following devices:
- 32 bit x86 compatible CPU
- 8259 Programmble Interrupt Controller
- 8254 Programmble Interrupt Timer
- 16450 UART
- Real Time Clock.
- IDE interface and hard disk.
The code is written in pure Javascript using
the W3C
Typed Arrays. A slightly slower fallback mode is implemented for
browsers missing this support. For the exact list of supported
browsers, see the FAQ. In any case, a fast
Javascript engine is needed to have good performance.
CPU Emulation
Some of the code is inspired from my x86 dynamic translator present
in QEMU, but there are important
differences because here it is an interpreter. The CPU is close to a
486 compatible x86 without FPU. The lack of FPU is not a problem when
running Linux as Operating System because it contains a FPU
emulator. In order to be able to run Linux, a complete MMU is
implemented. The exact restrictions of the emulated CPU are:
- No FPU/MMX/SSE
- No segment limit and right checks when accessing memory (Linux
does not rely on them for memory protection, so it is not an
issue. The x86 emulator of QEMU has the same restriction).
- No single-stepping
I added some tricks which are not present in QEMU to be more precise
when emulating unaligned load/stores at page boundaries. The
condition code emulation is also more efficient than the one in QEMU.
Devices
Currently there is no synchronization between the PIT frequency and
the real time, so there is a variable drift between the time returned
by Linux (try the "date" command) and the real time.
The UART (serial port) does not support FIFO mode. Perhaps it could
help to improve the display speed.
There is no network emulation at this point.
A clipboard device (seen as /dev/clipboard in the emulator)
was added to allow exchange of data between the emulator and the
outside world.
Javascript terminal
Although I could have reused the
excellent termlib, I
decided to write my own because I was curious to see how it could be
done. The main problem is the key handling which is different among
browsers and OSes, as
described here.
Linux distribution
I compiled a 2.6.20 Linux kernel (I guess any other version would work
provided there is still an FPU emulator). The Linux kernel
configuration, patch and the source code of the Linux starter (kind of
BIOS) are
available: linuxstart-20120111.tar.gz.
The disk image contains a filesystem generated
with Buildroot using
BusyBox. I added my toy C
compiler TinyCC and my unfinished
but usable emacs
clone QEmacs. There is also a
small MS-DOS .COM launcher I use to test the 16 bit emulation with a
tiny .COM program to compute pi and a
small self-assembling
assembler for MS-DOS.
Javascript
I happen to be interested by the implementation of Javascript engines
these days - but I don't know yet if I will write my own any time soon
! Anyway, this emulator was a way to learn how to write optimized code
for recent Javascript engines, in particular Jaeger Monkey (for
Firefox 4) and V8 (for Chrome).
A troubling thing is that the PC emulator is slower using V8 than
Jaeger Monkey (I used the 32 bit version for both). I have no precise
explanation yet because I only looked at the Jeager Monkey code so
far.
What's the use ?
I did it for fun, just because newer Javascript Engines are fast
enough to do complicated things. Real use could be:
- Benchmarking of Javascript engines (how much time takes your
Javascript engine to boot Linux ?). For this particular application,
efficient handling of 32 bit signed and unsigned integers and of typed
arrays is important.
- Learning to use command line Unix tools without leaving the browser.
- Client side processing using an x86 library, for example for
cryptographic purposes. For such application, the x86 emulator can be
modified to provide an API to load x86 dynamic libraries and to
provide
a js-ctypes
like API to call the C/C++ functions from javascript.
- A more advanced version would allow to use old DOS PC software
such as games.
[Back to the PC emulator]