Basic Hello World module won't load

Hey everyone! I'm fairly new to FreeBSD and was following a tutorial on writing FreeBSD drivers. The first example was a simple Hello World module, here's the code for hello.c:

Code:
#include <sys/param.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>

static int
hello_modevent(module_t mod __unused, int event, void *arg __unused)
{
   int error = 0;
   switch (event) 
   {
      case MOD_LOAD:
         uprintf("Hello, world!\n");
         break;
      case MOD_UNLOAD:
         uprintf("Good-bye, cruel world!\n");
         break;
      default:
         error = EOPNOTSUPP;
         break;
   }
   return (error);
}

static moduledata_t hello_mod = 
{
   "hello",
   hello_modevent,
   NULL
};

DECLARE_MODULE(hello, hello_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
And here's the makefile I used:

Code:
KMOD= hello
SRCS= hello.c

.include <bsd.kmod.mk>
When I first tried sudo kldload ./hello.ko it threw an error about a malformed conditional in /sys/conf/kern.mk. I commented that line and it told me it couldn't find the compiler; after a bit of googling I did cp /usr/src/share/mk/bsd.compiler.mk /usr/share/mk/ and the module compiled fine.

However (and here's when I'm currently stuck), when I try to load it (either with $ sudo kldload ./hello.ko or $ sudo make load), it gives me the following error:
Code:
KLD hello.ko: depends on kernel - not available or version mismatch
linker_load_fle: Unsupported file type
kldload: can't load /home/phillipe/hello.ko: Exec format error
*** Error code 1

Stop in /home/phillipe.
If I inspect /var/log/messages it shows me the same error messages, and so does dmesg. Here's my uname -a:
Code:
FreeBSD mcvlab1 9.1-PRERELEASE FreeBSD 9.1-PRERELEASE #4: Thu Jul 26 12:49:04 ART 2012     root@mcvlab1:/usr/obj/usr/src/sys/MCVLAB1  amd64
And here's file ./hello.ko:
Code:
hello.ko: ELF 64-bit LSB relocatable, x86-64, version 1 (FreeBSD), not stripped
I wonder what's wrong. I read somewhere that people having the same error had compiled their modules using sources that didn't work with their kernel, but I don't know how to check that. Any ideas on how to fix this?

Thanks a lot!
 
Phillipe said:
I wonder what's wrong.
My first guess would be that the source in /usr/src/ isn't the same version as the rest of your system. You must have the same version.

I also suggest updating your system. 9.1-PRERELEASE? I mean 9.1 has been out quite a while, even 9.2 is around the corner.
 
I know it's old. It's not really my PC, it belongs to the lab I'm working in so I don't know if I'm allowed to update it myself. On the other hand, I don't think that just because it's an old version I can't load any modules.

How can I check if my /usr/src is the same version as the rest of my system?
 
Phillipe said:
How can I check if my /usr/src is the same version as the rest of my system?
To my knowledge there is no way to be 100% sure. For example; if someone has updated the source code after the last reboot then it would differ from your active kernel. However; revision control for /usr/src is normally done using Subversion, and that program has no ties with the kernel itself.

I noticed from your uname output that you're using a customized kernel. You could try comparing the output from kldstat with the custom configuration and /etc/make.conf to see if it matches. But even then it's only a hint.

Personally I agree with @SirDice on this one; considering the error the most obvious cause is a mismatch. And the best way to solve that is to update the system to a specific (preferably supported) version.
 
Last edited by a moderator:
ShelLuser said:
And the best way to solve that is to update the system to a specific (preferably supported) version.
Yes, that's what I would do.

Update the source to 9.1-RELEASE-p7 and use it to update the system. After that both the source and the system itself should be in sync. I'm pretty sure that will solve the errors you're having.
 
Thanks a lot for your responses! I'll talk with the supervisor and see if we can update the system. Here's my newvers.sh:

Code:
#!/bin/sh -
#
# Copyright (c) 1984, 1986, 1990, 1993
#       The Regents of the University of California.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 4. Neither the name of the University nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#       @(#)newvers.sh  8.1 (Berkeley) 4/20/94
# $FreeBSD: head/sys/conf/newvers.sh 246246 2013-02-02 11:58:35Z avg $

TYPE="FreeBSD"
REVISION="10.0"
BRANCH="CURRENT"
if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
        BRANCH=${BRANCH_OVERRIDE}
fi
RELEASE="${REVISION}-${BRANCH}"
VERSION="${TYPE} ${RELEASE}"
SYSDIR=$(dirname $0)/..

if [ "X${PARAMFILE}" != "X" ]; then
        RELDATE=$(awk '/__FreeBSD_version.*propagated to newvers/ {print $3}' \
                ${PARAMFILE})
else
        RELDATE=$(awk '/__FreeBSD_version.*propagated to newvers/ {print $3}' \
                ${SYSDIR}/sys/param.h)
fi

b=share/examples/etc/bsd-style-copyright
year=`date '+%Y'`
# look for copyright template
for bsd_copyright in ../$b ../../$b ../../../$b /usr/src/$b /usr/$b
do
        if [ -r "$bsd_copyright" ]; then
                COPYRIGHT=`sed \
                    -e "s/\[year\]/1992-$year/" \
                    -e 's/\[your name here\]\.* /The FreeBSD Project./' \
                    -e 's/\[your name\]\.*/The FreeBSD Project./' \
                    -e '/\[id for your version control system, if any\]/d' \
#!/bin/sh -
#!/bin/sh -
#
# Copyright (c) 1984, 1986, 1990, 1993
#       The Regents of the University of California.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 4. Neither the name of the University nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
#       @(#)newvers.sh  8.1 (Berkeley) 4/20/94
# $FreeBSD: head/sys/conf/newvers.sh 246246 2013-02-02 11:58:35Z avg $

TYPE="FreeBSD"
REVISION="10.0"
BRANCH="CURRENT"
if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
        BRANCH=${BRANCH_OVERRIDE}
fi
RELEASE="${REVISION}-${BRANCH}"
VERSION="${TYPE} ${RELEASE}"
SYSDIR=$(dirname $0)/..

if [ "X${PARAMFILE}" != "X" ]; then
        RELDATE=$(awk '/__FreeBSD_version.*propagated to newvers/ {print $3}' \
                ${PARAMFILE})
else
        RELDATE=$(awk '/__FreeBSD_version.*propagated to newvers/ {print $3}' \
                ${SYSDIR}/sys/param.h)
fi

b=share/examples/etc/bsd-style-copyright
year=`date '+%Y'`
# look for copyright template
for bsd_copyright in ../$b ../../$b ../../../$b /usr/src/$b /usr/$b
do
        if [ -r "$bsd_copyright" ]; then
                COPYRIGHT=`sed \
                    -e "s/\[year\]/1992-$year/" \
                    -e 's/\[your name here\]\.* /The FreeBSD Project./' \
                    -e 's/\[your name\]\.*/The FreeBSD Project./' \
                    -e '/\[id for your version control system, if any\]/d' \
                    $bsd_copyright` 
                break
        fi
done

# no copyright found, use a dummy
if [ X"$COPYRIGHT" = X ]; then
        COPYRIGHT="/*-
 * Copyright (c) 1992-$year The FreeBSD Project.
 * All rights reserved.
 *
 */"
fi

# add newline
COPYRIGHT="$COPYRIGHT
"

LC_ALL=C; export LC_ALL
if [ ! -r version ]
then
        echo 0 > version
fi

touch version
v=`cat version` u=${USER:-root} d=`pwd` h=${HOSTNAME:-`hostname`} t=`date`
i=`${MAKE:-make} -V KERN_IDENT`
compiler_v=$($(${MAKE:-make} -V CC) -v 2>&1 | grep 'version')

for dir in /bin /usr/bin /usr/local/bin; do
        if [ -x "${dir}/svnversion" ] && [ -z ${svnversion} ] ; then
                svnversion=${dir}/svnversion
        fi
        if [ -x "${dir}/p4" ] && [ -z ${p4_cmd} ] ; then
                p4_cmd=${dir}/p4
        fi
done
if [ -d "${SYSDIR}/../.git" ] ; then
        for dir in /bin /usr/bin /usr/local/bin; do
                if [ -x "${dir}/git" ] ; then
                        git_cmd="${dir}/git --git-dir=${SYSDIR}/../.git"
                        break
                fi
        done
fi

if [ -n "$svnversion" ] ; then
        svn=`cd ${SYSDIR} && $svnversion`
        case "$svn" in
        [0-9]*) svn=" r${svn}" ;;
        *)      unset svn ;;
        esac
fi

if [ -n "$git_cmd" ] ; then
        git=`$git_cmd rev-parse --verify --short HEAD 2>/dev/null`
        svn=`$git_cmd svn find-rev $git 2>/dev/null`
        if [ -n "$svn" ] ; then
                svn=" r${svn}"
                git="=${git}"
        else
                svn=`$git_cmd log | fgrep 'git-svn-id:' | head -1 | \
                     sed -n 's/^.*@\([0-9][0-9]*\).*$/\1/p'`
                if [ -n $svn ] ; then
                        svn=" r${svn}"
                        git="+${git}"
                else
                        git=" ${git}"
                fi
        fi
        if $git_cmd --work-tree=${SYSDIR}/.. diff-index \
            --name-only HEAD | read dummy; then
                git="${git}-dirty"
        fi
fi

if [ -n "$p4_cmd" ] ; then
        p4version=`cd ${SYSDIR} && $p4_cmd changes -m1 "./...#have" 2>&1 | \
                awk '{ print $2 }'`
        case "$p4version" in
        [0-9]*)
                p4version=" ${p4version}"
                p4opened=`cd ${SYSDIR} && $p4_cmd opened ./... 2>&1`
                case "$p4opened" in
                File*) ;;
                //*)    p4version="${p4version}+edit" ;;
        if [ -x "${dir}/p4" ] && [ -z ${p4_cmd} ] ; then
                p4_cmd=${dir}/p4
        fi
done
if [ -d "${SYSDIR}/../.git" ] ; then
        for dir in /bin /usr/bin /usr/local/bin; do
                if [ -x "${dir}/git" ] ; then
                        git_cmd="${dir}/git --git-dir=${SYSDIR}/../.git"
                        break
                fi
        done
fi

if [ -n "$svnversion" ] ; then
        svn=`cd ${SYSDIR} && $svnversion`
        case "$svn" in
        [0-9]*) svn=" r${svn}" ;;
        *)      unset svn ;;
        esac
fi

if [ -n "$git_cmd" ] ; then
        git=`$git_cmd rev-parse --verify --short HEAD 2>/dev/null`
        svn=`$git_cmd svn find-rev $git 2>/dev/null`
        if [ -n "$svn" ] ; then
                svn=" r${svn}"
                git="=${git}"
        else
                svn=`$git_cmd log | fgrep 'git-svn-id:' | head -1 | \
                     sed -n 's/^.*@\([0-9][0-9]*\).*$/\1/p'`
                if [ -n $svn ] ; then
                        svn=" r${svn}"
                        git="+${git}"
                else
                        git=" ${git}"
                fi
        fi
        if $git_cmd --work-tree=${SYSDIR}/.. diff-index \
            --name-only HEAD | read dummy; then
                git="${git}-dirty"
        fi
fi

if [ -n "$p4_cmd" ] ; then
        p4version=`cd ${SYSDIR} && $p4_cmd changes -m1 "./...#have" 2>&1 | \
                awk '{ print $2 }'`
        case "$p4version" in
        [0-9]*)
                p4version=" ${p4version}"
                p4opened=`cd ${SYSDIR} && $p4_cmd opened ./... 2>&1`
                case "$p4opened" in
                File*) ;;
                //*)    p4version="${p4version}+edit" ;;
                esac
                ;;
        *)      unset p4version ;;
        esac
fi
        

cat << EOF > vers.c
$COPYRIGHT
#define SCCSSTR "@(#)${VERSION} #${v}${svn}${git}${p4version}: ${t}"
#define VERSTR "${VERSION} #${v}${svn}${git}${p4version}: ${t}\\n    ${u}@${h}:${d}\\n"
#define RELSTR "${RELEASE}"

char sccs[sizeof(SCCSSTR) > 128 ? sizeof(SCCSSTR) : 128] = SCCSSTR;
char version[sizeof(VERSTR) > 256 ? sizeof(VERSTR) : 256] = VERSTR;
char compiler_version[] = "${compiler_v}";
char ostype[] = "${TYPE}";
char osrelease[sizeof(RELSTR) > 32 ? sizeof(RELSTR) : 32] = RELSTR;
int osreldate = ${RELDATE};
char kern_ident[] = "${i}";
EOF

echo $((v + 1)) > version

I noticed it says
Code:
FreeBSD: head/sys/conf/newvers.sh 246246 2013-02-02
That date differs from the one I got from uname -a, which is Thu Jul 26 12:49:04 ART 2012. Should those dates be the same?
 
Look at the TYPE, REVISION and BRANCH variables. The source you have is for 10-CURRENT.
 
Solved! I just installed 9.1-RELEASE and now it works like a charm.

Just a question,though: I'm currently about to start working on some drivers for the 10.0 release. Where can I get the sources?
 
Back
Top