How to make an embedded Linux device driver (1)

First time: Build environment preparation and simple kernel module creation

About this series

This is a HowTo article for developing embedded Linux device drivers as kernel modules. All the content of this article can be run on a Raspberry Pi.

I think the first step in Linux driver development is difficult. There aren't many materials available, and I think most people will be frustrated by trying out O'Reilly books. (I was ...)

In this article, I will proceed according to the contents of "Linux Device Driver Programming (Yutaka Hirata)". I think this book is very easy to understand and good. However, since it was published in 2008 and is old, I will check it while actually running it on the Raspberry Pi so that it will work in the current environment (December 2017). (From the middle, it will be separated from the contents of the book)

Also, I wanted to make it as easy as possible, so I will not prepare a cross development environment and will develop with the Raspberry Pi itself. Therefore, no matter what the host OS is, those who have Raspberry Pi can try it immediately. (The development style of coding on a host PC such as Windows and transferring it to Raspberry Pi by SFTP is recommended.)

--__ 1st time: Build environment preparation and simple kernel module creation <-------------- ------- Contents of this time __ -Second time: System call handler and driver registration (static method) -Third time: System call handler and driver registration (dynamic method) -4th: Read / write implementation and memory story -5th time: Implementation of GPIO driver for Raspberry Pi -6th time: Implementation of ioctl -7th time: Interface for procfs -8th time: Interface for debugfs -9th time: Call a function of another kernel module / Use GPIO control function -10th time: Create a device driver using I2C -11th time: Add I2C device to device tree -12th time: Load the created device driver at startup

Contents of this time

First, let's prepare the environment and create a simple kernel module.

The entire source code that appears in this article

https://github.com/take-iwiw/DeviceDriverLesson/tree/master/01_01 https://github.com/take-iwiw/DeviceDriverLesson/tree/master/01_02

environment

Preparing the environment

As mentioned at the beginning, we will develop on Raspberry Pi. In other words, build in the native environment. Therefore, basically you can use gcc on Raspberry Pi as it is, so you should not need any preparation. However, headers etc. are required to access the kernel functions. Install with the following command. This will install the complete header and makefile for the build here (/usr/src/linux-headers-4.9.41-v7+/). Also, a symbolic link to here will be created here (/lib/modules/4.9.41-v7+/build). (This directory is for my environment)

sudo apt-get install raspberrypi-kernel-headers

That's all there is to it, as it doesn't build the entire kernel.

Make a simple kernel module

Write code

First, let's write only the behavior when the kernel module is loaded (insmod) and unloaded (rmmod). It's like Hello World. Name the file test.c. Specify the entry point for insmod with module_init and the entry point for rmmod with module_exit. Since printf cannot be used in the kernel, printk is used.

test.c


#include <linux/module.h>

static int test_init(void)
{
	printk("Hello my module\n");
	return 0;
}

static void test_exit(void)
{
	printk("Bye bye my module\n");
}

module_init(test_init);
module_exit(test_exit);

Prepare Makefile

I think that you can build the kernel module by typing the gcc command yourself, but it is troublesome to specify the include path in various ways. As mentioned above, the Makefile for build is prepared, so use it. Create a Makefile like the one below, set the source file name, and call the Makefile in / lib / modules / 4.9.41-v7 + / build. Actually, the part of 4.9.41-v7 + changes depending on the environment, so get it with the ʻuname` command.

Makefile


obj-m := test.o

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

Build and run

In the directory containing test.c and Makefile above, make. Then test.ko should be completed. After that, try loading the module with ʻinsmodand unloading the module withrmmod`.

make
sudo insmod test.ko
sudo rmmod test.ko
dmesg

Finally, let's take a look at the result output by printk with dmesg. Then, you can see that the implemented code is executed as shown below.

[ 2324.171986] Hello my module
[ 2327.753108] Bye bye my module

Notes on logs

If there is no \ n when doing printk, it doesn't seem to be output to the dmesg log. Apparently, it is outputting to the buffer for dmesg at the timing of \ n.

printk prints its contents to a buffer in memory instead of the terminal. The buffer looks like a ring buffer and will be overwritten. dmesg is just printing that buffer. It is saved as a file in cat / var / log / syslog. However, please note that it is not written to this file immediately, but it seems to be written at a reasonable frequency. In the event of a crash, it is possible that the desired log has not been written.

Build a module consisting of multiple files

This is an example of creating MyModule.ko from test01.c and test02.c. Make a Makefile like the one below. The .o file required to generate MyModule.o is specified in MyModule-objs. Therefore, the prefix for MyModule-objs must be MyModule. The resulting module can be loaded with sudo insmod MyModule.ko.

CFILES = test01.c test02.c

obj-m := MyModule.o
MyModule-objs := $(CFILES:.c=.o)

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

in conclusion

With that feeling, I will summarize it little by little. This is my study memo. If you write something wrong, please let me know.

Recommended Posts

How to make an embedded Linux device driver (11)
How to make an embedded Linux device driver (8)
How to make an embedded Linux device driver (1)
How to make an embedded Linux device driver (4)
How to make an embedded Linux device driver (7)
How to make an embedded Linux device driver (2)
How to make an embedded Linux device driver (3)
How to make an embedded Linux device driver (6)
How to make an embedded Linux device driver (5)
How to make an embedded Linux device driver (10)
How to make an embedded Linux device driver (9)
How to make an embedded Linux device driver (12) (Complete)
[Blender x Python] How to make an animation
How to make Linux compatible with Japanese keyboard
How to make Yubico Yubikey recognized in Manjaro Linux
How to make an interactive CLI tool in Golang
How to make an HTTPS server with Go / Gin
[Python] How to make an adjacency matrix / adjacency list [Graph theory]
How to make a hacking lab-Kali Linux (2020.1) VirtualBox 64-bit Part 2-
How to make a hacking lab-Kali Linux (2020.1) VirtualBox 64-bit edition-
How to make a Python package (written for an intern)
How to create an ISO file (CD image) on Linux
How to make a Japanese-English translation
How to make a slack bot
How to install wkhtmltopdf (Amazon Linux2)
How to create an email user
How to install VMware-Tools on Linux
How to make a crawler --Advanced
How to make a recursive function
How to install MBDyn (Linux Ubuntu)
How to make a deadman's switch
[Blender] How to make a Blender plugin
[Blender] How to make Blender scripts multilingual
How to make a crawler --Basic
How to build MongoDB C driver
How to check Linux OS version
How to make a string into an array or an array into a string in Python
How to get the printer driver for Oki Mac into Linux
How to make Word Cloud characters monochromatic
How to make Selenium as light as possible
[Linux] How to subdivide files and folders
How to make an artificial intelligence LINE bot with Flask + LINE Messaging API
How to install aws-session-manager-plugin on Manajro Linux
[Python] How to make a class iterable
python3 How to install an external module
How to create an NVIDIA Docker environment
How to convert Python to an exe file
I want to know how LINUX works!
[Linux] How to use the echo command
How to use the Linux grep command
How to update php on Amazon linux 2
How to display emoji on Manjaro Linux
How to install packages on Alpine Linux
[Cocos2d-x] How to make Script Binding (Part 2)
How to install Anisble on Amazon Linux 2
How to operate Linux from the console
How to install Windows Subsystem For Linux
How to power off Linux with Ultra96-V2
How to update security on CentOS Linux 8
I want to make an automation program!
How to install php7.4 on Linux (Ubuntu)