Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 11 Jan 2001 23:13:14 -0500 (EST)
From:      Andrew Gallatin <gallatin@cs.duke.edu>
To:        freebsd-current@freebsd.org
Cc:        "'Alfred Perlstein'" <bright@wintelcom.net>
Subject:   RE: Running Linux kernel modules.
Message-ID:  <14942.32188.899333.434988@grasshopper.cs.duke.edu>
In-Reply-To: <01C07BF3.695D3780.ggross@symark.com>
References:  <01C07BF3.695D3780.ggross@symark.com>

next in thread | previous in thread | raw e-mail | index | archive | help

 > On Thursday, January 11, 2001 3:12 PM, Alfred Perlstein 
 > [SMTP:bright@wintelcom.net] wrote:
 > > * Carl Makin <carl@xena.ipaustralia.gov.au> [010111 14:52] wrote:
 > > >
 > > > There are a couple of linux kernel modules that I'd love to run under
 > > > FreeBSD.  I've always assumed that I'd have to rewrite them substantially
 > > > to make that happen.
 > > >
 > > > Can anyone give me some pointers on how hard it could be to port a linux
 > > > kernel module to FreeBSD?
 > >
 > > Depends on how familiar you are with kernel internals, for instance
 > > after taking a quick look at the kernel module needed to run vmware
 > > it was pretty clear that someone with the experience and time could
 > > have it done in under a week, about 2 weeks later some maniac ( :) )
 > > surfaced who had done just that.

The biggest problem I've had porting linux drivers is that linux
exports enough internals to allow drivers to distinguish between
multiple opens of the same device.  Eg:

	int 
	foo_ioctl(struct inode *inode, struct file *filp,
	                  unsigned int cmd, unsigned long arg)
	{
	        foo_per_open_data *priv = filp->private_data;
	        foo_softc *sc = priv->dev;
	<..>
	}

AFAIK, there's no clean way to do this with FreeBSD.  I think this is
why VMware is limited to running one virtual machine.

This can be somewhat overcome in a very ugly way -- At my day job, I'm
porting a driver for Giganet cLAN1000 VIA adapters.   This has much
the same problem as VMware.  They've got an open-source linux kernel
module and a closed source userland binary. 

To handle the multiple open problem, I'm overloading the open and
close system calls.  Upon open, I call the native open, then I grovel
around in the process' open file table looking for my special file.
When I find it, I mark fp->f_nextread with a magic number, then store
a pointer to the per-open private data in fp->f_offset.  On close, I
go grovelling again.  I deallocate the private data, clear the magic
number, and call the system close function.  I've also got an
at_exit() hook that does much the same thing.

Obtaining the file descripter at ioctl() and mmap() time is much more
interesting.  When I'm called from a syscall, I pull the args out of
the process and grab the fd, index the process' file table and bingo.

The real problem is when mmap is called out of a fault (and not
dev_pager_alloc, which is what gets called when the mmap syscall is
issued).  Right now I throw up my hands and return the private data
from the first instance I find when walking the process' open file
table.   If this becomes a problem, I'm planning on prefaulting the
pages at dev_pager_alloc() time (when I can get an fd from the
process) and wiring them -- its only 20k per process..

Isn't this gross?  Is there a better way?

Drew

------------------------------------------------------------------------------
Andrew Gallatin, Sr Systems Programmer	http://www.cs.duke.edu/~gallatin
Duke University				Email: gallatin@cs.duke.edu
Department of Computer Science		Phone: (919) 660-6590


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?14942.32188.899333.434988>