Summary of embedded Linux driver development foundation (Part 1)

1, linux drivers are generally divided into 3 categories:

* Character device * Block device * Network device

2, development environment build:

* Cross tool chain construction * NFS and tftp server installation

3, the hardware designed in the driver development:

* Digital circuit knowledge * ARM hardware knowledge * Skilled use of multimeters and oscilloscopes * Read chip manuals and schematics

4, linux kernel source code directory structure:

* The arch/: arch subdirectory includes all core code related to the architecture. Each of its subdirectories represents a supported architecture, such as i386, which is a subdirectory of the intel cpu and its compatible architecture. * block/: partial block device driver; * crypto: common encryption and hashing algorithms (such as AES, SHA, etc.), and some compression and CRC check algorithms; * documentation /: document directory, no kernel code, just one Set of useful documentation; * drivers/: Place all device drivers for the system; each driver occupies a subdirectory: eg, block device drivers under /block, such as ide(ide.c). If you want to see how all devices that might contain a file system are initialized, you can look at device_setup() in drivers/block/genhd.c. * fs/: All file system code and various types of file operation code, each of its subdirectories supports a file system, such as fat and ext2; * include /: include subdirectory includes most of the headers needed to compile the kernel file. The platform-independent header files are in the include/linux subdirectory, the intel cpu-related header files are in the include/asm-i386 subdirectory, and the include/scsi directory is the header file directory for the scsi device; * init/: This directory contains the core initialization code (note: not the system's boot code), contains two files main.c and Version.c, which is one of the good starting points for how the core works. * ipc/: This directory contains the kernel Code for interprocess communication; * kernel/: The main core code, the files in this directory implement the kernel functions of most Linux systems, the most important of which is sched.c; likewise, the architecture-related code Under arch/i386/kernel; * lib/: place the kernel library code; * mm/: This directory includes all memory management code independent of the cpu architecture, such as page storage management memory allocation and release; Architecture-related memory management code is located under arch/i386/mm/; * net/: core and network-related code; * scripts/: description files, scripts, for core configuration; * security: mainly a SELinux module; * sound: drivers for common audio devices, etc.; * usr: implements cpio for packaging and compression;

5, the five subsystems of the kernel:

* Process Debug (SCHED) * Memory Management (MM) * Virtual File System (VFS) * Network Interface (NET) * Interprocess Communication (IPC)

6, linux kernel compilation:

* Configure the kernel: make menuconfig, after use will generate a .confiig configuration file, record which parts are compiled into the kernel, and which parts are compiled into kernel modules. * Compile the kernel and module methods: make zImage Make modules * After executing the above command, get the compressed kernel image zImage in the arch/arm/boot/ directory, and get the selected kernel module in the corresponding directory of the kernel.

7, add programs in the Linux kernel

(Compile directly into the kernel) To complete the following three tasks: * Copy the source code written into the corresponding directory of the Linux kernel source code * Add the build configuration options for the new source code corresponding project in the Kconifg file of the directory * Makefile in the directory Add a compilation entry for the new source code in the file

8, C programming features under Linux:

The Documentation/CodingStyle under the kernel describes the coding style requirements of the Linux kernel. The specific requirements are not listed, the following are to be noted: * The application of spaces in the code * Current function name: GNU C pre-defined two identifiers to save the name of the current function, __FUNCTION__ save the name of the function in the source code, __PRETTY_FUNCTION_ _ Save the name with the language feature. Since C99 already supports the __func__ macro, you should not use __FUNCTION__ in linux programming, you should use __func__. * Built-in functions: The names of other built-in functions that are not part of the library function usually start with __builtin.

9, kernel module

The kernel module is mainly composed of the following parts: (1) module load function (2) module unload function (3) module license statement (usually with Dual BSD/GPL, GPL, etc.) (4) module parameters (optional) It refers to the value that can be passed to the module when it is loaded. It itself corresponds to the global variable inside the module. For example, an example with module parameters mentioned on page P88: insmod book.ko book_name=”GOOD BOOK” num=5000 (5) Module export symbol (optional) The exported symbol can be used by other modules, only before use. Need to declare it. (6) Declaration information such as module authors (optional) The following is a typical kernel module:

/*

* A kernel module: book

* This example is to introduce module params

*

* The initial developer of the original code is Baohua Song

* <>. All Rights Reserved.

*/

#include #include

Static char *book_name = "dissecting Linux Device Driver"; static int num = 4000;

Static int book_init(void)

{

Printk(KERN_INFO " book name:%s",book_name);

Printk(KERN_INFO " book num:%d",num);

Return 0;

}

Static void book_exit(void)

{

Printk(KERN_INFO " Book module exit ");

}

Module_init(book_init);

Module_exit(book_exit);

Module_param(num, int, S_IRUGO);

Module_param(book_name, charp, S_IRUGO);

MODULE_AUTHOR("Song Baohua, ”);

MODULE_LICENSE("Dual BSD/GPL");

MODULE_DESCRIPTION("A simple Module for testing module params");

MODULE_VERSION("V1.0");

Note: The function marked with __init is placed in the .init.text section at link time. A function pointer is also stored in .initcall.init. When initialized, the kernel will call the __init function through these function pointers. Release the init section after initialization is complete.

Module compilation common template:

KVERS = $(shell uname -r)# Kernel modules

Obj-m += book.o# Specify flags for the module compilation.#EXTRA_CFLAGS=-g -O0build: kernel_moduleskernel_modules:

Make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules

Clean:

Make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean

Note that the kernel version is to be specified and the kernel version is to be matched - the kernel version used by the build module is the same as the kernel version that the module is intended to load. Commands that are often used in modules:

Insmod, lsmod, rmmod

· 1

· 2

System call:

Int open(const char *pathname, int flags, mode_t mode);

· 1

· 2

Flag indicates the file open flag, such as: O_RDONLY mode indicates file access rights, such as: S_IRUSR (user readable), S_IRWXG (group can read, write, execute)

10, the relationship between linux file system and device driver

The interface between the application and the VFS is a system call, and the interface between the VFS and the disk file system and the normal device is a file_operation structure member function.

Two important functions: (1) The struct file structure definition is defined in /linux/include/linux/fs.h (Linux 2.6.11 kernel). The file structure represents an open file, and each open file in the system has an associated struct file in kernel space. It is created by the kernel when the file is opened and passed to any function that operates on the file. The kernel releases this data structure after all instances of the file are closed. In kernel creation and driver source, pointers to struct files are usually named file or filp. In driver development, file read /

The write mode mode and the flag f_flags are all things that the device driver cares about, and the private data pointer private_data is widely used in the driver, and is mostly directed to the device driver to customize the structure for describing the device. Similar code is used in the driver to detect how the user can read and write files:

If (file->f_mode & FMODE_WRITE) //User requirements can be written

{

}if (file->f_mode & FMODE_READ) //User requirements are readable

{

The following code can be used to determine whether to open a device file in blocking or non-blocking mode:

If (file->f_flags & O_NONBLOCK) //non-blocking

Pr_debug("open:non-blocking");else //block

Pr_debug("open:blocking");

(2) struct inode structure defined in linux/fs.h

11, the relationship between devfs, sysfs, udev:

(1) devfs linux has a special file system for managing devices, devfs and sysfs are two of them. In 2.4 kernel 4 has been using devfs, devfs is mounted in the /dev directory, provides a file-like method to manage all devices located in the /dev directory, we know that every file in the /dev directory Corresponding to a device, as to whether the device currently exists or not, and these special files are located on the root file system, we have already created these device files when making the file system, so by operating these special files , can achieve interaction with the kernel. However, the devfs file system has some shortcomings, such as: Undefined device mapping, sometimes the device file mapped by a device may be different. For example, my U disk may correspond to sda corresponding to sdb; there is not enough primary/secondary device number when the device In too many cases, this will obviously become a problem; there are too many files in the /dev directory and cannot represent the actual devices on the current system; the names are not flexible enough, they cannot be arbitrarily specified, and so on. (2) sysfs Because of these problems, after the linux2.6 kernel, a new file system sysfs was introduced, which is mounted in the /sys directory. Like devfs, it is also a virtual file system. To manage the devices of the system, it organizes the devices and buses actually connected to the system into a hierarchical file. The user space program can also use this information to realize interaction with the kernel. The file system is actually on the current system. An intuitive response of the device tree, which is created by the kobject subsystem. When a kobject is created, the corresponding files and directories are created, located in the relevant directory under /sys, since each The device has a unique directory in sysfs, so it can be read and written by user space. The user space tool udev uses the information provided by sysfs to implement all devfs functions, but the difference is that udev runs in user space, while devfs runs in kernel space, and udev does not have the inherent defects of devfs. (3) udev udev is a tool that dynamically updates device files based on the status of hardware devices in the system, including the creation and deletion of device files. Device files are usually placed in the /dev directory. After using udev, only the devices that exist in the system are included under /dev. It is independent of the hardware platform, is located in the user space, requires the support of the kernel sysfs and tmpfs, sysfs provides the device entry and uevent channel for udev, and tmpfs provides storage space for the udev device file.

12, linux device model:

In the Linux kernel, bus_type, device_driver, and device are used to describe the bus, driver, and device. These three structures are defined in the include/linux/device.h header file. The drivers and devices are paired by the match() function in bus_type.

Ceramic Housing

Ceramic Housing

Ceramic Housing

YANGZHOU POSITIONING TECH CO., LTD. , https://www.cnfudatech.com