How does Linux emulator in Javascript by Fabrice Bellard work?
At first, I also thought this is just a terminal emulator connecting you to a VM but it isn't. If you watch the network connections, you can see that, after bootup, no data is transmitted anymore.
So it's real.
A CPU is not something magic; in fact all it does is read bytes from memory and modify the RAM in accordance to what the commands mean.
In this case, the CPU emulator is based on the qemu code. What he does is he creates an array of functions where the index is the next byte at the PC (program counter).
Now all you need is a simple linux distribution that doesn't need any exotic CPU commands like floating point arithmetic or MMX code and voila.
What's interesting is the speed of the beast. The whole thing is a bit sluggish but then, it's JavaScript in a browser.
Conclusion: Impressive. Can't wait to see a C64 emulator :-)
What tricks did Fabrice Bellard use to make his PC emulator in Javascript so fast?
I believe that sharing some general credit with "speed" of the modern JS interpreter is a far way an offtopic in the list of Bellard's techniques (since he does not replace browser's engine). What are his optimization techniques? is a great question and I would like to get a more detailed record on it.
The points I can name so far
- (Optional) JS Typed arrays exclude unnecessary memory allocation dynamics (resizing). Fixed type (size) allows to allocate contiguous blocks of memory (with no variable-length elements' segments in such blocks) and uniformly address elements of a single type.
- Fast boot by a custom minimalistic booter (see linuxstart code published by Fabrice, also see his project called TCCBOOT http://bellard.org/tcc/tccboot.html)
- Optimized uncompressed embedded kernel (See the kernel configuration, it is extra tiny and optimized for small "linuxes").
- Minimal number of devices (Devices are super standard and easy to recognize by the kernel. So far, I have properly studied serial device but the rest benefits from similar properties). Ramdisk initialization is rather slow though.
- Small (2048 blocks) uncompressed root.bin ext2 system. The root system consists of minimal combination (rootfs, proc, tmpfs, devpts). No swap.
- (Unsure) he has patched the buffer size for ttyS0 (serial port device, or actually the kernel UART driver - to be precise) which communicates to terminal. Communication is in any way buffered using his term.js binding (I have found no transmit buffer in UART itself). Note that emulation (as in this case) can be much faster than the real thing.
Please also mind the browser cache while refreshing the page. It kicks very fast if its all in memory (optimized by the host OS). Performing direct (if cached - in-memory) copying (with load_binary()) of "uncompressed" binary segments (start_linux.bin, vmlinux26.bin, root.bin). No hard disk I/O limitations.
Simulating linux terminal in browser
The full linux is http://docker.io, the rest is https://github.com/Runnable/dockworker
We're not simulating the terminal but as Kyle says, replicating the terminal over websockets (with an ajax fallback).
In the browser we're using https://github.com/chjj/term.js which was derived from Fabrice Bellard's emulator. It handles the output, and also the keystroke capture.
Is there any website having command line environment of Linux, for practicing commands?
There is a quite a good one here:
Javascript PC Emulator - http://bellard.org/jslinux/
Related:
- How does Linux emulator in Javascript by Fabrice Bellard work?
- Simulating linux terminal in browser
Simplest possible architecture that can be virtualized and run the Linux kernel
Simplest possible architecture will be from point-of-view of ease of implementation. Since you are building an emulator that fully emulates the machine, whichever has simplest Instruction Set Design/Architecture will be suitable. RISC architectures no doubt are better. But choosing an architecture that is not widely used is also not good, if you need support few would be able to help you. Writing a simulator is no piece of cake. I would say either go for ARM or MIPS, both are popular:
- ARM Instruction Set
- MIPS Instruction Set
Also you must know that Fabrice Bellard's javascript virtual machine uses 32-bit x86 compatible CPU, something which is supported by Linux natively. You would have to port linux kernel (use toolchains) for ARM or MIPS yourself. See links on how to use the linux kernel
For MIPS :
- http://www.linux-mips.org/wiki/Main_Page
- Porting Linux kernel 2.6 to new MIPS board
- http://developer.mips.com/linux/
For ARM :
- http://www.arm.com/community/software-enablement/linux.php
- http://www.arm.linux.org.uk/docs/kerncomp.php
Related Topics
How to Listen/Detect Changes to an Input Value - When the Input Value Is Changed via JavaScript
What Is a Text Node, Its Uses? //Document.Createtextnode()
How to Select All Text in Contenteditable Div
How to Set Textarea Scroll Bar to Bottom as a Default
How to Open a File Browser with Default Directory in JavaScript
How Does Github Change the Url But Not the Reload
Adding Images to an HTML Document with JavaScript
Ios8 Safari After a Pushstate the :Nth-Child() Selectors Not Works
How to Tell When a CSS Background Image Has Loaded? Is an Event Fired
Transitionend Event Fires Twice
Getcomputedstyle (Or) $.Css(Map) <-- to Get Every Style Declaration
Smoothly Stop CSS Keyframe Animation
How Does Linux Emulator in JavaScript by Fabrice Bellard Work
Passing Parameters to JavaScript Files
Why Doesn't JavaScript Support Multithreading
Putting Datepicker() on Dynamically Created Elements - Jquery/Jqueryui
How to Make a Function Wait Until a Callback Has Been Called Using Node.Js