BullseyeCoverage Up Contents Search

Linux Kernel Modules

This information applies to Linux kernel version 2.6 and later.

Module Initialization

To measure coverage of a Linux kernel module, an initialization entry point and an exit entry point must be defined. This can be accomplished with the module_init and module_exit macros, as shown below.

static int __init m_init(void)
{
    return 0;
}

static void __exit m_exit(void)
{
}

module_init(m_init)
module_exit(m_exit)

Alternatively, the entry points can be defined using a module initialization helper macro provided by Linux. For example, a USB driver may use module_usb_driver rather than module_init and module_exit.

Build Your Modules

  1. Put BullseyeCoverage/bin at the front of the PATH environment variable.
  2. If needed, create an interceptor for your compiler. This step is only necessary if you are cross-compiling.
  3. Enable BullseyeCoverage with cov01 -1
  4. Build as you normally do

For example:

$ PATH=/opt/BullseyeCoverage/bin:$PATH
$ cov01 -1
$ make -C linux-x.y.z M=`pwd` ... modules

Run-Time Library Built Automatically

BullseyeCoverage automatically compiles and adds the run-time source BullseyeCoverage/run/libcov-linuxKernel.c when compiling a source that defines a Linux kernel module initialization function. This source implements the small footprint configuration.

Saving Coverage

When an instrumented kernel module is unloaded, BullseyeCoverage writes a file named /var/tmp/BullseyeCoverage.data-n. Use the covpost command to transfer measurements to the coverage file. For example:

$ covpost /var/tmp/BullseyeCoverage.data-*
$ rm /var/tmp/BullseyeCoverage.data-*

You can retrieve measurements from a loaded module from /proc/BullseyeCoverage.data-n. For example:

$ covpost /proc/BullseyeCoverage.data-*

For modules that run on embedded or remote devices, copy the files above to the host computer, then process them with covpost.

If a read error occurs on /proc/BullseyeCoverage.data-*, use the command dmesg to see additional diagnostic information.

$ dmesg | tail

Example Commands on Ubuntu 21.04

user@ubuntu:~$ export COVFILE=`pwd`/test.cov
user@ubuntu:~$ cd BullseyeCoverage/sample/linuxKernel/
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ cov01 -1 -q
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ make -C /usr/src/linux-headers-5.11.0-17-generic/ M=`pwd` modules
make: Entering directory '/usr/src/linux-headers-5.11.0-17-generic'
  CC [M]  /home/test/BullseyeCoverage/sample/linuxKernel/hello.o
BullseyeCoverage Compile 9.12.0 Linux-x64, Copyright (c) Bullseye Testing Technology
  MODPOST /home/test/BullseyeCoverage/sample/linuxKernel/Module.symvers
  CC [M]  /home/test/BullseyeCoverage/sample/linuxKernel/hello.mod.o
BullseyeCoverage Compile 9.12.0 Linux-x64, Copyright (c) Bullseye Testing Technology
  LD [M]  /home/test/BullseyeCoverage/sample/linuxKernel/hello.ko
  BTF [M] /home/test/BullseyeCoverage/sample/linuxKernel/hello.ko
Skipping BTF generation for /home/test/BullseyeCoverage/sample/linuxKernel/hello.ko due to unavailability of vmlinux
make: Leaving directory '/usr/src/linux-headers-5.11.0-17-generic'
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ sudo insmod hello.ko
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ sudo dmesg | tail -n 1
[ 1544.412224] hello world
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ covpost -q /proc/BullseyeCoverage.data-*
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ covfn -q
Function      Source        Line      Function Coverage           C/D Coverage
------------  ------------------  ---------------------  ---------------------
m_exit(void)  hello.c         12       0 /     1 =   0%       0 /     0
m_init(void)  hello.c          6       1 /     1 = 100%       0 /     0
------------  ------------------  ---------------------  ---------------------
Total                                  1 /     2 =  50%       0 /     0
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ sudo rmmod hello
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ sudo dmesg | tail -n 1
[ 1681.455681] goodbye world
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ covpost -q /var/tmp/BullseyeCoverage.data-*
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ sudo rm /var/tmp/BullseyeCoverage.data-*
user@ubuntu:~/BullseyeCoverage/sample/linuxKernel$ covfn -q
Function      Source        Line      Function Coverage           C/D Coverage
------------  ------------------  ---------------------  ---------------------
m_init(void)  hello.c          6       1 /     1 = 100%       0 /     0
m_exit(void)  hello.c         12       1 /     1 = 100%       0 /     0
------------  ------------------  ---------------------  ---------------------
Total                                  2 /     2 = 100%       0 /     0

Updated: 11 Oct 2023