
KernelModules:  Brecis Specific information about kernel loadable modules.

IMPORTANT NOTE, regarding error messages of the form "local symbol <x>
with index <y> exceeds local_symtab_size <z>" when loading modules:

    The newer releases of the GNU tools that we are using seem to have
    a "feature" where the assembler does not create ELF *.o files that
    are compatible with insmod.  The linker/loader creates compatible
    files, however.

    When using the usual methods for making modules, this only affects
    modules created from a single source file, because using "mips-ld
    -r" to create the module from the component object (.o) files
    creates a correct ELF .o file.

    The fix is to run mips-ld -r on your module before using it.

    For modules in the standard kernel tree, our makefiles complete
    this step automatically when placing the modules in the process of
    making the romdisk; look for "find root/lib/modules" in
    ../romdisk/makefile for an example of how to do this.


For the standard generic linux information about kernel modules, see
uClinux/linux/Documentation/modules.txt elsewhere in this tree.

STEP 1:  Prepare the kernel for loadable modules, and create some modules.

    You must set the kernel options correctly to allow for loadable
    modules.  At the time of this writing, modules are enabled by
    default, and the security driver (brecis_sec) is compiled as a
    module.

    In the linux directory, use "make xconfig", "make menuconfig",
    "make config", or (as a last resort) manually edit the .config
    file to enable the "Enable loadable module support" option (AKA
    CONFIG_MODULES if you are editing config directly).  Also set the
    option for drivers you want to configure as modules to "m".

    Note that if you are using the Makefile or scripts in directory
    brecis/compilescripts, such as LINUXALL, the kernel configuration in
    uClinux/linux/arch/mipsnommu/defconfig-brecis is copied to
    uClinux/linux/.config, so after making the desired changes, you must
    copy .config to uClinux/linux/arch/mipsnommu/defconfig-brecis so
    that future recompiles will not overwrite the file.

    "make LINUXALL", or the LINUXALL script will build the modules.

    For creating your own modules (ones not shipped with Linux), you
    can either incorporate your modules into the kernel source tree,
    or see below for how to build a loadable module outside of the
    kernel source tree.

STEP 2: build everything.

    In the uClinux/brecis/compilescripts directory type "make LINUXALL",
    or use the LINUXALL script, or whatever method you use to do the
    equivalent.  (Make sure your "path" is set up to point to the
    mips-gcc cross compiler found in the 
    uClinux/brecis/tools/mipsisa32-brecis-uclinux/bin directory.


STEP 3: boot the EVM board

    Covered elsewhere.

STEP 4: Loading the module.

    Run the command "insmod <module_name>".  This will install the
    module into the running kernel.

STEP 4a: Alternative method.

    If you use insmod to load your modules, you must be aware of any
    dependencies between your modules, and load them in the correct
    order.  For instance, if your module uses routines supplied by the
    brecis_sec module, you must "insmod brecis_sec" before loading
    your module.

    Linux's module utilities (modutils) provide alternative commands,
    depmod and modprobe, to solve this problem.  Depmod walks through
    the modules, figures out which modules depend on which others, and
    creates a dependency list.  Modprobe loads the desired kernel
    module, but first consults the dependency list depmod created and
    loads any other modules that the current module depends upon.

    The usual linux kernel build process runs depmod to create the
    dependency list at build time.  Unfortunately, the modutils aren't
    designed to run cross platform (i.e. figure out the dependencies
    between MIPS based .o's while running on an i386 platform).  So,
    depmod must be run on the target (EVM) before modprobe can be
    used.

    When designing your final system, you have these options to choose
    from (with disadvantages to consider in parenthesis):

        * run depmod at each boot. (takes some extra time at boot)

        * run depmod once only when the modules to be loaded changed,
          for example at upgrade time, and store the results in some
          form of non-volatile storage.  (uses up some NV space)

	* somehow as part of your build process, run depmod on a
          target system, capture the results, and incorporate them
          into your release.  (makes for a more complex build
          environment)

	* skip depmod/modprobe altogether, and handle module
          dependencies manually.  (dependencies must be handled
          manually)

    If your system will only load modules once at boot time, and leave
    them there until the next reboot, manually handling the
    dependencies would probably be the logical choice.


STEP 5. Removing the modules.

    Use either rmmod or modprobe -r to remove modules from the kernel;
    see their manual pages for more information.  (see
    uClinux/uC-src/modutils/modutils-2.4.12/man)

APPENDIX A. modutils considerations

The current port of modutils uses getopt, not getopt_long, because
getopt_long is not available in the uClinux/uC-libc library.  This
means none of the long options work.  Use the short options.

For similar reasons, sprintf() has been used in place of snprintf().
This may have opened up some chances for buffer overflow, but no
problems have been encounterd so far.  When snprintf is available, we
will be switching back to it.

APPENDIX B. compiling modules outside of the linux source tree.

This is actually quite easily done.  Look in the uClinux/brecis/secutil/
directory at the files Makefile.kmod and seckerntest.c.  These files
together create a kernel loadable module called seckerntest.o, which
can be loaded with insmod.

The tricky part is generally getting the compiler flags to match the
flags used in the kernel tree when building modules.  These are
manually set in Makefile.kmod.  If the flags ever change in the kernel
tree, we will probably have to change them here as well.

APPENDIX C.  Tainting and Licenses

If your module does not indicate that it is released under the GPL or
a compatible license, modutils will print out error messages such as
"Warning: loading <your_module>.o will taint the kernel: no license".

According to uClinux/linux/include/linux/module.h:

 * This exists for several reasons
 * 1.	So modinfo can show license info for users wanting to vet their setup 
 *	is free
 * 2.	So the community can ignore bug reports including proprietary modules
 * 3.	So vendors can do likewise based on their own policies


If you wish to indicate your module is licensed under the GPL and avoid
this warning message, place:

MODULE_LICENSE("GPL") ;

somewhere in your module's source code.

