Search My Blog

Tuesday, May 17, 2011

JavaScript emulator lets Linux run in a browser tab – Computer Chips & Hardware Technology |

JavaScript emulator lets Linux run in a browser tab

May. 17, 2011 (9:32 am) By: Matthew Humphries

The name Fabrice Bellard may not be recognizable to a lot of people, but the work he carries out as a programmer and computer scientist is. He is the man behind the LZEXE compression engine, FFmpeg audio and video converter, the QEMU emulator and virtualizor, and he also held the World Record for the computation of PI to 2,700 billion digits in 2009.

He is a very talented programmer, and his latest project demonstrates once again just how talented he is. Using the super-fast JavaScript engines that now come as standard in popular web browsers, he has managed to create a PC emulator that runs in a browser. As a demonstration he has posted a link to a version of the Linux kernel running in such a scenario.

Bellard wrote the entire emulator in JavaScript and says it runs fine in both Firefox 4 and Google Chrome 11. As it's in a browser it automatically becomes platform independent meaning whatever platform your browser runs on, the emulator will work.


Javascript PC Emulator - Technical Notes

By Fabrice Bellard - May 14, 2011

This PC emulator is written in Javascript. The emulated hardware consists in:

  • a 32 bit x86 compatible CPU
  • a 8259 Programmble Interrupt Controller
  • a 8254 Programmble Interrupt Timer
  • a 16450 UART.
The code is written in pure Javascript using Typed Arrays which are available in recent browsers. It was tested with Firefox 4 and Google Chrome 11 on Linux, Window and Mac (it does not work with Chrome 12 beta. As far as I know, it is a bug in the browser). 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:
  2. 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).
  3. No CS/DS/ES/SS segment overrides. FS/GS overrides are implemented because they are needed for Thread Local Storage in Linux.
  4. A few seldom used instructions are missing (BCD operations, BOUND, ...).
  5. No single-stepping
  6. No real mode
  7. No 16 bit protected mode (although most 16 bit instructions are present because they are needed to run 32 bit programs).
Most of these restrictions are easy to remove, but I decided to implement the strict minimum to be able to use a recent Linux kernel and its user applications.

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.


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.

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 configuration is here and there is a small optional patch to avoid outputting warnings due to the slow serial port. An uncompressed kernel image is used instead of a compressed one to have a faster boot. It is generated with "objcopy -O binary vmlinux vmlinux.bin".

The disk image is just a ram disk image loaded at boot time. It contains a filesystem generated with Buildroot containing BusyBox. I added my toy C compiler TinyCC and my unfinished but usable emacs clone QEmacs.


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 about 2 times 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.
  • 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]

Go there...

Fabrice Bellard's Web Site...


BusyBox - The Swiss Army Knife of Embedded Linux


 busybox <applet> [arguments...]  # or
 <applet> [arguments...]          # if symlinked


BusyBox combines tiny versions of many common UNIX utilities into a single small executable. It provides minimalist replacements for most of the utilities you usually find in GNU coreutils, util-linux, etc. The utilities in BusyBox generally have fewer options than their full-featured GNU cousins; however, the options that are included provide the expected functionality and behave very much like their GNU counterparts.

Read More and see a list of Terminal Commands...

I tried it out in my Firefox 3.6.17, but it needs Firefox 4. So, then I tried ny Google Chrome 11.0.696.68. And it Booted up in a Flash!:) Go here to Boot it up in your Web Browser...

I tried out a few Linux commands that I know. But, yum and apt nor any networking is installed (like the article said about networking). So, I played around with a bunch of commands from It's pretty cool, seeing a running Linux OS in a Web Browser. But, being a GUI Linux User... there was nothing that I could really use it for. But, I bet there are many things that can be done with this Web Browser OS, when more features are added...


JavaScript emulator lets Linux run in a browser tab
JavaScript emulator lets Linux run in a browser tab – Computer Chips & Hardware Technology |
Fabrice Bellard's Home Page
Javascript PC Emulator - Technical Notes
LZEXE Home Page
About - QEMU
Pi Computation Record
Old projects
Javascript PC Emulator
TCC : Tiny C Compiler
QEmacs Editor
BusyBox - The Swiss Army Knife of Embedded Linux

No comments: