Linux kernel-driven learning (eight)----driver Categories | Learning Methods | Hardware access

Source: Internet
Author: User
Tags function prototype

Drive Classification:For drivers, we generally classify them in two ways: General taxonomy and bus classification.
According to the general classification, can be divided into the following three categories:1. Character Device:ToBytes is the minimum access unitThe device.character device drivers are typically accessed through character device files. The character driver is responsible for driving the character device , which usually supports open, close, read, write system calls, and the application can access the character device (serial port) through device files (such as/DEV/TTYSAC0, etc.). For example: Serial port \led\ Button
2, block equipment:A device with a block (typically 512 bytes) for the smallest transmission unit. On most Unix systems, block devices cannot process data in bytes. Common block devices include hard drives, Flash, SD cards. InLinux Tracking allows any number of bytes to be transmitted by the block device。 The special point of a block device:a) The interface of the operating hardware is implemented differentlyThe block device driver first organizes the data sent by the user into chunks, then writes the device, or reads a number of pieces of data from the device, and then picks out what the user needs.b) The data on the data block can be in a certain format. usually the data is stored in a certain format in the fast device, and the different file system types are defined in these formats. In the kernel, the filesystem hierarchy is located above the block device driver, which means that the block device driver, in addition to providing the user layer with the same interface as the character device, also provides some interfaces to the other parts of the kernel that the user cannot see, but that can be used to store file systems on block devices, mount blocks Equipment.
the difference between a block device and a character device is that the interface provided to the kernel is not the same, but the interface provided to the user layer is the same.
3. Network InterfaceThis can be a hardware device, such as a network card, or a device that is purely software. such as the Loopback Interface (LO). A network interface is responsible forsend and receive data messages. For network drivers and unlike character devices and block devices, libraries and cores provide a set of functions related to packet transport, rather than ordinary system calls (Open\write)
According to the bus classification, can also be divided into the following three categories: 1, USB device 2, PCI device 3, platform bus equipmentFor example, USB wireless network card: According to the general classification for the network interface, by bus classification: USB devices.
Driving Learning methods:We know that the Linux kernel is made up of a variety of drivers, the kernel source of about 85% of the code is the driver. There is a complete range of drivers implemented in the kernel, which we can modify on a pass-type drive to match specific devices. The learning drive is more importantfigure out the existing driver framework and add the appropriate hardware to the framework.
For hardware operations, refer to the arm bare metal code and port it to the drive frame.
And one more thing.It is best not to read the kernel code too much in the early days of driving learning to avoid confusion.

Hardware access:the essence of hardware access: driver-controlled devices, mainly through the device registers to achieve the purpose of control , so we discuss how to access the hardware, it becomes how to access these registers. One, address mappingbare Metal uses physical addresses to operate registers, whereas virtual addresses are used in Linux systems (whether kernel programs or applications). The mapping of the physical address to the virtual address needs to be completed when the register is manipulated. address mapping is also divided into: 1.1 dynamic mapping:The ioremap function is used in the driver to map the physical address to a virtual address. function prototype:void * IOREMAP (physaddr, size) parameter:physaddr: Physical Address to be mapped Size: The area length of the mapreturn value: The mapped virtual address
1.2 static mapping: The Linux system automatically maps the physical address to a virtual address when the kernel is booted , based on a mapping relationship that the user has specified beforehand .
Example of mapping: the static mapping of IO memory, how the mapping relationship is specified when the Linux system maps the physical address of the IO memory to the virtual address. This requires Map_desc the structure array, where the mapping is done by adding new members to the structure array. that is, in the static mapping, the user is through the map_desc structure to indicate the physical address and virtual address mapping relationship. file Map.h (Linux-ok6410\arch\arm\include\asm\mach) in the static mapping, the user is through the map_desc structure to indicate the mapping between the physical address and the virtual address.
struct MAP_DESC {unsigned long virtual;/* The mapped virtual address */unsigned long PFN;/* The page frame number where the physical address is located */unsigned long length;/* Map Length */u nsigned int type; /* The device type mapped */};


