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