Wednesday, February 25, 2009

Scheme VM like a microkernel service

Yes, it's an idea. I'm thinking about benefits in the microkernel and multiservice OS on desktop or some kind of development environment. Well, I know all the things that going in microkernel while you calling fork() after those exec() - it takes a lot of system time.
Usually within shell you makes fork()/exec() every time when you starts anything - ls,cat ... or you can wrong with some arguments for utility and this will increase system job time. Also, it's a waste of a time to implement small utils on C, there are few POSIX things, few useful things, few OS specific things and so on. Better one - run login/shell environment within VM context - like a thread, all utils will runs like a thread (thread creation in Jari OS isn't so wasteful) and writing simple things on scheme is a simple and fast process. It doesn't mean that Jari OS reject exec/fork and other POSIX calls, it's mean that we can take a benefits on desktop I think.
Many people told me that microkernel is sucks and microkernel is bad for desktop - well, most of them doesn't know anything about OS design, but others are right in some case. But I want to make some note - there are no existing microkernel (and multiservice) OSes with a pure microkernel and multiservers design (I don't take early, prototype-like, featureless systems, like Jari OS and some line of other interest projects, HelenOS for example) - yes it's a first thing to think that microkernel sucks, second it's a performance - yes context switching, calls partially going outside of the caller time slice and so on, it's not the problem as well, for most I/O operations context switch and related thing is very little compare to disk I/O or other I/O (no, I don't mean highband special devices), also most of technical microkernel critics based on existing solution - that can has ugly design (I don't want to make a shit showing examples here).
My thesis - Well designed and implemented microkernel and multiservice OS can works at the same speed as monolithic OS works, but ugly designed monolithic OS will be ran slowly then microkernel based OS with good design. Also, you should remember that some abstractions in monolith made within user space - like example GUIs, and I don't think that some operations will be slowly on microkernel.
And ... the main idea - for microkernel world you should keep in mind microkernel oriented solutions, instead of porting old and ugly tricks from monolithic - schemevm running as microkernel service is such solution.

Friday, November 21, 2008

Jari OS: device drivers development wellness

I have a lot of time spent with drivers development in different OSes/kernels. Generally it was microkernel or hybrid kernels and I cannot told that this process takes me into pleasure.
Jari OS on other side is a new microkernel OS that can takes in advance all my skills with system design.
Actually every Jari driver is a microkernel service working in userspace like a trusted task. All IO mechanics has a protocol and every time you need to support it with all changes. It's a bad, but for this case I've designed a generic device server layer that will hide all semantics within several library functions.
All of this located in system libraries - in LibOS part.
Include and you will have server implemented. Really is a generic layer - on top of this I will design and implement other layers - for console drivers, input drivers, block drivers and so on.
Like example of this I will show a code snippet of the generic VGA console driver uses this generic layer:


#include <sys/types.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <wchar.h>
#include <errno.h>
#include <time.h>
#include <datalib/usrtc.h>
#include <ns/ns.h>
#include <scheduler.h>
#include <proto/rpc.h>
#include <devio/devio.h>
#include <devio/server.h>
#include <termio/termio.h>

#include <termio/term.h>

#include "vga.h"
#include "hwops.h"

#define DRVNAME "vgacons.d"
#define DEVNAME "/console"

static size_t __vga_write(void *buf,uni_rpc_t rpc,size_t size,size_t offset);
static size_t __vga_read(void *buf,uni_rpc_t rpc,size_t size,size_t offset);
static int __vga_ioctl(void *buf,uni_rpc_t *rpc,size_t size);

struct device_ops dev_op = {
__vga_write,
__vga_read,
NULL,
__vga_ioctl,
__vga_write,
__vga_read,
NULL,
NULL,
};

int main(int argc,char **argv)
{
device_server_t *sys;
int r=0;
void *iobuf=mmap(NULL,4096,MMAP_RW|MMAP_PHYS,NOFD,(void*)VGA_TM_BASE);
char buff[256];

task_scheduler_control(getpid(),SYS_SCHED_CTL_SET_PRIORITY,30);

vga_init(iobuf);

vga_print("[vgacons] i've started\n");

sys=malloc(sizeof(*sys));
if(!sys)
abort();

r=init_device_server(sys,DIRECTIO_READ | DIRECTIO_WRITE | HW_READ | HW_WRITE,
2048,4096,512,1,DRVNAME,DEVNAME,&dev_op,4);

sprintf(buff,"sys->allowed = %p\n",sys->allowed);
vga_print(buff);

if(r!=0) {
sprintf(buff,"r=%d\n",r);
vga_print(buff);
abort();
}

vga_print("[vgacons] device server run\n");

device_server_start(sys);

vga_print("[vgacons] :((\n");

return 0;
}

static size_t __vga_write(void *buf,uni_rpc_t rpc,size_t size,size_t offset)
{
char *msg=buf;
size_t rsize=size;

if(size<=sizeof(rpc)) {
return -EINVAL;
}
msg+=sizeof(rpc);
size-=sizeof(rpc);

switch(rpc.arg3) {
case PHYT_WRITE:
uni_print((cschar_t*)msg,size);
break;
case PHYT_WRITEPOS:
uni_printxy((cschar_t*)msg,size,rpc.arg4,rpc.arg5);
break;
case PHYT_SCROLL:
if(rpc.arg4==SCROLL_UP) {
uni_scrollup(rpc.arg5);
uni_printxy((cschar_t*)msg,size,0,0);
} else if(rpc.arg3==SCROLL_DOWN) {
uni_scrolldown(rpc.arg5);
uni_printxy((cschar_t*)msg,size,0,uni_height()-rpc.arg5);
} else
return -EINVAL;
break;
default:
return -EINVAL;
break;
}

return rsize;
}

void ascii_puts(const char *msg)
{
return;
}

static size_t __vga_read(void *buf,uni_rpc_t rpc,size_t size,size_t offset)
{

vga_print("ridden\n");

return 0;
}

static int __vga_ioctl(void *buf,uni_rpc_t *rpc,size_t size)
{
uni_rpc_t rrpc;

if(size<sizeof(rrpc))
return EINVAL;

memcpy(&rrpc,buf,sizeof(rrpc));
switch(rrpc.arg3) {
case PHYT_DISABLEAUTOSCROLL:
uni_scrolldisable();
rpc->rpc_call=0;
break;
case PHYT_ENABLESCROLL:
uni_scrollenable();
rpc->rpc_call=0;
break;
case PHYT_GETSIZE:
rpc->rpc_call=0;
rpc->arg0=uni_width();
rpc->arg1=uni_height();
break;
case PHYT_CLEAR:
uni_clear();
break;
default:
return EINVAL;
break;
}

return 0;
}

Wednesday, November 12, 2008

Jari Operating System: LibAlloc updates

Some of today's deal within Jari OS project was dlmalloc (Douglas Lee memory allocator) porting.
So, it's done and now I've rejected using of ugly smalloc (simple memory allocator).
Dlmalloc is a great thing - it can be ported anywhere, for example - Jari OS doesn't have sbrk() function, and will not have this oldish shit, otherwise - all is done via mmap() and dlmalloc allow to use it without sbrk().
Porting to the Jari OS mmap() semantics taken few minutes only.
Like usually you can look out source code - git clone git://rep.jarios.org/syslibs.git - LibAlloc/lib/dlmalloc.c

thanks.