Kernel Module Definition .mdef

This topic provides details about Legato AF's Kernel Module Definition file.

The .mdef files support 2 methods of building drivers within the Legato AF.

  1. Using pre-built to bundle kernel module binary files.
  2. Using sources to make and bundle .c files into a kernel object.

Each method will bundle the kernel module into the system definition (when called in the .sdef) and will be installed on the target when the system is updated.

Note
The .mdef must contain either a source or a preBuilt section, not both.

.mdef files contain the following sections:

sources

The sources: section specifies the path of the source code that is required to build the kernel module binary file. This will build a .ko file from the source

Building a driver using sources:

sources:
{
mangoh_iot.c
green.c
eeprom.c
}

preBuilt

The preBuilt: section specifies the path to the pre-built kernel module binary file. The module binary file specified must have an extension .ko.

Building a kernel module binary file from /path/to/module/hello.ko:

preBuilt:
{
/path/to/kernel/module/hello.ko
}

externalBuild

Specifies a list of commands required to build a kernel module using an external build process. These commands will be executed in order by the shell.

If externalBuild: section is used in a module, the sources: section cannot be used.

A common use is to create a Makefile and to run the Makefile using an external build process. To use the module built from externalBuild section, list the module object in the preBuilt section.

For example, suppose hello.ko module is built using a Makefile. Specify the make command in the externalBuild section and list the built module object in the preBuilt section.

externalBuild:
{
"make -f $CURDIR/Makefile"
}
 
preBuilt:
{
$CURDIR/hello.ko
}

params

The optional params: section lists all module parameters that must be provided to the insmod command.

The following code sample will execute this command insmod <module> param1=value1 param2=value2 …:

params:
{
param1 = "value1"
param2 = "value2"
}

The mandatory quotes (" ") around each parameter value indicate a string type.

flags

The optional cflags: and ldflags: can be added to list all options that need to be passed to the compiler and linker during the driver build.

cflags:
{
"-I/path/to/custom/includes"
}
 
ldflags:
{
"-L/path/to/custom/libs"
}

load

Specifies if the module should load automatically at start-up:

  • auto loads automatically by the Supervisor at Legato start-up.
  • manual loads when the dependent app starts. Default is auto.
load: manual

If an app is set to manual start and the app depends on a kernel module set to manual then the module will be installed only when the app is triggered to start and the module will be removed when the app is triggered to stop. For example, if app helloWorld depends on module alpha (which is set to manual load), then alpha will be installed only when helloWorld is started using app start helloWorld and alpha will be removed when helloWorld is stopped using app stop helloWorld.

bundles

Kernel modules might need additional files to work correctly. Examples of files that you would bundle with a kernel module may be binaries or firmware images. You can add files and directories in bundles: section that will be bundled with the kernel module and will be copied from the build host to the target such that they are available to the module at runtime. You can then configure the files using a script when loading and unloading the module.

bundles:
{
file:
{
$CURDIR/bin/a.bin /bin/a.bin
$CURDIR/firmware/b.img /firmware/b.img
}
 
dir:
{
$CURDIR/dir/ /dir
}
}

The build system path and target path needs to be specified for each of the files or directories. The build system path is on your dev machine where the file is located at build time. The target path is the file system path on the target where the file will appear at runtime. If the path ends with '/', it means the directory path where the source object (file or directory) will be copied. The destination object will have the same name as the source object. The default file path on the target is located at /legato/systems/current/modules/files/modulename/.

scripts

Lists the installation and removal scripts for the kernel module. It is mandatory to add a scripts: section if you have additional files bundled. The scripts must include insmod and rmmod to handle installation and removal of the modules othewise the modules will not be loaded or unloaded.

scripts:
{
    install:  $CURDIR/scripts/install.sh
    remove:   $CURDIR/scripts/remove.sh
}

install: specifies the build system path of the module installation script where the script is located at build time.

remove: specifies the build system path of the module removal script where the script is located at build time. The default script file path on the target is located at /legato/system/current/modules/files/modulename/scripts/.

Example of install.sh:

#!/bin/sh

KO_PATH=$1

