Subject: Re: LKM Device Drivers
To: Bill Studenmund <wrstuden@netbsd.org>
From: Jared D. McNeill <jmcneill@invisible.ca>
List: tech-kern
Date: 04/12/2002 21:23:13
On Fri, 12 Apr 2002, Bill Studenmund wrote:
> One intermediate step would be to add something like /dev/ksym from
> Solaris (which I don't know much about). The main thing is to add a way
> for the kernel to:
>
> 1) export its symbol table to userland
>
> 2) have the symbol table grow as lkms are added (and shrink when they
> unload).
>
> 3) have userland tools use said new device

Strangely enough, just before I got this email, I fudged something similar
to this completely in userland with an 'add_driver' script I wrote. I can
now add_driver foo.o and everything just works. I've stuck a copy of the
script below.

It's not pretty, but it's doing the job.

Laters,
Jared



#!/bin/sh
#	$NetBSD$
#
# Copyright (C) 2002 Jared D. McNeill <jmcneill@invisible.ca>
#

if [ "$#" -lt 1 ]; then
	echo "usage: add_driver <driver> [depends]"
fi

LD=/usr/bin/ld
DRVDIR=/usr/lkm/drivers
MODLOAD=/sbin/modload
DRIVER="$1"
DEPENDS=`echo $* | sed 's/ /\.o /g' | sed 's/$/\.o/'`

cd $DRVDIR

#
# METHOD 1:
#	Prelink all of the objects, and load them all in one go
#
#$LD -r -o "$LKMDIR/$DRIVER.o" $DEPENDS
#$MODLOAD "$LKMDIR/$DRIVER.o"

#
# METHOD 2:
#	Chainload all of the objects, loading them separately
#
#cnt=0
#for curdrv in $DEPENDS; do
#	if [ ! "$lastname" = "" ]; then
#		ARGS="-A $DRVDIR/$lastname"
#	else
#		ARGS=""
#	fi
#	lastname="drvtmp$cnt"
#	cnt=`expr $cnt + 1`
#	ARGS="$ARGS -o $DRVDIR/$lastname $curdrv"
#	echo $ARGS
#	$MODLOAD -s -S $ARGS
#done

#
# METHOD 3:
#	Keep a shadow kernel (with updated symbol table) and always
#	use it for loading modules.
#

MODULES=/modules
SHADOW_KERNEL=/var/run/lkm.shadow
SHADOW_TMP=/var/run/lkm.shadow.tmp
KERNEL=/netbsd

if [ ! -f "$SHADOW_KERNEL" ]; then
	# This is the first time we've been run on this boot
	cp "$KERNEL" "$SHADOW_KERNEL"
fi
rm -f "$SHADOW_TMP"
$MODLOAD -s -S -A "$SHADOW_KERNEL" -o "$SHADOW_TMP" $DRIVER
if [ -f "$SHADOW_TMP" ]; then
	# Module successfully loaded, so copy the temporary shadow to the
	# original one.
	mv -f "$SHADOW_TMP" "$SHADOW_KERNEL"
fi