Linux driver easy to learn notes

PC operating system: Ubuntu 16.04 LTS
Compiler: arm poky Linux gnueabi GCC 4.9.1

Based on the i.mx6 platform, the Linux driver module has been modified for some time, in which a lot of information is checked intermittently, and it feels that the knowledge is not so coherent, so it's time to start from the foundation.

1, Create a minimum driver module template

Create a hello.c file


//                           Local macro definition
#define EN_DEBUG                    1                                          /* Debug information switch */
#define PRINT(x...)                 printk(KERN_EMERG x)                       /* Improve printing level */
#define PRINT(x...)

**  Function name: DRV init
**  Function: Driver initialization function, called at load time
**  Parameter: None
**  Return: no
static int __init drv_init(void)
    PRINT("%s ------ \n", __FUNCTION__);
    return 0;

**  Function name: drv_exit
**  Function Description: i2c driver exit function, called when uninstalling
**  Parameter: None
**  Return: no
static void __exit drv_exit(void)
    PRINT("%s ------ \n", __FUNCTION__);

module_init(drv_init);                                                         /* Module initialization */
module_exit(drv_exit);                                                         /* Module unloading */

MODULE_AUTHOR("hrx");                                                          /* Module author */
MODULE_DESCRIPTION("Linux Driver");                                            /* Module description */
MODULE_VERSION("1.0.0");                                                       /* Module version */
MODULE_LICENSE("GPL");                                                         /* License that the module complies with */

Functions realized by this module

  • Loading function
  • Unloading function
  • Author, description, version, permission, etc
  • Print debug information (printk)

Print debugging explanation

  • The user layer uses the printf function
  • Linux kernel layer uses the print function
  • The Kern? Emerg macro in the print is to set the output level (this is the output level that can output debugging information directly). More definitions can be seen in the kernel \ include \ Linux \ Kern? Levels. H file.
  • If the print level is not high, you can also output the cached print information through the dmesg -c command (- c is to clear the cache after output).

2, Write Makefile

#Current directory path
PWD = $(shell pwd)

#Linux kernel root path
KERNEL_DIR = $(PWD)/../../kernel

#Driver name
DRVNAME = hello

#The obj-m option will be compiled as a module and will not be compiled into the kernel. Instead, it will generate a. ko file independently
#The obj-y option is compiled into the kernel
obj-m += hello.o


	@rm -rf *.o *.ko .*.cmd *.mod.c *.order *.symvers .tmp_versions *~


  • Kernel? Dir is the kernel directory path relative to the current Makefile.
  • **$(MAKE) * * is the macro definition of the make command, which may contain other parameters (I'm here only MAKE).
  • -C this C is uppercase. It is to switch to the kernel? Dir directory and make again.
  • **M = * * is the directory where the Linux driver source code is specified.

3, Generate driver files (*. ko)

1. Configure cross compile environment

Because I use it on the development board, I need to cross compile.
Reference resources: Configuring the imx6 cross compiling environment

2. Compile

Execute the make command to generate the. ko file.

make build

4, Loading and unloading drive

First, you need to transfer hello.ko to the development board to perform subsequent operations.

1. Load driver (insmod)

root@imx6qsabresd:/tmp# insmod hello.ko 
[ 7707.518557] drv_init ------ 

This outputs the initialization function.

2. Unload driver (rmmod)

root@imx6qsabresd:/tmp# rmmod hello.ko 
[ 7843.203066] drv_exit ------ 

This outputs the exit function.

5, View driver information

1. List loaded driver modules (lsmod)

root@imx6qsabresd:/tmp# lsmod
    Tainted: G  
hello 832 0 - Live 0x7f057000 (O)

lsmod actually reads the contents of * * / proc/modules * * file

root@imx6qsabresd:/tmp# cat /proc/modules 
hello 832 0 - Live 0x7f057000 (O)

2. Drive loading information storage location

After the driver is loaded, a folder with the same name as the driver file will be generated in / sys/module / directory, where the driver loading information is stored.

root@imx6qsabresd:/tmp# ls -l /sys/module/hello/
-r--r--r--    1 root     root          4096 Nov 10 19:40 coresize
drwxr-xr-x    2 root     root             0 Nov 10 19:40 holders
-r--r--r--    1 root     root          4096 Nov 10 19:40 initsize
-r--r--r--    1 root     root          4096 Nov 10 19:40 initstate
drwxr-xr-x    2 root     root             0 Nov 10 19:40 notes
-r--r--r--    1 root     root          4096 Nov 10 19:40 refcnt
drwxr-xr-x    2 root     root             0 Nov 10 19:40 sections
-r--r--r--    1 root     root          4096 Nov 10 19:40 srcversion
-r--r--r--    1 root     root          4096 Nov 10 19:40 taint
--w-------    1 root     root          4096 Nov 10 19:35 uevent

3. View driver file information (modinfo)

  • This command queries the driver file directly, and does not need to be loaded.
  • The development board is castrated with this command, which is the driver file information viewed on the PC.
  • The author, description, version, permission and other descriptions defined in the driver file can be found.
hrx@@@:~/Imx6/platform/driver/hello$ modinfo hello.ko
filename:       /home/hrx/Imx6/platform/driver/hello/hello.ko
license:        GPL
version:        1.0.0
description:    Linux Driver
author:         hrx
srcversion:     A5F2F4E32D4DF79D5CF15B7
vermagic:       3.14.38-6UL_ga-svn12810 SMP preempt mod_unload modversions ARMv7 p2v8

Reference 1:

65 original articles published, 107 praised, 220000 visitors+
Private letter follow

Tags: Linux Makefile Ubuntu shell

Posted on Tue, 11 Feb 2020 05:10:49 -0500 by crislewis