[openbeosnetteam] Re: Progress report

  • From: philippe.houdoin@xxxxxxx
  • To: openbeosnetteam@xxxxxxxxxxxxx
  • Date: Thu, 14 Mar 2002 19:47:52 +0100 (MET)

David wrote:
> Philippe, no offense, but I actually want to rip out all sorts of 
> code and reorganise what we have anyways! Given this your code is 
> very useful but I can't help thinking that a totally new clean 
> codebase will be cool and should allow us to have a best possible 
> implementation.

I would vote +1 for a code reorganisation too.
BTW, I've wrote a skeleton *core* module this morning, but can't 
find time and where to commit it :-)
I can post it on my web site, if you like.

> Well, let's not get too excited yet - we don't have it working and 
> as someone pointed out it took Be about a year to get this working 
> correctly...

I know that.
So many code to write!!! And, worst, to fix.
Isn't any cool?! 
:-)

Challenge *is* exciting.

> Why not simply call it net_stack?

Okay.

>> I suggest we put them here:
>> /boot/home/config/add-ons/kernel/network/*
>
> Hmmm, yes this should work, but maybe net_stack to differentiate between
> the stack and drivers? Or maybe we have
> 
> /network
> /network/stack
> /network/drivers

Well, the R5.x devfs don't let you choose where to put the device drivers, as 
he looks for device drivers in these places only:

/boot/home/config/add-ons/kernel/drivers/dev/*
/boot/beos/system/add-ons/kernel/drivers/dev/*

In fact, what's in */add-ons/kernel/drivers/dev/* are symlinks to the binary 
driver file tradidionnaly in */add-ons/kernel/drivers/bin/*.
Which, in turn, could allow us to put the drivers binary file wherever we want, 
*/add-ons/kernel/network/drivers/* included :-)

> I call sendto(...) in my app. This passes a pointer to a buffer for 
> the data. I wrap all the data up in a struct and pass the pointer to 
> the struct into ioctl - how does the kernel module get the data? In 
> my reading it seems like the kernel can't actually read userland memory? 

With R5 kernel, he can (Need to check for NewOS).
But... only to the caller team address (user)space.

AFAIK, BeOS kernel space is 0x00000000-0x7fffffff and user space 0x80000000 - 
0xffffffff. When a kernel code is called from a userspace team, 
the 0x00000000-0x7fffffff address space is the kernel one, always the same, 
with all kernel, drivers and modules code there, plus the kernel heap.
The 0x80000000 - 0xffffffff is the userspace of the calling team.

Problem rise when you want to *keep* this userland pointer somewhere, to hand 
it back to another caller team. For example, the loopback interface may want to 
queue a sent mbuf, and when (another) reader team call it, he would 
return back a pointer that have no meaning into his team.
In this case, you must copy the userspace block into a kernel space one 
(malloc() from a kernel driver code always return a kernel space block)
We can also ask to lock a userspace memory block, it's another way...

> Also, if I call
> read/write or any of that fmaily there are actually 2 returns. How much
> data did we read/write and an error code. How do we handle those as the
> kernel knows the errors but the ioctl simply returns a value saying if it
> succeeded or not! 

For read/write ioctls(), use the return value same way read()/write() do:
< 0 error
>= 0 nb bytes read/write

Or, we could add a return_code field to the data_xfer_ioctl struct used 
by libnet & stack driver to communicate.

Or both solutions, even ;-)

Currently, lib/socket.c and kernel/net_stack_driver.c use the first one...

> If I'm a sub-module and I want to call mget() then the allocation 
> should take place at the "core" level, not in the module making the 
> call. Also if I want to free memory that's a core function. So, 
> the core needs to export all sorts of extra fucntions. Keeping track 
> of all this is likely to be a nightmare and I'm not sure it's possible, 
> however I hope it is. Look also at the route
> code.  I think we just need to be clear that once a module has a valid
> pointer to a structure it can mess with it, but getting/freeing the pointer
> should be done centrally.

We could move all *support* functions into a support module, that all 
modules (core, interfaces, protocols) will use (get_module()).

Kernel modules are like kernel DLLs, except... they're not really :-)
get_module() / put_module() do reference count, so no multiple loads...

pools, mbuf, misc, timers, queues would be better in one network support 
module.

Another point, when you're in kernel land, all allocations you make are 
accessible to all kernel land code: drivers (our), modules, etc.
It's what's make coding in kernelland far difficult: no memory protection.

> Oh. Well, what does the select() hook in the driver do anyways? If it
> passes calls into our stack there shouldn't be any issues...

In a device driver, the select() and deselect() hooks are called 
for each event monitored by a client who call select()on a file descriptor
opened on the device driver.

Under net_server R5, there is no userland select() available, apart the 
net_server only one. If the *hidden* kernel select() have the reported bug, 
we could perfectly implement the select() ourselves the way we want, without 
any kernel help. But our select() will works only on sockets, not real file 
descriptors. Oh, well, it still be better than net_server one 
(read event only !!!).

Under BONE R5, the kernel select() bugs where fixed, so no problem here.
Apart distributing a binary kernel upgrade :-(

Anyway, too early to worry yet.

-Philippe.

Other related posts: