BullseyeCoverage Up Contents Search

Linux Kernel Modules

BullseyeCoverage uses the small footprint run-time configuration for Linux kernel modules. With this configuration, you must perform a post-processing step to update coverage into the coverage file, as described below.

Kernel Module Initialization

An initialization entry point and an exit entry point must be defined in one of the source files in each kernel module. 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 kernel module initialization helper macro provided by Linux. For example, a USB driver may use module_usb_driver rather than module_init and module_exit.

Building Kernel 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 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 kernel module from /proc/BullseyeCoverage.data-n. For example:

$ covpost /proc/BullseyeCoverage.data-*

For kernel 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

These commands demonstrate instrumenting, running, getting code coverage of a simple kernel module.

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: 23 Apr 2025