linux compat layer for device drivers.

Luigi Rizzo rizzo at icir.org
Wed Jan 24 15:48:09 UTC 2007


I have been doing some work on building a linux compatibility
layer to help porting linux device drivers to FreeBSD.

If someone wants to have a look at the details and maybe
help with suggestions on the proper layout and implementation,
you can find a snapshot of the code and a more info at

	http://info.iet.unipi.it/~luigi/FreeBSD.html

A somewhat more detailed description is available at

	http://info.iet.unipi.it/~luigi/FreeBSD//README_linux_kld

(the URL is so that you can access the latest version from
the archived email), i am attaching the current content
of the file below.

Note, i know it is a monumental task to to provide a full emulation
of all internal linux API. I don't want to do that, i just want
to provide enough glue to ease the porting of drivers for devices
that we currently do not support. Among these, certainly usb
cameras/webcams/dvb receivers, and probably some wireless network
adapters (for most of these things, the linux is written with the help
of reverse engineering or usb sniffers, so it is extremely confusing
to dig through the source code in order to do a 'real' port).

	cheers
	luigi


---------------------------------------------------------------
# $Id: README,v 1.3 2007/01/24 15:10:06 luigi Exp $

This archive contains some headers and source files to help
porting linux drivers to FreeBSD (6.x and above).

The idea is that you should be able to take linux sources,
write a suitable Makefile.kld following the example below,
and then build a working driver for FreeBSD.

At the moment (2007.01.24) this is still work in progress so we are
basically just building a loadable kld module (with all symbols
resolved), and providing enough glue to invoke the probe routine
for USB devices.  As time goes we are adding emulation of the USB
layer (not much is needed, in fact) and hooks from the BSD driver
calls to the linux ones.

----------------------------------------------------------------------
			U S A G E

+ extract the archive in a work/ directory. With the exception of this
  README, everything ends up under linux_compat/ (note, you can
  use a different, system-wide place provided you set up the
  paths in Makefile.kld accordingly).

+ extract the driver you want to port into the same work/ directory.
  Depending on the structure of the driver it may extract just a few
  files, or a large number of subdirectories.

+ write a Makefile.kld using the template supplied below.

+ run "make -f Makefile.kld" to try and build the driver.
  If you are lucky, everything works and you end up with a .kld file.
  Most likely, you will encounter one or more of the following problems:

  + compiler error due to the strict checks we make (-Werror ...).
    You can usually remove them by adding missing prototypes,
    removing extra ones, and fixing the qualifiers (const etc) on
    arguments.

  + clashes between the FreeBSD and the Linux symbols (e.g. msleep() has
    different meaning on the two; the FreeBSD system headers define a
    "version" as a global symbol (string) while some Linux drivers appear
    to use it as a local variable; and so on.
	The fix of these errors depends on a case-by-case

  + missing function in the linux emulation library. We are only implementing
    what our sample drivers need, so it is likely that some parts are missing.
    Your best option is to look at some suitable linux distribution
    (e.g. i like http://www.gelato.unsw.edu.au/lxr/ ) to find out
    how to implement what is missing.
	The first step is to provide the prototype in some of the header
    files, and then a stub routine (returning an error) in some of the
    .c file, and then try to fill up the details.

  + error loading the module, typically because the kernel loader could
    not resolve some of the symbols. Fix is the same as above.

  + finally, even if everything loads, in order to achieve the desired
    functionality you are likely to need to implement in full some of
    the emulation functions for which we only provide stubs.

That's all... this is developer stuff!
 
----------------------------------------------------------------------
		A R C H I T E C T U R E

The system is structured as follows.
Note that paths need to be revisited to make this installable as a port.
Also the content of some of the headers may be moved from one to
another in order to match better the original linux layout.

	linux_compat/
		contains the whole subtree (headers, sources, .mk files)

	linux_compat/linux/ linux_compat/asm
		adapted linux headers with enough definitions to
		compile stuff under FreeBSD

	linux_compat/linux_compat.c
		implementation of the linux function called by drivers.
		This may be expanded into multiple files for the various
		subsystem (memory, usb, pci, ...) as needed.
		In principle, these files should be compilable as a
		library so they should have no dependency (also in terms
		of cpp magic) on the actual driver they are used for.

	linux_compat/ldev_stub.c, linux_compat/ldev_stub.h
		A template for a FreeBSD device driver that calls
		the wrappers for the linux functions.
		This should be recompiled each time, as there are some
		parts whose output depends on the preprocessor symbols,
		e.g. DRIVER_NAME and DEV_NAME.

	linux_compat/bsd.linux_kmod.mk
		bmake include file to be added at the end of the
		driver-specific Makefile.kld to add the required
		.PATH, CFLAGS and SRCS (see example at the end of this file).

------------------------------------------------------------------
		P R O J E C T    S T A T U S

2007.01.24
	Linked the _probe() routine to the usb_device table provided
	by the linux driver, so that device matching works.
	Implemented an initial wrapper for the linux attach routine
	(which is called probe). However, it does not yet provide a
	suitable emulation of the usb layer so it is simply instructed
	to fail.

2007.01.23
	Implemented stubs for all hooks needed by the gspca driver.
	You can now build and load it.
	
2007.01.22
	start of project
-------------------------------------------------------------------

----- example Makefile.kld (taken from gspca) -----

# Makefile.kld to build a driver with linux emulation.
# $Id: README,v 1.3 2007/01/24 15:10:06 luigi Exp $
#
# Here you should set the following:
#	.PATH:	driver-specific paths
#	SRCS=	list of (driver) source files that we want to compile.
#	KMOD=	driver name (one word, will be used also elsewhere).
#	CFLAGS=	any driver-specific flags you might need. Often
#		-Ixyz listing all directories with include files.
#
#	Any other driver-specific variables.

.PATH: ${.CURDIR} ${.CURDIR}/decoder 

# sources for the linux driver
SRCS= gspca_core.c gspcadecoder.c

KMOD=gspca

CFLAGS+= -ISunplus -ISunplus-jpeg -ISonix -IConexant
CFLAGS+= -IVimicro -Idecoder
CFLAGS+= -DUSB_DEBUG

#DEBUG_FLAGS=-g

#--- Here are the driver-specific variables

VERSION    = 01.00.12

###
# The following flags enable experimental features.
# By default, these are enabled for development versions of the driver, and
# disabled for release versions.

# Optional: Enable driver debugging
CFLAGS   += -DGSPCA_ENABLE_DEBUG

# Optional: Enable direct register read/write for PAC207 development
#CFLAGS   += -DGSPCA_ENABLE_REGISTERPLAY

###
# The following flags enable features that aren't yet implemented, and
# therefore are disabled by default.

# Optional: Enable compression
CFLAGS   += -DGSPCA_ENABLE_COMPRESSION

###
# Rest of Makefile follows here. You probably won't need to touch this.

# Setup defines
CFLAGS   += -DCONFIG_USB_GSPCA_MODULE=1 -D__KERNEL__
#CFLAGS   += -DCONFIG_USB_GSPCA_MODULE=1 -DMODULE -D__KERNEL__
CFLAGS   += -DVID_HARDWARE_GSPCA=0xFF -DGSPCA_VERSION=\"$(VERSION)\"

.include <linux_compat/bsd.linux_kmod.mk>

# -------- end of file ----------


More information about the freebsd-arch mailing list