Create Linux Kernel Module With Parameters

I stumbeled upon linux kernel module parameters when I came across v4l2loopback. There you can create multiple virtual loopback devices with specific numbers using the kernel module parameters.

for example as v4l2loopback documentation says.

if you need several independent loopback devices, you can pass the “devices” option, when loading the module; e.g.

# modprobe v4l2loopback devices=4

will give you 4 loopback devices (e.g. /dev/video1/dev/video5)

you can also specify the device IDs manually; e.g.

# modprobe v4l2loopback video_nr=3,4,7

will create 3 devices (/dev/video3, /dev/video4 & /dev/video7)

In this post I’ll be writing about how to create your own kernel module that takes some input parameters. So let’s get started.

Regular programs can take command line arguments using argc/argv, linux kernel module can not do that. In order to take input parameters at load time the kernel module uses a macro called module_param which takes three arguments

Let’s see some code.

#include <linux/module.h>       // this you need to crate a kernel module
#include <linux/moduleparam.h>  // Not necessary, but good if you want to make it explicit.
static int dest_port = 80;
module_param (dest_port, int, 0660);

In this cae we have used an int for the parameter, module parameters can have a number of different types such as int, uint, short, ushort, long, bool and a few others, all defined in the header file <linux/moduleparam.h>.

So the sample code (mod-args.c) for this looks like following

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/kernel.h>

static int dest_port = 10;
module_param (dest_port, int, 0660);

static int __init mod_args_init (void)
{
    printk (KERN_INFO "hello.... dest_port=%d \n", dest_port);
    return 0;
}

static void __exit mod_args_cleanup (void)
{
    printk (KERN_INFO "bye dest_port=%d \n", dest_port);
}

MODULE_LICENSE ("GPL");
MODULE_AUTHOR ("Girish Joshi");
MODULE_DESCRIPTION ("Linux Kernel Module with parameters.");

module_init (mod_args_init);
module_exit (mod_args_cleanup);

The Makefile looks like

obj-m += mod-args.o

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Once you make it, you can pass the paramter as follows.

$ sudo insmod mod-args.ko dest_port=81

On can see the output using dmesg

$ dmesg
......
......
......
[108014.295063] hello.... dest_port=81 

While removing the module

$ sudo rmmod mod-args
$ dmesg
.....
.....
.....
[108014.295063] hello.... dest_port=81 
[108296.247945] bye dest_port=81 

At this point we can see while remving the module; value of dest_port is same as it was when we did insmod. We can even change the kernel module parameter values on the fly, that’s when the permission/access right value provided to module_param macro comes into the picture.

I’ll be writing about access rights for kernel modules in the next post.