Driver development question

John Baldwin jhb at freebsd.org
Wed Jul 22 13:21:06 UTC 2009


On Wednesday 22 July 2009 2:37:49 am Marc Loerner wrote:
> Am Mittwoch 22 Juli 2009 02:07:13 schrieb Alfred Perlstein:
> > * John Baldwin <jhb at freebsd.org> [090721 14:44] wrote:
> > > On Tuesday 21 July 2009 2:34:21 am Marc Loerner wrote:
> > > > Am Dienstag 21 Juli 2009 00:38:56 schrieb Sam Leffler:
> > > > > John Baldwin wrote:
> > > > > > On Friday 17 July 2009 11:10:17 am Chris Harrer wrote:
> > > > > >> Hi All,
> > > > > >>
> > > > > >> I'm hoping someone can point me in the right direction...  I'm
> > > > > >> developing a FreeBSD driver for a PCIe card.  The driver controls
> > > > > >> a hardware device that has DRAM and various state information on
> > > > > >> it.  I'm trying to mimic functionality I have for other OS 
support
> > > > > >> such that I can dump memory and state information from the card 
to
> > > > > >> a file I create from within my driver (kernel module).
> > > > > >>
> > > > > >> For example, in a Linux driver I use filp_open to create the dump
> > > > > >> file (represented by fp), then use fp->f_op->write to put
> > > > > >> information into the file.
> > > > > >>
> > > > > >> FreeBSD doesn't have filp_* API's.  I've tried searching for
> > > > > >> example drivers and googling for file API's from kernel modules 
to
> > > > > >> no avail. Can someone please offer some guidance as to how I 
might
> > > > > >> proceed here?
> > > > > >>
> > > > > >> Thanks in advance and any insight would be most appreciated!
> > > > > >
> > > > > > You can look at sys/kern/kern_ktrace.c to see how the ktrace()
> > > > > > system call creates a file.  I think in general you will wind up
> > > > > > using NDINIT/namei() (to lookup the vnode for a pathname) and then
> > > > > > vn_open() / vn_rdwr() / vn_close().
> > > > >
> > > > > man alq(9).
> > > >
> > > > Why not use kern_open, kern_close, kern_preadv, kern_pwritev?
> > >
> > > Those affect the state of the current process by opening a new file
> > > descriptor, etc.  That is generally bad practice for a device driver to
> > > be interfering with a process' state, and it will not work for kernel
> > > threads. You can rather easily have userland open a file and then pass
> > > the file descriptor to a driver which can then do operations on a file
> > > directly.
> >
> > If the vnode operations are annoying to wrap ones head around, one
> > could have the driver defer this this to a kernel resident process
> > that the driver would create on attach.
> 
> So when action on a "pseudo" driver is requested via IOCTL from the same 
> userspace-thread the above kern_* functions can be used for file-io?

Possibly.  If the userland ioctl gives you an fd then you could invoke 
kern_read(), etc.  I still think doing an actual open (i.e kern_open()) or 
close in a driver that affects the state of a process is a bad thing.  
Applications expect that the only file descriptors they have are ones they 
open.  For example, some apps have assumptions about the relative order of fd 
numbers (at the moment I can only think of regression tests I've written that 
check for leaked fd's, etc.), though you also have apps that assume if they 
do 'close(0); open()' then the new fd will be stdin (i.e. fd == 0).  If the 
app were multithreaded and another thread was invoking your ioctl, your icotl 
handler might claim 0 instead resulting in possible security holes, etc.  I 
really think that sort of thing is best avoided.  If an application has 
already opened a file and passes you an fd you could use kern_read/kern_stat, 
etc. safely though.

However, for your use case (dumping debug info) I think Sam is correct and 
that ALQ is the best thing for you to use.

-- 
John Baldwin


More information about the freebsd-drivers mailing list