After two weeks of exploration, I finally had a preliminary understanding of the development of Linux device drivers. Next I will make a summary of the establishment of the development environment for Linux device drivers to facilitate future queries, it also helps beginners of the same path.
When users are new to Linux drivers, they often don't know how to compile the driver, let alone how to compile the driver into the kernel or load the test. Generally, you need to find the simplest helloworld driver on the Internet and compile it strictly according to the steps mentioned on the Internet, but the result is a lot of errors you have never seen before, let alone solve the problem based on the error message. Many people do not know how to proceed here. Ten days ago, I got stuck here for a long time. Now I know what it is, so I can write it down. It may be helpful to some Evangelists.
A basic Linux device driver development environment consists of the host machine and the target machine. The host machine is used for driver development, and the target machine is used to run and test the device driver, development tools (GCC, GDB, make, and so on) and Linux source code (the version must correspond to the Linux Kernel on the target machine) are required on the host machine, and the target machine only needs to run Linux. Due to the different steps, the following describes how to build the environment and compile the driver in two scenarios: general Linux device driver development and embedded Linux device driver development:
(1) General Linux device driver development
General Linux is mainly divided into embedded Linux (generally uClinux). In this development, the host machine and the target machine can be a host, that is, develop and compile on the local machine and load and run on the local machine (Linux device drivers can also be directly compiled into the kernel, but dynamic loading is generally used for the convenience of development ), of course, it can also be two hosts. If it is two hosts, you must ensure that the Linux source code version on the host is consistent with the Linux kernel version on the target host. To develop a driver for a common Linux device, follow these steps:
- Install the development tool on the host machine and download the Linux source code (the version must be the same as the Linux kernel version on the target machine ). Development tools include GCC, GDB, and make. These tools are installed by default in RedHat or FC. you can install them in Debian or Ubuntu by using the following command:
apt-get install build-essential
Linux source code can be obtained through the following channels:
- Go directly to www.kernel.org to download
- Use the package management tool to download the source code. In Debian and Ubuntu, you can use the following command to download the source code,
Apt-Get install linux-source-(Version)
, The downloaded file is in the/usr/src directory, and you can decompress it to this directory.
Decompress the source code to the/usr/src/directory and go to the Linux-source-(Version Number) directory to execute the following commands:
make oldconfig
make prepare
make scripts
- Write a Linux driver. Take the simplest hello. C as an example. The content of Hello. C is as follows:
#include "linux/init.h"
#include "linux/module.h"
static int hello_init(void)
{
printk(KERN_ALERT "Hello World linux_driver_module/n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbey linux_driver_module/n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("lpj");
- Write the MAKEFILE file. For example, the parameters in the makefile are changed according to the actual situation:
#sample driver module
obj-m := hello.o
KDIR = /usr/src/linux-source-2.6.24/
all:
$(MAKE) -C $(KDIR) M=$(PWD)
.PHONY:clean
clean:
rm -f *.mod.c *.mod.o *.ko *.o *.tmp_versions
- Compile: Execute make in the directory where hello. C and makefile are located. After compilation, generate the hello. Ko file in the current directory.
- Load and test: Use the insmod or modprobe command to load the file. For example, run the following code in the current path:
Insmod hello. Ko or modprobe hello
Note: If the kernel is loaded on the virtual terminal, the kernel printing information will not be displayed, because the kernel printing information will not be output to the virtual terminal, but to the/proc/kmsg file, you can view the kernel information in the following ways:
cat /proc/kmsg
Will always print, need Ctrl-C to manually terminate
Dmesg or dmesg | tail-n
, N is a number, indicating that the last n rows are displayed.
- Uninstall: run the rmmod command to uninstall the driver module, as shown in figure
rmmod hello
(2) development of embedded Linux Device Drivers
In this development, the general target machine is a development board with an embedded processor, while the host machine is a PC, and the development environment needs to be built on the host machine. The steps for developing an embedded Linux device driver are as follows:
- Download the source code of Embedded Linux on the host machine and install the embedded Linux development tool (for different embedded processors, the tool is also different, such as the arm-GCC series corresponding to arm, nios2-cc series for nios2 processors)
- Compile the driver program for the Linux device. For example, copy the file to the (Linux source code directory)/Drivers/(target folder )/.
- Create makefile and kconfig in the (target folder). The contents are as follows:
#makefile
obj-$(CONFIG_HELLODRV) += hello.o
#Kconfig
menu USER_DEVICE_DRIVERS
config HELLODRV
tristate "Hello"
---help---
This is a sample driver programme.
endmenu
Note: If the "tristate" in the kconfig file is written as "bool", this module can only be selected as Y (compiled into the kernel) or N (not selected), and cannot be selected as M (compiled as a module, can be dynamically loaded)
- Modify the makefile and kconfig files in the upper-level directory (Linux kernel source code directory/Drivers/). Add the following statement to the makefile:
# Makefile
OBJ-y + = (target folder)
(There are multiple writing methods here, which is only one of them)
Add the following statement to kconfig:
# Kconfig
Source "Drivers/(target folder)/kconfig"
- Compile the kernel: Several Basic commands and selection interfaces are as follows:
make menuconfig
After performing this step, you will see the following interface:
Where vendor/product... is to select the processor manufacturers and models, kernel/library... is to configure the application, press the Space key or enter the option to configure, use the up and down key to move to the kernel/library... on the menu, Press space or enter to enter the following Kernel configuration interface:
There are two mimize... option. The first option is to select the custom configuration kernel, and the second option is to select a custom configuration application. You can select these options by pressing the Space key, and then press the exit key to exit, select "yes" when selecting whether to save. If the first mimize... is selected ..., after exiting, The Kernel configuration page is automatically displayed, for example:
There are many options on this interface. If you want to configure the driver module, use the up/down key to move it to device drivers and press ENTER or space key to enter the device driver configuration interface, as shown in the following figure:
Here is the content in linux-2.X/Drivers/kconfig, the following green V (+) indicates that this page is not displayed, you can continue browsing with the next key, find our own menu name and press ENTER or space to enter. The module configuration interface is as follows:
Use the M key to display m in the brackets before the option to indicate that the module needs to be dynamically loaded. You can also press the y key to directly edit it into the kernel. After the selection, exit and exit, in the Select Yes or No dialog box, select YES.
make romfs
# This step must be performed before the first kernel Compilation
make
- Load Test: Download the generated zimage file to the Development Board. After the embedded Linux on the Development Board is started, you can use insmod or modprobe to load the driver module. After the test, you can run the rmmod command to uninstall the driver module.