Monday, January 28, 2008

xnu uio api

Hello guys,

Since few days I implement a simple rs232 driver on Darwin. But during this implementation I have got some understand problem about a data structure.

Today I will introduce you a part of the kpi : the struct uio and a lot of conveniance functions about uio. And this api is the sources of my past problems. But after my explication I will seem dumb because uio is very simple to understand and to implement.

Uio what s that ? Its simply a api to work with data buffer. Which is the relationship between the rs232 and the struct uio? The functions pointer you ll need to implement to register your driver use uio (like the read or write). Why is this destabilizing? because the struct uio is defined like that in the uio header :

struct uio;

So we don't know the members of that structure. Why apple does that? Because they want to be able to change the code managing this data without the change of all the code using this api.

an uio is a container of iovec. It can have one iovec or a collections of iovec. The iovec contains data. the iovec structure looks like :
 
struct iovec 
{
void *iov_base;
size_t iov_len;
}


This API offers some functions to work on uio containing just one iovec :

void uio_setresid( uio_t a_uio, user_ssize_t a_value );
int uio_rw( uio_t a_uio );
void uio_setrw( uio_t a_uio, int a_value );
int uio_isuserspace( uio_t a_uio );

for collections of data  uio struct can work with this fuctions :

int uio_iovcnt( uio_t a_uio );
uio_t uio_create( int a_iovcount, off_t a_offset, int a_spacetype, int a_iodirection );
void uio_reset( uio_t a_uio, off_t a_offset, int a_spacetype, int a_iodirection ); 
uio_t uio_duplicate( uio_t a_uio );
void uio_free( uio_t a_uio );
void uio_update( uio_t a_uio, user_size_t a_count );
user_ssize_t uio_resid( uio_t a_uio );

int uio_iovcnt( uio_t a_uio );
off_t uio_offset( uio_t a_uio );
void uio_setoffset( uio_t a_uio, off_t a_offset );
user_addr_t uio_curriovbase( uio_t a_uio );
user_size_t uio_curriovlen( uio_t a_uio );
int uio_addiov( uio_t a_uio, user_addr_t a_baseaddr, user_size_t a_length );
int uio_getiov(uio_t a_uio, int a_index, user_addr_t *a_baseaddr_p, 
   user_size_t * a_length_p );
off_t uio_offset( uio_t a_uio );
void uio_setoffset( uio_t a_uio, off_t a_offset );

My rs232 driver read and write exemple :

/*
** Serial read, read one byte from the device
*/

int serial_read(dev_t dev, struct uio *uio, int ioflag)
{
struct device *current;
int len;
int rlen;
char buff[1];
int size= 1;
int i;

*buff = 0;
if (uio_rw(uio) != UIO_READ)
return (EINVAL);
if (minor(dev) >= MAX_PORTS)
return (ENXIO);
current = &serial[minor(dev)];
if (!(current->attached))
return (EBUSY);
len = uio_resid(uio);
rlen = MIN(size, len);
for (i = 0; i <>
 
  while(((inb(current->port + LSR)) & 0x01) == 0);
buff[i] = inb(current->port + RECEIVER);
}
uiomove(buff, rlen, uio);
printf(DEVICE_NAME " READ\n");
return KERN_SUCCESS;
}

/*
** Serial write, write n bytes to the device
*/

int serial_write(dev_t dev, struct uio *uio, int ioflag)
{
struct device *current;
int len;
char *buff;
int i;

if (uio_rw(uio) != UIO_WRITE)
return (EINVAL);
if (minor(dev) >= MAX_PORTS)
return (ENXIO);
current = &serial[minor(dev)];
if (!(current->attached))
return (EBUSY);
len = uio_resid(uio);
MALLOC(buff, char *, len * sizeof(*buff), M_WAITOK|M_ZERO, M_TEMP);
if ((uiomove(buff, len, uio)) != 0)
{
printf(DEVICE_NAME "KPI error");
return KERN_FAILURE;
}
for (i = 0 ; i < style="text-align: justify;"> 
while((inb(current->port + LSR) & 0x20) == 0);
outb(current->port + TRANSMITTER, buff[i]);
}
FREE(buff, M_WAITOK|M_ZERO);
printf(DEVICE_NAME " WRITE\n");
return KERN_SUCCESS;
}

Wednesday, January 23, 2008

Unix V7

Hello,

I found here a mail of mr nordier who says "hey I made the x86 V7 port do you want it".

Grrr I need more time to read interesting sources like these. If you want to see the Project Page.

Friday, January 4, 2008

Paid to do kernel land stuff

Since the 5th of November I start my new job at Adeneo and it's the first time in my life where I was paid to do kernel land stuff :)

The first step job this is a one month formation on Windows CE 6.0 and diverse embedded cpus. Before my first day I'd just have some bad feeling about CE development because it wasn't unix kernel development, but when the formation start I realize that I was totally wrong. This job is really interesting for a lot of reasons:

- Co-Workers seems to be good workers and C lovers. They are a great source of information.
- With a very quick and interesting formation this permits me to learn a lot of things in just two weeks...
- CE6.0 permits to browse all of the kernel land and user land source, and it s funny to read the ie or cmd sources :)
- The code I have to realize is not ugly like some C# or another ugly, sad or insane thing. It's just C, C++ or asm. It was some code very near the hardware.
- I start my work on a atmel chip that was an architecture very different from the ugly x86.
- CE permit me to see another kernel code implementation. With that I can find better code abstraction in driver development.
- I can continue my personal development in unix and free software and continue to work on some project or create new one...

Links:
Adeneo Website
Windows embedded developper center
wiki on winCE

Thursday, January 3, 2008

advancement on sos


