Original address: Linux device driver Learning (0)-hello, World Module Author: Tekkamanninja Linux device driver Learning (0)
-Device driver Introduction & Hello, World. Module
The role of device drivers
The device driver is the gateway to the Linux kernel world. Device drivers play a special role in the Linux kernel. It is a separate "black box" that enables a particular hardware to respond to a well-defined internal programming interface that completely hides the details of the device's work. User actions are performed through a standardized set of calls that are independent of specific drivers. mapping these calls to a device-specific operation that works on the actual hardware is the task of the device driver.
Device-driven classifier character device: a character (char) device is a device that can be accessed like a byte stream (similar to a file). Character device drivers typically implement open, close, read, and write system calls at least.
block Device: A block device driver accesses a device primarily by transmitting a fixed size of data. The difference between a block device and a character device is simply the way the kernel manages the data, which is the software interface between the kernel and the driver, which is transparent to the user program. In the kernel, block drivers have completely different interfaces than character drivers.
Network interface: any network transaction is formed through a network interface, that is, a device that can exchange data with other hosts. It can be a hardware device, but it may also be a pure software device. The way to access the network interface is still to assign them a unique name (such as Eth0), but the name does not exist in the file system for the corresponding node. Communication between kernel and network device drivers is completely different from kernel and character and block driver communication, the kernel calls a set of functions related to packet transfer instead of read, write, etc. characteristics of the drive module
(1) The drive module runs in the kernel space, the runtime can not rely on any standard C library and other application layer libraries, modules, so the function called in the write-driven can only be part of the kernel as a function, that is, the use of "Export_symbol" exported functions.
Àinsmod uses the common kernel symbol table to resolve undefined symbols in the module. The Common kernel symbol table contains all the global kernel entries (that is, the addresses of functions and variables), which is necessary to implement a modular driver.
Àlinux using modular cascade technology, we can divide the modules into layers and shorten the development cycle by simplifying each layer. If a module needs to export symbols to other modules, the following macro is used:
Export_symbol (name); EXPORT_SYMBOL_GPL (name); |
The symbols must be exported in the global Variables section of the module file, because the macros will be extended to the declaration of a special variable, and the variable must be global.
(2) One important difference between the driver module and the application is that the application exits regardless of resource release or other cleanup work, but the module's exit function must carefully undo everything that the initialization function does, otherwise, something will remain in the system until the system reboots.
(3) The multiple operating modes (levels) of the processor are designed for the user space and kernel space of the OS. Only two levels are used in the Unix-class operating system: the highest and lowest levels.
(4) Attention should be paid to the concurrent processing of the driver.
(5) A function with a double underscore (_ _) in the kernel API, usually the underlying component of the interface, should be used with caution.
(6) The kernel code cannot implement floating-point arithmetic. References: Introduction to HTTP://BLOG.CHINAUNIX.NET/U/30180/SHOWART.PHP?ID=1421920 module structure
Take advantage of the first routine of a Linux device driver: The Hello World Module understands the structure of the kernel-driven module.
#include <linux/init.h> #include <linux/module.h>
static int hello_init (void) { PRINTK (Kern_alert "Hello, Tekkaman Ninja.") \ n "); return 0; }
static void Hello_exit (void) { PRINTK (Kern_alert "Goodbye, Tekkaman Ninja. Love Linux! Love ARM! Love KeKe!\n "); }
Module_init (Hello_init); Module_exit (Hello_exit); Module_license ("Dual BSD/GPL"); |
1. All of the module's code contains two header files:
#include <linux/init.h> #include <linux/module.h> |
2. All module codes should specify the licenses that are used:
Module_license ("Dual BSD/GPL"); |
In addition, there are other descriptive definitions that are optional:
Module_author (""); Module_description (""); Module_version (""); Module_alias (""); Module_device_table (""); |
The above Module_ statements are customarily put in the final document . 3. Initializing and closing
The actual definitions of initialization are usually as follows:
static int _ _init initialization_function (void) { /* Initialize Code * * }
Module_init (initialization_function) |
The actual definition of the purge function is usually as follows:
static int _ _exit cleanup_function (void) { /* Clear Code * * }
Module_exit (cleanup_function) |
4. A simple Makefile file:
Kerneldir =/home/tekkaman/working/sbc2440/linux-2.6.22.2 PWD: = $ (Shell PWD) INSTALLDIR =/home/tekkaman/working/rootfs/lib/modules Cross_compile = arm-9tdmi-linux-gnu- CC = $ (cross_compile) gcc obj-m: = hello.o . Phony:modules Modules_install Clean Modules $ (make)- C $ (kerneldir) m=$ (PWD) modules Modules_install: CP Hello.ko $ (INSTALLDIR) Clean RM-RF *.o *~ core. Depend *.cmd *.ko. *.mod.c |
obj-m: = hello.o
Represents the module name that we want to construct Hell.ko,make will automatically find the hell.c file to compile under the directory. If the hello.o is generated by other source files (such as file1.c and file2.c), add the following (note the corresponding relationship of the red font):
HELLO-OBJS: = FILE1.O file2.o ... |
$ (make)-C $ (Kerneldir) m=$ (PWD) modules
- C $ (kerneldir) Specifies the location of the kernel source code, which holds the top-level makefile file of the kernel.
m=$ (PWD) Specifies the location of the module source code
The modules target points to the module set in the OBJ-M variable. 5. Compiling modules
Make modules, make modules_install.
[Root@tekkaman-ninja helloworld]# make modules Make-c/home/tekkaman/working/sbc2440/linux-2.6.22.2 M=/home/tekkaman/working/linuxdriver/helloworld Modules MAKE[1]: Entering directory '/home/tekkaman/working/sbc2440/linux-2.6.22.2 ' CC [M]/home/tekkaman/working/linuxdriver/helloworld/hello.o Building modules, Stage 2. Modpost 1 Modules cc/home/tekkaman/working/linuxdriver/helloworld/hello.mod.o LD [M]/home/tekkaman/working/linuxdriver/helloworld/hello.ko MAKE[1]: Leaving directory '/home/tekkaman/working/sbc2440/linux-2.6.22.2 ' [Root@tekkaman-ninja helloworld]# make Modules_install CP Hello.ko/home/tekkaman/working/rootfs/lib/modules [Root@tekkaman-ninja helloworld]# |
6. Actions on the Development Board:
[tekkaman2440@sbc2440v4] #cd/lib/modules/ [tekkaman2440@sbc2440v4] #ls C S89x0.ko hello.ko p80211.ko prism2_usb.ko [tekkaman2440@sbc2440v4] #insmod hello.ko Hello, Tekkaman ninja . [tekkaman2440@sbc2440v4] #lsmod Modul |