PFN: use __PHYS_TO_PFN ( Physical Address ) to calculate the physical page frame number where the physical address resides for a 6410 processor, the padding for this structure is as follows:cpu.c (linux-ok6410\arch\arm\mach-s3c64xx)
/* Minimal IO mapping */static struct MAP_DESC s3c_iodesc[] __initdata = {{. virtual= (unsigned long) s3c_va_sys,.pfn= __phy S_TO_PFN (S3c64xx_pa_syscon),. length= sz_4k,.type= Mt_device,}, {. virtual= (unsigned long) s3c_va_mem,.pfn= __phys_to_ PFN (S3c64xx_pa_srom),. length= sz_4k,.type= Mt_device,}, {. virtual= (unsigned long) (S3c_va_uart + uart_offs),. pfn= __ PHYS_TO_PFN (S3c_pa_uart),. length= sz_4k,.type= Mt_device,}, {. virtual= (unsigned long) va_vic0,.pfn= __PHYS_TO_PFN ( S3C64XX_PA_VIC0),. length= sz_16k,.type= Mt_device,}, {. virtual= (unsigned long) va_vic1,.pfn= __PHYS_TO_PFN (S3C64XX_ PA_VIC1),. length= sz_16k,.type= Mt_device,}, {. virtual= (unsigned long) s3c_va_timer,.pfn= __PHYS_TO_PFN (S3C_PA_TIMER ),. length= sz_16k,.type= Mt_device,}, {. virtual= (unsigned long) s3c64xx_va_gpio,.pfn= __PHYS_TO_PFN (S3c64xx_pa_gpio) ,. length= sz_4k,.type= Mt_device,}, {. virtual= (unsigned long) s3c64xx_va_modem,.pfn= __PHYS_TO_PFN (S3c64xx_pa_modem) ,. length= sz_4k,.type= Mt_device,}, {. virtual= (unsigned long) S3c_va_watchdog,.pfn= __PHYS_TO_PFN (S3c64xx_pa_watchdog),. length= sz_4k,.type= Mt_device,}, {. virtual= (unsigned long) S3C_ va_usb_hsphy,.pfn= __PHYS_TO_PFN (s3c64xx_pa_usb_hsphy),. length= sz_1k,.type= Mt_device,},};


automatic mapping is done within the following functions when the kernel starts
/* Read CPU Identification code */void __init s3c64xx_init_io (struct map_desc *mach_desc, int size) {unsigned long idcode;/ * Initialise The IO descriptors we need for initialisation */iotable_init (S3c_iodesc, Array_size (S3C_IODESC)); Build Map Iotable_init (mach_desc, size); Idcode = __raw_readl (S3c_va_sys + 0x118); if (!idcode) {/* s3c6400 has the ID register In a different place, * and needs a write before it can be read. */__raw_writel (0x0, S3c_va_sys + 0xa1c); Idcode = __raw_readl (S3c_va_sys + 0xa1c);} S3c_init_cpu (Idcode, Cpu_ids, Array_size (Cpu_ids));}


Second, register read and writeOnce the address mapping is complete, the registers can be read and written, and the Linux kernel (3.0.1) provides a series of functions to read registers
/* Read CPU Identification code */void __init s3c64xx_init_io (struct map_desc *mach_desc, int size) {unsigned long idcode;/ * Initialise The IO descriptors we need for initialisation */iotable_init (S3c_iodesc, Array_size (S3C_IODESC)); Build Map Iotable_init (mach_desc, size); Idcode = __raw_readl (S3c_va_sys + 0x118); if (!idcode) {/* s3c6400 has the ID register In a different place, * and needs a write before it can be read. */__raw_writel (0x0, S3c_va_sys + 0xa1c); Idcode = __raw_readl (S3c_va_sys + 0xa1c);} S3c_init_cpu (Idcode, Cpu_ids, Array_size (Cpu_ids));}












Linux kernel-driven learning (eight)----driver Categories | Learning Methods | Hardware access

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.