[comp.unix.questions] Loadable device drivers...in V.4?

ir@cel.co.uk (ian reid) (10/19/90)

Now with the move to make UNIX a truly shrink wrapped product it would
be nice for certain things which MS-DOS users have taken for granted to be
incorporated into V.4.  The following comments are certainly true for V3.2 and
as far as I am aware for V.4, please correct me if I am wrong.

I am specifically thinking of loadable device drivers.  Now I am not pretending
that config.sys doesn't cause users a great deal of pain and heartache, but
when you consider the inconvenience a UNIX user is put to achieve this task
the point becomes valid.  These inconveniences are:-

1) The user must have the kernel configuration subset loaded, taking up valuable
disk space on the users disk, causing vendors to distribute systems on a lot of
media, and requiring a lot of installation time.

2) The kernel must be rebuilt and reinstalled, which takes a lot of time.

3) Even a simple changing of a kernel parameter variable requires a kernel 
rebuild and re-installation.

But what if we lived in a world where there was one generic kernel.  The kernel
would provide all the device independent facilities.  All device drivers would
be loaded at run-time by the kernel.  Space for system buffers would be 
dynamically allocated at run-time by the kernel by reading its mtune file.  The 
question is how would this process be managed.

The framework is already in place.  All drivers are described by the various 
mdevice, sdevice files.  All kernel parameters are described by the mtune
and stune files.  When a new driver was added to the system the new files would 
be added in the usual way, with checks for interrupt conflicts etc, only a 
kernel build and installation would not be needed.  The drivers themselves would
be built as some form of shared library.

This must all be possible, as SunOS4.0-> already has something similar (I am not
familiar with details).  So does V.4 have this facility or something similar or 
is it planned to add such a facility in the future.

-- 
Ian

ts@cup.portal.com (Tim W Smith) (10/21/90)

I wish vendors would do this.  It's not even hard.  I worked out
how it could be done a long time ago (when I worked at Callan
Data Systems), but didn't try it.  When I worked at Interactive,
I got to try it.  It only requires a couple of relatively simple
kernel changes.

First, you need a system call that will allocate kernel memory
for the driver.  Second, you need a system call that will install
an interrupt handler for the driver.

The rest you do with a program.  The basic things that must be done
to load a driver are these:

	Assuming the driver object file is named Driver.o, get
	a list of undefined external references in Driver.o.
	Use nm or ld to do this for you.

	Look up each of these in the kernel symbol table.  You  must
	have a kernel symbol table, of course, for this to work.

	Make a file that defines these externals as absolute references
	to the values obtained from the kernel symbol table.
	I don't remember if I did this by making as assembly file
	that declared them this way, or some sort if input file
	for ld.  It's been a while since I did this.

	The program (which must be running as root) now uses the
	system call for memory allocation to allocate memory in
	the kernel for the driver.  This system call returns the
	base address in kernel space of the allocated memory.

	Use ld and the file created two steps ago and the return value
	from the memory allocation system call to create a .o file
	that has all external references resolved and is set up
	to be loaded at the address of the kernel memory allocated
	in the previous step.

	The driver loader program now opens /dev/kmem and copies
	the driver into the memory allocated a couple of steps ago.
	
	The driver loader then adds entries for the driver open, close,
	read, etc., routines into the appropriate kernel table (bdevsw,
	cdevsw, or whatever).

	The driver load program uses the second new system call to
	tell the kernel what interrupt the driver uses, and where
	the interrupt routine is at.

The ISC version of this could load drivers and streams modules.

Facilities were also included to unload drivers.

The main reason it was never released by ISC was that they were
interested in this as a way to make the kernel smaller on the
boot floppy.  At the time, there were limits in the boot program
on the size of a kernel that could be loaded, and if all the drivers
they wanted were in the kernel, it would exceed those limits.

However, someone fixed the boot program, so they did not need the
loadable driver stuff.  I was in the process of leaving at the time,
so I don't know what ever happened to it after that.