insmod $KO_PATH id="first" port=0x330

Example of remove.sh:

#!/bin/sh

KO_PATH=$1

rmmod $KO_PATH
Warning
The installation script must handle the loading of the module using insmod and the removal script must handle the unloading of the module using rmmod.

requires

The requires: section specifies various requirements the module needs from its runtime environment.

kernelModules

Your module may depend on one or more kernel modules to load before it loads. kernelModules: section declares a list of kernel modules that a module depends on. Each entry is a path to another .mdef definition file. This section marks that the module has a requirement on a kernel module but does not add the kernel module to the Legato system. The kernel module needs to be explicitly added to kernelModules: section of your systems .sdef. After the kernel modules are added to the sdef, the modules will be bundled as a part of the parent module and installed with the Legato system. The listed modules will be installed before the parent module itself is installed. In the example below, hello and world kernel modules will be installed before its parent module is installed.

requires:
{
kernelModules:
{
$CURDIR/kernelmodule/hello
$CURDIR/kernelmodule/world
}
}

hello module might further depend on alpha module and the following requires section needs to be added to the hello module. In such case, alpha module will be loaded before hello module is loaded.

Example of requires: kernelModules: section of hello module:

requires:
{
kernelModules:
{
$CURDIR/kernelmodule/alpha [optional]
}
}

If a kernel module is marked as optional using '[optional]' tag, module load failure is ignored and no fault recovery action is taken. In the above example, module alpha is optional.

If a module is dependent on an app and is not specified as optional in the adef then fault handler kicks in which triggers fault action of each process in the app.

If a module is added at the system level in sdef and is not optional then the Legato framework restarts when module fails to load in order to attempt recovery. Please note that for the same module with module dependencies, optional tag for the modules must be the same specified in both sdef and mdef.

Warning
Cyclic dependency must be avoided when designing the kernel module hierarchy. For instance, if module 'a.mdef' is dependent on module 'x.mdef' at some point in the hierarchy then module 'x.mdef' must never be dependent on module 'a.mdef' at any point.

kernelModule

A module definition file can contain multiple source files which can be build into multiple kernel module objects instead of just building one kernel module object. Instead of creating multiple mdef files and generating module objects separately, in many cases it might be convenient to list the module objects in a single mdef and specify common module depencencies if applicable. This reduces the number of mdef files to maintain and provide an efficient way to generate multiple module objects using single mdef.

kernelModule: section defines a kernel module with the name of the kernel module in name: sub-section and the list of corresponding source files in sources: section. The list of dependency modules are listed using requires: kernelModules: section.

myModule.mdef
 
kernelModule:
{
name: myModuleA
sources:
{
myModuleA1.c
myModuleA2.c
}
}
 
 
kernelModule:
{
name: myModuleB
sources:
{
myModuleB.c
}
 
requires:
{
kernelModules:
{
myModuleA // myModuleB depends on kernel module defined above
alpha // myModuleB depends on another Legato kernel module
}
}
}
 
requires:
{
kernelModules:
{
beta // myModuleA and myModuleB both have dependency on beta
gamma // myModuleA and myModuleB both have dependency on gamma
}
}

myModule.mdef generates two kernel module object files: 'myModuleA.ko' and 'myModuleB.ko'. Both the modules have dependency on beta and gamma modules. myModuleB depends on myModuleA and alpha modules.

Please note that if the names of kernel modules are not explicity provided using name: section then default names are generated using the mdef filename and incrementing number appended to the end of the filename. In myModule.mdef file, if names 'myModuleA' and 'myModuleB' are not explicitly provided then ko files with default names 'myModule1.ko' and 'myModule2.ko' are generated. This is also true when one of the sub module is named and the other is not. For example, if myModuleB name is not specified then ko files 'myModuleA.ko' and 'myModule1.ko' are generated.

If a kernel module is a dependency to another module, provide a name for the kernel module so that it can always be referred by the specified name. In myModule.mdef file, provide a name for the first module i.e. myModuleA as the second module depends on myModuleA. Whereas, naming myModuleB might be optional as no other module is dependent on it.