DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Observability With eBPF
  • extended Berkeley Packet Filter (eBPF) for Cloud Computing
  • Advanced Linux Troubleshooting Techniques for Site Reliability Engineers
  • Introduction to KVM, SR-IOV, and Exploring the Advantages of SR-IOV in KVM Environments

Trending

  • The Full-Stack Developer's Blind Spot: Why Data Cleansing Shouldn't Be an Afterthought
  • Metrics at a Glance for Production Clusters
  • Data Quality: A Novel Perspective for 2025
  • Endpoint Security Controls: Designing a Secure Endpoint Architecture, Part 2

Linux Kernel Module Programming — Simplest Example

Let's write a simple Linux kernel hello world module, and try to understand all the basic things defined in that program.

By 
Sachith Muhandiram user avatar
Sachith Muhandiram
·
Sep. 30, 20 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
5.4K Views

Join the DZone community and get the full member experience.

Join For Free

Today lets talk about how to write a simple Linux kernel module. Let's write a simple hello world module, and try to understand all the basic things defined in that program. For this guide, I assume you have a basic understanding.

  • C programming language
  • Makefiles

As you already know, we use C — Programming language to write Linux kernel modules. But we can not use normal C syntax for some cases in kernel module programs. All official guide can be found here. Please go through it if you are not familiar.

This is one of the basic hello-world type Linux kernel module.

C
 




x
16


 
1
#include <linux/init.h>
2
#include <linux/module.h>
3
#include <linux/kernel.h>
4
MODULE_LICENSE("GPL");
5
MODULE_AUTHOR("Sachith Muhandiram");
6
MODULE_DESCRIPTION("Simple first Linux module");
7
MODULE_VERSION("1.0.0");
8
static int __init initHelloWorld(void){
9
    printk(KERN_INFO "Hello, this is my first kernel module \n");
10
    return 0;
11
}
12
static void __exit exitHelloWorld(void){
13
    printk(KERN_INFO "Exit Hello world module\n");
14
}
15
module_init(initHelloWorld);
16
module_exit(exitHelloWorld);



Let's get started with the header files we included for this, why, and what they do.

Makefile to generate the respective kernel module.

C
 




xxxxxxxxxx
1


 
1
obj-m += hello.o
2
all:
3
 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
4
clean:
5
 make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean



Let's start with the header files we included.

linux/init.h

No wonder about its name and functionality, this header file includes all things related to __init part. This provides you a detailed guide about how it works.

linux/module.h

This is where module_init and module_exit are defined. module_init tells the kernel what is the entry point to our program and also only one module_init call for the program we write. As the official comment says

module_init() will either be called during do_initcalls() (if * builtin) or at module insertion time (if a module)

module_exit does the opposite, when we call rmmod module , this will be a trigger and this calls to our __exit function. Only one module_exit for a program. If the driver is statically compiled into the kernel, module_exit() has no effect. (official doc)

linux/kernel.h

This is where all the workload happening features are listed.

Macros

Above we have defined 4 macros. Those are mainly used for identifying our module. Here one most the most important macro is MODULE_LICENSE(“GPL”); , if we do not define this, we won't be able to use any other system libraries running under GPL license. For this simplest sample, this won't be a big issue, but when we develop a kernel driver, etc, this could be a big issue. So always remember to keep GPL license if you need to get GPL licensed libraries.

Also if you release your module, then you must select appropriate licensing to your module, and in that case, you would have to use static linking to GPL licensed libraries. For more about GPL-license.

The other three macros are just basics, used to identify our module.

__init functionName(param)

This is the initialization point for the module. This feature is enabled kernel 2.2 . The compiler specially treats this function and add this at the beginning of the executable file.

Linux kernel will allocate memory for each __init and free memory used by this after __init function finishes for buildin drivers, for loadable modules, it keeps till we unload the module. (we use the second method). For more information please refer to this.

This and __exitfunctions are also macros. init returns 0 to the kernel if success.

__exit functionName(param)

This macro is used to free up resources hold by a module. Similar to init functionality. This works as a cleanup for the loadable module we wrote, build-in device drivers do not need exit function to cleanups.

module_init(functionName)

This is the entry point to our kernel module. We define our desired entry function as a parameter. This tells the kernel what our module’s functionality and setup kernel to run the module’s functionalities when the kernel needs.

This registers our functionality to kernel. After this function completes, our module does nothing till kernel requests to do something.

module_exit(functionName)

This is the opposite of module_init . It unregisters our module functionality from the kernel. This is get called when rmmod ourModule is called.

printk(KERNEL_LOGLEVEL,”msg”,ARG)

This is basically for logging kernel info, it has different logging levels. INFO ,WARN,EMERG, ALERT, CRIT, ERR etc. You can see all details such as what are default numbers assigned to these macros etc from this.

Also, this makes sure our message is printed to /var/log/messages .

Here I won't describe how Makefile . When we run make it creates all necessary modules, libraries for our module.

To add our module to the kernel, we use insmod ./hello.ko (as our makefile creates outputs as hello . This .ko is the file that holds our module.

When this is loaded, you won't see anything at the terminal. As described earlier, it is printed to the kernel log. dmesg -w will show our module is loaded. and it will have a record saying Hello, this is my first kernel module

To remove our module from the kernel, we use rmmod hello , here we do not need to provide any file extension, just use our module name. This will invoke module_exit function.

I think this is enough for today, I highly recommend you to read the programming guide book I have included in references.

This post was originally posted on my Medium page.

References:

Linux Kernel Module Programming Guide

Description of kernel.printk values

Where exactly is the file Linux/kernel.h?

Linux kernel

Opinions expressed by DZone contributors are their own.

Related

  • Observability With eBPF
  • extended Berkeley Packet Filter (eBPF) for Cloud Computing
  • Advanced Linux Troubleshooting Techniques for Site Reliability Engineers
  • Introduction to KVM, SR-IOV, and Exploring the Advantages of SR-IOV in KVM Environments

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!