A little new post to keep you aware of the advancement of the sos framebuffer driver.

Right now, Buckman and I have finished the vm86 driver, allowing us to call 16bits bios interrupts from kernel land. Thanks to this vm we will be able to call the vesa functions, reachable only through 16 bit modes.

Bios interrupts are called just like in this piece of code, that allows us to get some infromation from the VBE:

vbe_info_block_t *get_vbe_info()
{
vbe_info_block_t *vbe;
sos_vm86_t regs;
memset(&regs, 0, sizeof(sos_vm86_t));
regs.service = 0x10;
regs.ax = VBE_INFO;

regs.es = SOS_VM86_SEGMENT;

regs.di = vbe = sos_vm86_malloc(sizeof(*vbe));
strzcpy(vbe->vbe_signature, "VBE2", 4);
sos_vm86_bioscall(&regs);

return (vbe);
}


In a first time we will memset the structure to be sure it is initialised to 0. Then we will fill the vm86 structure with the data corresponding to interruption 0x10 and the data for this interruption in the virtual registers ax es and di. And then we call the function sos_vm86_bioscall that wraps around the interrupt. The data structure sos_vm86_t is defined as :

typedef struct
{

sos_ui8_t service; /* Numero de l interruption a appeler*/
sos_ui16_t ax;

sos_ui16_t bx;
sos_ui16_t cx;

sos_ui16_t dx;

sos_ui16_t si;
sos_ui16_t di;
sos_ui16_t es;
sos_ui16_t ds;
} sos_vm86_t;

In a second time we coded the vesa driver wich is a simple set of convenience functions. Here is the exhaustive list of vesa functions prototypes :

void init_vesa(sos_ui16_t mode);
vbe_info_block_t *get_vbe_info();

void map_lfb(mode_info_block_t *mib);

void set_display(sos_ui16_t mode);
mode_info_block_t *get_mib_info(sos_ui16_t mode, vbe_info_block_t *vbe);
sos_bool_t is_mode_usable( sos_ui16_t mode, vbe_info_block_t *vbe);
void vesa_clear_screen(mode_info_block_t *mib, sos_ui32_t color);

void vesa_draw_rect(sos_ui32_t startx, sos_ui32_t starty, sos_ui32_t
height, sos_ui32_t width, mode_info_block_t *mib,
sos_ui32_t color);

void vesafont_draw_text(const char* s, sos_ui32_t x, sos_ui32_t y,
sos_ui32_t fg, sos_ui32_t bg,
mode_info_block_t *mib);

void vesa_draw_bitmap(sos_ui32_t x, sos_ui32_t y, sos_vaddr_t *img);

void vesa_plot_pixel(sos_ui32_t x, sos_ui32_t y, mode_info_block_t *mib,
sos_ui32_t color);


It represents our virtual machine with a set of register and the id of the interrupt to call.

For the moment, we still have to work on the tty driver and the chardev /dev/fb.

To be concluded...

Implement a framebuffer on SOS


Matthieu bucchianeri (buckman) and I started this Monday 15th of October the portage of a framebuffer on SoS[1].

This ports contains 3 great parts:
- The vm86 driver
- The vbe driver
- The vesatty driver

The vm86 driver permits to do bioscall in protected mode. This driver was finish and works fine :).

The vbe driver is a set of conveniences functions to set the config of the fb to map the memory of the db , to get vbe structure etc... This driver is completed at 75%. We have a mystical bug because our driver works fine on qemu but doesn t work on a GeForce2 with vbe3 support....

The last driver permits to replace the current console print by a framebuffer print but it is not yet started.

We took contact with the sos' developers to know if they wan't our kernel patch and a new article for GNU/Linux magazine. I will keep you informed about the advancement of this project.

[1]
SimpleOS

zobfs


The goal of the evilkittens October coding party for Filth and me was to create our first filesystem : the zobfs.

What is zobfs? Simply a port from scratch of a fat32 fs on OpenBSD. The aim of zobfs is to learn and understand how we can develop a filesystem on our favorite operating system.

We based our dev on some documentation about the fat32 specs and some OBSD fs howto:

fat32

Doc Open

Our project have a free CVS hosting offered by veins on evilkittens and you can browse the source on this cvsweb :

cvsweb

I hope we'll have finished this project for December. And I promise you a simple and sexy paper under LateX which explains how we implement this fs :)

my new job

Hello, I'm writing a new post to talk about my hypothetical new job at Adeneo.

Do you now what is a BSP. A BSP is a Board support package, that means a package of file needed to port an os on a new architecture.

Why do I talk about BSP? Because my future job possibly concerns it. I will certainly work for the R&D of Adeneo to make the State-of-the-art of the differents BSP. When I will have finish the research job I will made some papers about it and perhaps start to think about a BSP generator.

With the Driver generator and the Stack Ip generator, this third project ensures the idea that the two next years should be generation years :)

Rataxes

In the epitech cursus we have to realize a project named PFE (end of curses project). That s why we created rathaxes.


Rathaxes <1> will be a multi platform driver generator. This idea hinges around the fact that developping drivers is a difficult task because it requires developpement skills and electronic ones. Moreover the driver's specific code of an operating system is huge (about 70% for Linux) and this code is more buggy than other applications (7 times more).

To start we are going to use laurent reveillere's works and his thesis ''Approche langage au développement de pilotes de périphériques robustes" <2>. In this thesis, reveillere introduces the DSL/Driver concept. A DSL stands for Domain Specific Language, it is like SQL for the domain of databases.

For this project we will be helped by the LSE (System Laboratory of Epita) during the next two years<3> and his chief Lionel Auroux.


Liens :

<1> Rathaxes

<2> Thesis

<3> LSE