: 29676
WebLinux
Linux live on the web!
Darkroses blog
I told you we weren't dead!
By: darkrose
It's been a while, I know, but amongst other projects (http://sandbox.ltmnet.com) I have been working on WebLinuxy related things too.

Specifically a hardware platform on which to build the system. What we have is a virtual hardware interface on top of javascript, essentially enabling full multi-tasking/multi-threading.
The system is inspired by the x86 architecture, but is by no means an emulator for that architecture. It uses an x86 style cpu, memory, and interrupt architecture to enable the additional functionality.

Here's a simple hello world to demonstrate what an application looks like written in JSASM:

{
data:{
0:0, // self pointer
1:0 // we'll put a pointer to the vga bios here
},
global:{
start:0 // instruction pointer for 'start' procedure
},
text:{
0:function(){cpu.vars.ds[1] = ram.read(2);}, //create a pointer to the vga bios at ds:1
1:function(){cpu.vars.ds[1].clearScreen();}, //clear the screen
2:function(){cpu.vars.ds[1].write('Hello World!
');}, //write to the screen
3:function(){asm.hlt()} // halt the cpu
},
stack:[]
}

Note this is written for 'real mode'... we're not in a kernel. As a further example, here's the actual bios code used:

{
data:{
0:0,
1:NULL
},
global:{
start:0,
halt:10,
logo:20,
cpu:40,
hdd:50,
seek:70,
load:100
},
text:{
/* start */ 0 :function(){cpu.vars.ds[1] = ram.read(2)},
1 :function(){cpu.vars.ds[1].clearScreen()},
2 :function(){asm.call('logo');},
3 :function(){asm.int(32);}, // trigger a timer interrupt to ensure screen is refreshed
4 :function(){asm.cli();}, // before masking interrupts
5 :function(){asm.call('cpu');},
6 :function(){asm.sti();}, // unmask interrupts
7 :function(){asm.call('hdd');},
8 :function(){asm.call('seek');},
9 :function(){asm.call('load');},

/* halt */ 10:function(){cpu.vars.ds[1].write('halting');},
11:function(){cpu.halt();},

/* logo */ 20:function(){cpu.vars.ds[1].write("MTN Initialised
");},
21:function(){cpu.vars.ds[1].setBg(10)},
22:function(){cpu.vars.ds[1].drawString(' ',65,1)},
23:function(){cpu.vars.ds[1].drawString(' ',63,2)},
24:function(){cpu.vars.ds[1].drawString(' ',61,3)},
25:function(){cpu.vars.ds[1].drawString(' ',59,4)},
26:function(){cpu.vars.ds[1].setBg(0)},
27:function(){cpu.vars.ds[1].setFg(10)},
28:function(){cpu.vars.ds[1].drawString(' WebLinux ',61,4)},
29:function(){cpu.vars.ds[1].setBg(10)},
30:function(){cpu.vars.ds[1].setFg(15)},
31:function(){cpu.vars.ds[1].drawString(' ',71,4)},
32:function(){cpu.vars.ds[1].drawString(' ',61,5)},
33:function(){cpu.vars.ds[1].drawString(' ',63,6)},
34:function(){cpu.vars.ds[1].drawString(' ',65,7)},
35:function(){cpu.vars.ds[1].setBg(0)},
36:function(){cpu.vars.ds[1].setFg(10)},
37:function(){cpu.vars.ds[1].drawString('MTN BIOS 0.2',60,9)},
38:function(){cpu.vars.ds[1].setFg(15)},
39:function(){asm.ret()},

/* cpu */ 40:function(){asm.cmp(0,cpu.hz);},
41:function(){asm.tru(40);},
42:function(){cpu.vars.ds[2] = Math.round(cpu.hz/1000)},
42:function(){cpu.vars.ds[1].write('CPU cycling at: ');},
43:function(){cpu.vars.ds[1].write(''+Math.round(cpu.hz/1000));},
44:function(){cpu.vars.ds[1].write('Mhz
');},
45:function(){asm.ret();},

/* hdd */ 50:function(){cpu.vars.ds[1].write('Detecting Hard Drives
');},
51:function(){asm.mov('ebx',0);},
52:function(){asm.mov('ecx',0);},
53:function(){asm.inc('ebx');},
54:function(){asm.outb(500,cpu.vars.ebx);},
55:function(){asm.inb(500,'eax');},
56:function(){asm.cmp(cpu.vars.eax,1);},
57:function(){asm.fal(60);},
58:function(){asm.inc('ecx');},
59:function(){asm.jmp(53);},
60:function(){asm.cmp(cpu.vars.ecx,0);},
61:function(){asm.fal(64);},
62:function(){cpu.vars.ds[1].write('No Hard Drives Found
');},
63:function(){asm.jmp(65);},
64:function(){cpu.vars.ds[1].write(cpu.vars.ecx+' Hard Drives Found
')},
65:function(){cpu.vars.ds[2] = cpu.vars.ecx},
66:function(){asm.ret();},

/* seek */ 70:function(){cpu.vars.ds[1].write('
Seeking bootable media...
');},
71:function(){asm.cmp(cpu.vars.ds[2],0);},
72:function(){asm.tru(91);},
73:function(){asm.outb(500,1);},
74:function(){asm.inb(500,'eax');},
75:function(){asm.cmp(cpu.vars.eax,0);},
76:function(){asm.tru(91);},
77:function(){asm.outb(498,0);},
78:function(){asm.outb(499,506);},
79:function(){asm.inb(496,'ebx');},
80:function(){asm.cmp(cpu.vars.ebx.substr(0,6),'0xAA55');},
81:function(){asm.fal(91);},
82:function(){asm.outb(499,0);},
83:function(){asm.inb(496,10);},
84:function(){asm.outb(499,256);},
85:function(){asm.inb(496,11);},
86:function(){asm.cat(10,11);},
87:function(){asm.sub(10,506);},
88:function(){cpu.vars.ds[1].write('Operating System Found
');},
89:function(){cpu.vars.ds[3] = 1;},
90:function(){asm.ret();},
91:function(){cpu.vars.ds[1].clearScreen();},
92:function(){cpu.vars.ds[1].write('Operating System Not Found');},
93:function(){cpu.vars.ds[3] = 0;},
94:function(){asm.call('halt');},

/* load */ 100:function(){cpu.vars.ds[1].write('Loading...
');},
101:function(){ram.markx(10);},
102:function(){asm.fal(104);},
103:function(){asm.mov('eax',0);},
104:function(){asm.hlt();},
105:function(){asm.inc('eax');},
106:function(){asm.cmp(cpu.vars.eax,4);},
107:function(){asm.fal(104);},
108:function(){cpu.align(10);},
109:function(){cpu.vars.ds[1].write('Boot Segment Corruption
')},
110:function(){asm.call('halt')},
111:function(){asm.ret();}
},
stack:[]
}

It's a little messy at the moment, and it doesn't actually initialise the vga bios, or memory, or any of that - that's done with native javascript before this is called - but it does let you know the cpu speed, detects hard drives, reads the Master Boot Record, Loads that data, marks it as executable, and executes the Bootloader... which in this case is just a hello world type of thing.

It's only been tested in firefox 3.5/3.6 so far... so let me know if you try it in another browser.

Also there's no source release yet, as I wanna tidy the code up a bit before I let anyone look at it :)

The test build can be found here or by clicking on 'Try the development snapshot' on the home page.
There are no comments for this blog entry.