linux-driven learning (2) - access to hardware devices

(A) mmap system call

Features:

void * mmap (void * addr,
size_t len, int prot, int flags, int fd, off_t offset) memory mapping functions mmap, responsible for the contents of the file mapped into the process's virtual memory space, by reading and modification of this memory to achieve read and modify files, without the need to call read, write and other operations.

parameter:

  • addr: Specifies the start address mapping, generally set to NULL, assigned by the system.
  • length: length of the file mapped into memory.
  • prot: protection zone maps, which can be:
  • PROT_EXEC: mapping area can be executed
  • PROT_READ: mapping area can be read
  • PROT_WRITE: mapping area can be written
  • flags: the characteristic map of the area, can be:
    1. MAP_SHARED: Data written to the shadow area is copied back to the file, and allow other processes to map the file share.
    2. MAP_PRIVATE: produce copy (copy-on-write) mapping area of ​​a write operation to the mapped area, modifications to this region did not write back to the original file
  • fd: file returned by the open file descriptor, representatives to be mapped.
  • offset: offset to the beginning of the file, must be a multiple of the page size, usually 0, it indicates the start mapping from the file header.

Unmap:

int munmap(void *start,size_t length)

Features:

   Cancel parameter points to start mapping memory, parameter length said he wished to cancel the memory size.

return value: 

  Lift the successful return 0, otherwise it returns -1 in the cause of the error is stored in errno.

Virtual memory area:

  Virtual memory area is a homogeneous range of virtual address space of a process, that has the same characteristics of a continuous range of addresses. A memory image by the process of the following components: a program code, data, stack area and the BSS, and a region of memory mapping.

Memory area can be a process by looking at / proc / pid / maps
each line domain: start_end perm offset major: minor inode

    • Start: The starting virtual address area
    • End: end the region virtual address
    • Perm: read, write, and execute permissions; expressed the area, allowing the process to do. The last character of this field is either p for a private, either s is shared.
    • Offset: is mapped starting address section in the file
    • Major, minor: major and minor device numbers
    • Inode: inode

Linux kernel structure vm_area_struct (<linux / mm_types.h>) to describe the virtual memory area, several of the following main members:

    • unsigned long vm_start virtual memory area starting address
    • unsigned long vm_end virtual memory area end address
    • unsigned long vm_flags the mark region. Such as: VM_IO and VM_RESERVED. The labeled VM_IO VMA memory mapped IO space, VM_IO will prevent the storage area comprises a dump (core dump) of the process, VM_RESERVED flag memory area can not be swapped out

mmap important device operating :()

Mapping refers to a device associated with the user address space to the period of the memory device. When the user program to read and write address this space, it is actually the access device.
mmap method is a member of file_oprations structure is called when mmap system call issued. Prior to this, the kernel has gotten a lot done. mmap Device method need to do is to create a virtual address to a physical address of the page table
int (* mmap) (struct file
*, struct vm_area_struct *) How to complete the establishment of mmap the page table?

    1. Use remap_pfn_range once established all page table;
    2. Use nopage VMA method every time you create a page table;

Work page table structure may be completed remap_pfn_range function, prototype is as follows:

int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,unsigned long pfn, unsigned long size, pgprot_t prot)

    • vma: virtual memory area pointer
    • The starting value of the virtual address: virt_addr
    • pfn: the physical address of the physical page frame number to be mapped is located, the physical address can be
    • >> PAGE_SHIFT get.
    • The size of the area to be mapped: size.
    • prot: protection of property VMA.
 1 int memdev_mmap(struct file*filp, struct vm_area_struct *vma)
 2 {
 3     Vma->vm_flags |= VM_IO;
 4     Vma->vm_flags |= VM_RESERVED;
 5     if (remap_pfn_range(vma, vma->vm_start,virt_to_phys(dev-     >data)>> PAGE_SHIFT,size,vma->vm_page_prot))
 6     {
 7     return -EAGAIN;
 8     }
 9     return 0;
10 }
View Code

(B) register with memory

Where is the difference between register and memory in it?

  • The main difference is that the RAM registers and register operation has the side effect (side effect or a marginal effect):
  • This may lead to a change in address content while reading an address, such as many devices as long as a read interrupt status register, automatically cleared.

Memory and I / O:

Existence concept I / O space in the X86 processor, I / O space is a memory space relative terms, they are separate address space, the 32-bit x86 system, I / O space of 64K, the memory space is 4G.

    • X86 supports memory space, IO space
    • ARM only supports memory space
    • MIPS only supports memory space
    • PowerPC only supports memory space
    • IO Port: When a register or a memory located IO space, called IO port.
    • IO Memory: When a register or a memory space in memory, called the IO memory.

Operation I / O port: the operation of the I / O completion port basis having the following steps:

    1. Application 
    2. access
    3. freed

Application I / O ports:

The kernel provides a set of functions to allow the drive application I / O port, which is the core function it needs: struct resource * request_region (unsigned long first, unsigned long n, const char * name)
This function is to tell the kernel that you want to use from the beginning of the first n ports, name parameter is the name of the device. If the application is successful, it returns a non-NULL, the application fails, returns NULL.

Distribution system ports in the recording / proc / ioports (for display). If you can not assign ports need, you can come here to see who is using.

Access I / O ports:

I / O ports can be divided into 8-bit, 16-bit and 32-bit port. Linux kernel headers (system dependent header <asm / io.h>) defines the following inline functions to access I / O ports:

    • unsigned inb (unsigned port) read port byte (8 bits wide)
    • void outb (unsigned char byte, unsigned port) write port byte (8 bits wide)

 

    • unsigned inw(unsigned port)
    • void outw(unsigned short word, unsigned port)

16-bit access port.

    • unsigned inl(unsigned port)
    • void outl(unsigned longword, unsigned port)

32-bit access port.

The release of I / O ports:

When a group of exhausted I / O ports (typically unloaded during driving), the following function should be used to return them to the system:
void release_region (unsigned Long Start, n-unsigned Long)

Operation I / O memory:

Operation of the I / O memory of the basis having the following steps is completed:

    1. Application
    2. Mapping
    3. access
    4. freed

Application I / O memory:

The kernel provides a set of functions to allow the driver to apply it requires an I / O memory, in which the core functions are:
struct request_mem_region * Resource (unsigned Long start, unsigned Long len, char * name)
This function starts the application for a start, length len bytes of memory for the region. If successful, it returns a non-NULL; otherwise it returns NULL, all I / O memory already in use are listed in / proc / iomem in.

Mapped I / O memory:

Before accessing the I / O memory, you must map the virtual addresses to physical addresses, this function has ioremap function:
void * ioremap (phys_addr unsigned Long, Long unsigned size)

Access I / O memory:

The correct way to access I / O memory is a function provided by a series of core:
from I / O memory read, use one of the following:

    1. unsigned ioread8(void *addr)
    2. unsigned ioread16(void *addr)
    3. unsigned ioread32(void *addr)

Write I / O memory, use one of the following:

    1. void iowrite8(u8 value, void *addr)
    2. void iowrite16(u16 value, void *addr)
    3. void iowrite32(u32 value, void *addr)

The old version of the I / O memory access functions:
from I / O memory read, use one of the following:

    1. unsigned readb(address)
    2. unsigned readw(address)
    3. unsigned readl(address)

Write I / O memory, use one of the following:

    1. unsigned writeb(unsigned value, address)
    2. unsigned writew(unsigned value, address)
    3. unsigned writel(unsigned value, address)

The release of I / O memory:

(C) hybrid device driver

definition:

In the Linux system, there is a class of character devices, they share a major number (10), but different minor number, we call this type of equipment is mixed equipment (miscdevice). All hybrid devices forming a linked list, access to the device to find a kernel corresponding miscdevice apparatus according to the minor number.

Device Description:

Linux kernel uses to describe a struct miscdevice hybrid device.
struct miscdevice
{
  int Minor; / * minor number * /
  const char * name; / * device name * /
  const struct the file_operations * FOPS; / * file operations * /
  struct the list_head List;
  struct Device * parent;
  struct Device * this_device;
};

Device Registration:

Linux kernel uses misc_register function to register a hybrid device driver.
int misc_register (struct miscdevice * misc)

(Four) LED driver design

Pull-up / pull-down resistors:

Pull signal is undefined is connected through a resistor to the power supply, fixed at the high level. Uncertain pull-down signal is connected to ground via a resistor, fixed at low level. Pullup current is injected into the device, a pull-down output current. When a pull-up resistor connected to an I / O port to an input state, its normal high level, the input can be used to detect a low level.

 

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin www.cnblogs.com/WenLee/p/12114983.html