I wish they had pursued it.  I've developed a couple of drivers since
then, and would have really appreciated being able to test minor changes
without having to rebuild the kernel.  In my experience, there is a long
period at the end of a driver project where the thing works well enough
that it is not crashing the kernel, but it needs various tweeks.  This
stage would go much faster with a way to load drivers without rebooting
the system.

						Tim Smith

chris@mimsy.umd.edu (Chris Torek) (10/22/90)

In article <35110@cup.portal.com> ts@cup.portal.com (Tim W Smith) writes:
>I wish vendors would do this.  It's not even hard. ...
>First, you need a system call that will allocate kernel memory
>for the driver.  Second, you need a system call that will install
>an interrupt handler for the driver.  [Do everything else in user code]

It is not (always) this easy.  On some machines, you must use particular
memory regions for particular devices, and they may already be in use.
Not all machines use interrupts, either; the `install' call must have
more information than just an interrupt vector.  The first problem is
really the hardest, though, and usually means everything critical must
be allocated at boot time.  (Even VAXen, which are notorious for allowing
sloppiness, sometimes require special memory, e.g., for Unibus vectors
on 750s---these must appear immediately after the SCB [you could copy and
then move the SCB, of course...]---or for some Unibus devices [need 16-bit
addresses].)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750)
Domain:	chris@cs.umd.edu	Path:	uunet!mimsy!chris

dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (10/22/90)

In <6681@suns302.cel.co.uk> ir@cel.co.uk (ian reid) writes:

>Now with the move to make UNIX a truly shrink wrapped product...

Which would a wonderful thing!  Shrink-wrap license agreements have
never been shown to be legally enforcible, which would make UNIX truly
available to all without any trade secret constraints on it any more.
--
Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP:  oliveb!cirrusl!dhesi

ts@cup.portal.com (Tim W Smith) (10/22/90)

Oops.  I didn't notice the cross posting.  I did not mean to
suggest that it is easy on all machines, just 386 System V
machines.  Give me a Cray, and I'll put up with the kernel
rebuild time rather than demand loadable drivers :-)

					Tim Smith

ts@cup.portal.com (Tim W Smith) (10/22/90)

I left a couple of things out in my description of how dynamically
loadable drivers in ISC 1.0.6 worked.

First, I forgot a system call.  There is a system call that the installer
program can make that tells the kernel to call the device initialization
code.

Second, I forgot to emphasize an important point.  Any such scheme should
be done in such a way as to require no modification of drivers.  You do
not want to get a situtation where you have two versions of a driver, one
for compiling into the kernel, and one for dynamic loading.

Third, our scheme did require that the kernel be built with extra
space in cdevsw, bdevsw, and whatever the one for streams modules
is called.

Fourth, I don't remember if we allowed a device to be loaded that
used a shared interrupt vector.  We may have been limited to devices
that don't share vectors.

The reason the install program copied things into /dev/kmem to modify
cdevsw or bdevsw, rather than having a system call to do this, which
would probably be cleaner, was political.  The less kernel changes that
are required to implement something, the better the chances of convincing
people to do it.

						Tim Smith

erik@unislc.uucp (Erik Sean Nolte) (10/30/90)

In article <35110@cup.portal.com> ts@cup.portal.com (Tim W Smith) writes:
[ loadable device drivers: ]
>I wish vendors would do this.  It's not even hard.
Fortunately, Unisys already does this with their 6000/10/3x/5x/WS
Unix boxes & Converent's S series machines.  The command to load the
driver is lddrv and it operates roughly as you've described.

>I wish they had pursued it.  I've developed a couple of drivers since
>then, and would have really appreciated being able to test minor changes
>without having to rebuild the kernel.  In my experience, there is a long
>period at the end of a driver project where the thing works well enough
>that it is not crashing the kernel, but it needs various tweeks.  This
>stage would go much faster with a way to load drivers without rebooting
>the system.

I don't write many actual device drivers, but I find the loading feature
especially useful for STREAMS module debugging.