When Should I Write a Linux Kernel Module

What would you write kernel module for?

what would you want to be a kernel module?

Although most people associate kernel modules (only) with device drivers, other kernel services such as filesystems and network protocol handlers can also be built as modules.

The primary rationale for a kernel module versus static linkage (i.e. built in the kernel) is for runtime configurability (which in turn improves memory efficiency). Optional features, services and drivers can be left out of the kernel that is booted, but can still be loaded later when needed.

The overhead of loading the module, the storage space required by the module (the kernel is usually stored in compressed form whereas the module is not compressed) and the fragment of a memory page wasted by each module are usually considered acceptable tradeoffs.

What kind of tasks are best done as a kernel module compared to using syscalls and doing stuff?

This a separate question not really related to the previous. You should actually be comparing user-mode versus kernel-mode. Whether the kernel-mode uses a module (that has to be loaded) or statically linked code (that is always available) is not a significant aspect to the actual question. (The other answer that mentions a "a small performance penalty when running module code due to the virtual memory overhead" is incorrect.)

A user-mode service or driver has the advantages of:

  • Usually easier and quicker to implement (no need to build and install the kernel). Most C programmers learn (only) with the C runtime library, so the kernel environment instead of user-mode could be a learning experience.

  • Easier to control proprietary source code. May be exempt from the GNU GPL.

  • The restricted privileges are less likely to inadvertently take down the system or create a security hole.

A kernel-mode service or driver has the advantages of:

  • Availability to more than one program in the system without messy exclusion locks.

  • Device accessibility can be controlled by file permissions.

  • Status of the device or service is continuous and available as long as the system is running. A user-mode driver would have to reset the device into a known quiescent state everytime the program started.

  • More consistent/accurate timers and reduced event latency.

An example of user-mode versus kernel-mode is the Reliable Datagram Sockets that was added to the Linux kernel in version 2.6.30. Previously RDS was a user-mode protocol based on UDP but enhanced with "acking / windowing / fragmenting / re-ordering, etc". Under heavy loads the timers of the user-mode protocol were not accurate, so additional retransmissions and dropped messages caused stability and performance issues. A switch to a kernel-mode network protocol was intended to improve/solve such issues.

However there are pitfalls (or a responsibility) to kernel mode. Kernel code is responsible for ensuring the integrity and security of the system. RDS was found to introduce a security hole in the kernel.

Why would logging be done from kernel, rather then doing it is userspace?

There could be several reasons, but also for this example it would be likely that the log requestors would be in kernel mode rather than user mode, so this would avoid awkward mode switching.

How safe is that to develop a simple linux kernel module/driver on my own machine?

I had these issues when I started writing device drivers.

  1. System hangs - These happen to every kernel newbie. They're caused by the Linux kernel is doing useless work repeatedly. You won't even be able to move the mouse.
  2. Kernel crashes - Messages like 'System program problem detected' appear when you boot into your system again.
  3. As you start writing advanced drivers like network device drivers, your Ethernet or wireless cards may stop working. Restarting your system might fix this issue, but it might not.

A real kernel developer doesn't mess around with VMs. Don't be afraid to test and code on real machine. I compiled a separate kernel exclusively for testing device drivers. I have one kernel for testing and another for application programming.

If you want to test drivers on a newly built kernel, this is a nice guide on installing a new kernel.

Linux Kernel Threads : How to pass the Linux module write function as the function that the thread has to execute?

You can't. Your thread function has to use this format:

int my_thread_function(void *data)

You can call it whatever you want - it doesn't have to be called my_thread_function - and the parameter doesn't have to be called data but it does have to be a void *.

This will not work:

ssize_t exer_write(struct file *pfile, const char __user *buffer, size_t length, loff_t *offset)

I suggest writing a new function to be your thread function:

int exer_write_in_thread(void *data) {
exer_write(???, ???, ???, ???);
return 0;
}

Obviously you have to figure out what arguments you want to call exer_write with.

How to write Linux kernel module that is a new instance in each network namespace?

Linux Kernel modules have only one state. Network namespaces need to be explicitly handled in the kernel module.

The key methods to use are register_pernet_subsys, unregister_pernet_subsys and net_generic.

Here is an example kernel module:

#include <net/sock.h>
#include <net/netns/generic.h>
#include <net/net_namespace.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/pid_namespace.h>

/*
* Per network namespace data
*/
struct ns_data {
struct sock *sk;
};

/*
* Index to store custom data for each network namespace.
*/
static unsigned int net_id;

/*
* Called for every existing and added network namespaces
*/
static int __net_init ns_test_init(struct net *net)
{
// create (if not present) and access data item in network namespace (net) using the id (net_id)
struct ns_data *data = net_generic(net, net_id);
data->sk = -1; // initialize or example socket

// ...

return 0;
}

static void __net_exit ns_test_exit(struct net *net)
{
// called when the network namespace is removed
struct ns_data *data = net_generic(net, net_id);

// close socket
netlink_kernel_release(data->sk);
}

// callback to make the module network namespace aware
static struct pernet_operations net_ops __net_initdata = {
.init = ns_test_init,
.exit = ns_test_exit,
.id = &net_id,
.size = sizeof(struct ns_data),
};

static int __init netlink_test_init(void)
{
printk(KERN_INFO "netlink_test: Init module\n");

register_pernet_subsys(&net_ops);

return 0;
}

static void __exit netlink_test_exit(void)
{
printk(KERN_INFO "netlink_test: Exit module\n");

unregister_pernet_subsys(&net_ops);
}

module_init(netlink_test_init);
module_exit(netlink_test_exit);

MODULE_LICENSE("GPL");

Linux Kernel Module ignores main module file when an additional source file is added

The line

obj-m += mymodule.o

tells KBuild system just to build a module named mymodule.

The sources compiled into that module depend from variable mymodule-y:

  • If the variable is set (like in your code), then source list it taken only from this variable. There is no "automatic" addition of mymodule.c source.
  • If the variable is not set, then, by default, the module is compiled from the source which has the same name.

Note, that one cannot build a module mymodule from several sources, one of which is mymodule.c, that is has the same name as the module itself.
Either module or the source file should be renamed. That situation is described in that question.



Related Topics



Leave a reply



Submit