# Basic Hello World module won't load



## Phillipe (Sep 10, 2013)

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:


```
#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:


```
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:

```
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`:

```
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`:

```
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!


----------



## SirDice (Sep 10, 2013)

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.


----------



## Phillipe (Sep 10, 2013)

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?


----------



## SirDice (Sep 10, 2013)

Phillipe said:
			
		

> How can I check if my /usr/src is the same version as the rest of my system?


Tricky. But have a look at the /usr/src/sys/conf/newvers.sh file.


----------



## ShelLuser (Sep 10, 2013)

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.


----------



## SirDice (Sep 10, 2013)

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.


----------



## Phillipe (Sep 10, 2013)

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:


```
#!/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 
	
	



```
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?


----------



## SirDice (Sep 10, 2013)

Look at the TYPE, REVISION and BRANCH variables. The source you have is for 10-CURRENT.


----------



## Phillipe (Sep 13, 2013)

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?


----------

