noun explanation
Memory Space and IO space
Memory space is the address space of the non-system memory area of the computer system, now the general X86 system provides 32-bit address, addressing 4G bytes of memory space, but the general computer only installs 256M bytes or less memory, The rest of the high memory is used for PCI or AGP and System bridge devices, the host can access the high-end memory like the system memory, so that the extended device has greater space.
Linux user space and kernel space
IO space is the X86 system above the private space , now the size of Io space is 64K bytes, from 0x0000 to 0xFFFF, can be used for equipment, such as the South Bridge a lot of equipment is hanging in IO space, Many PCI devices also use IO space, and IO space addressing is done using dedicated IO commands.
Configuration space is a generalized description of Plug and Play device, the general configuration space refers to the configuration space of PCI device or PCI bridge device, in the configuration space, the configuration space of General PCI device is 256 bytes, but many bridge devices are extended configuration space, such as the system bridge space can reach 1k bytes. The configuration space provides the device with its configuration information, such as the IO base address of the device, the memory base address, and the interrupt number. This information is written by the BIOS or the operating system, and typically only the driver accesses the configuration space.
The concept of I/O space exists in the X86 processor, where I/O space is relative to the memory space, command in, out to access. The port number identifies the register address of the peripheral.
Currently, most embedded microcontrollers , such as arm, PowerPC, and so on, do not provide I/O space , and only memory space exists. Memory spaces can be accessed directly through addresses and pointers, and variables and other data used in program and program runs exist in the internal storage space. The memory address can be manipulated directly by the C language pointer.
For example, execute the following code in the 186 processor :
unsigned char *p = (unsigned char *) 0xf000ff00;*p=11; The meaning of the program is to write 11 in absolute address 0xf0000+0xff00 (186 processors using 16-bit segment addresses and 16-bit offset addresses).
ARM, PowerPC, etc. do not take the segment address ,p points to the memory space is 0xf000ff00, and *p = 11 is the address written 11.
Question: For ARM, is the memory space 0xf000ff00 a physical address or a virtual address? Answer: Virtual address, physical address must be mapped to virtual address to access
even in the X86 processor, although I/O space is provided, if we design the board ourselves, the peripherals can still only hook up in memory space. At this point, the CPU can access the peripheral I/O port as if it were accessing a memory unit without having to set up specialized I/O directives. Therefore, the memory space is required, and the I/O space is optional.
Memory Management Unit (MMU)
Features: Memory management (Hardware support such as virtual address and physical address mapping, memory access rights protection, and cache cache control)
Operating principle:
access to memory
device IO port and IO memory Access
a device typically provides a set of registers to control the device, read and write the device, and acquire the state of the device, that is, the control register, Register and Status registers. These registers may be in I/O space or in memory space . When in I/O space , usually referred to as the I/O port , when in memory space, the corresponding memory space is called I/O memory .
Of course, for ARM, these port registers are in memory space (IO memory).
Linux access to IO ports
Mapping IO ports to memory space
Later use to add
Linux access to IO memory
before accessing I/O memory in the kernel, you first use the Ioremap () function to map the physical address of the device to the virtual ground address .
The prototype of Ioremap () is as follows:
void *ioremap (unsigned long offset, unsigned long size);
The virtual address obtained through IOREMAP () should be freed by the Iounmap () function
void Iounmap (void * addr);
After the physical address of the device is mapped to the virtual address, although you can access the addresses directly through the pointer, you can
(1) Read I/O memory. unsigned int ioread8 (void *addr); unsigned int ioread16 (void *addr); unsigned int ioread32 (void *addr);// Earlier versions of functions corresponding to the above functions are (these functions are still supported in Linux 2.6): unsigned readb (address); unsigned readw (address); unsigned readl (address);// (2) write I/O memory. void Iowrite8 (U8 value, void *addr), void Iowrite16 (U16 value, void *addr), void Iowrite32 (u32 value, void *addr);//corresponding to the above function Earlier versions of the function were (these functions are still supported in Linux 2.6): void Writeb (unsigned value, address), void Writew (unsigned value, address), void Writel ( unsigned value, address);//(3) read a string of I/O memory. void Ioread8_rep (void *addr, void *buf, unsigned long count), void Ioread16_rep (void *addr, void *buf, unsigned long Count) void Ioread32_rep (void *addr, void *buf, unsigned long count);//(4) write a string of I/O memory. void Iowrite8_rep (void *addr, const void *buf, unsigned long count); void Iowrite16_rep (void *addr, const void *BUF, Unsign Ed long count); void Iowrite32_rep (void *addr, const void *buf, unsigned long count);//(5) Copy I/O memory. void Memcpy_fromio (void *dest, void *source, unsigned int cOunt); void Memcpy_toio (void *dest, void *source, unsigned int count);//(6) Set I/O memory. void Memset_io (void *addr, U8 value, unsigned int count);
Beep_ioremap instances
...//port gpbx Register address declaration#define gpbcon (unsigned long) ioremap (0x56000010,4) #define GPBDAT ( unsigned long) ioremap (0x56000014,4) #define GPBUP (unsigned long) ioremap (0x56000018,4) ... void Beep_start (void) { /*config Gpbcon, set GPB0 as output port*/port_status = Readl (gpbcon);p ort_status &= ~0x03;port_status |= 0x01;writel (Port_status,gpbcon);p ort_status = Readl (gpbdat);p ort_status |= 0x01; Set 1 to Gpb0writel (Port_status,gpbdat);} void Beep_stop (void) {/*config Gpbcon, set GPB0 as output port*/port_status = Readl (gpbcon);p ort_status &= ~0x03;por T_status |= 0x01;writel (port_status,gpbcon);p ort_status = Readl (gpbdat);p ort_status &= ~0x01;//set 0 to GPB0writel ( Port_status,gpbdat);} ...
request and release IO ports and IO memory
(see only IO memory here)
A set of functions used to request and release the range of I/O memory, paired presence//This function applies to the kernel for n memory addresses, which start with the name parameter of the device. If the assignment succeeds the return value is non-NULL, if NULL is returned, it means that the request for I/O memory fails. struct Resource *request_mem_region (unsigned long start, unsigned long len, char *name);//void release_mem_region ( Unsigned long start, unsigned long len);
the above request_region () and Release_mem_region () are not required , but are recommended for use. The task is to check if the source of the request is available, if it is available, and if it is already used, the other driver will fail to request the resource again.
It is not safe to have many device drivers that are directly accessible before I/O ports and I/O memory are requested.
Device I/O port and I/O memory access process
Access steps for I/O Memory:
1. Call Request_mem_region () to request resources
2. Map The register address to the kernel space virtual address via Ioremap ()
3. Access to the registers of these devices through the Linux Device Access programming interface
4. After the access is complete, the virtual address of the IOREMAP () request should be released and the I/O memory resources of the release_mem_region () request should be released
mapping device addresses to user space
1. Memory Mapping and VMA
in general, user space is not possible and should not directly access the device, however, the device driver can be implemented The mmap () function, which allows the user space to access the physical address of the device directly. In fact, Mmap () implements A mapping process that associates a piece of memory in a user's space with device memory, which in fact translates into Access to the device when the user accesses the address of the user space.
( This capability is very meaningful for devices of the display adapter class, if the user space can be accessed directly through the memory map to access the explicit The pixels of the dots on the screen frame will no longer require a copy from user space to kernel space. )
Mmap () must be mapped in page_size, in fact, memory can only be mapped in pages, and to map an address range that is not page_size integer multiples, page alignment is forced to map in multiples of page_size.
The prototype of the mmap () function in the drive int (*mmap) (struct file *, struct vm_area_struct*);//Application layer system call caddr_t mmap (caddr_t addr, size_t len, int p Rot, int flags, int fd, off_t offset);/* parameter FD is a file descriptor, usually returned by open (), FD can also be specified as! 1, at which point the flags parameter Map_anon is required to indicate that the anonymous mapping is being performed. Len is the number of bytes mapped to the calling user space, starting with the offset byte at the beginning of the mapped file, and the offset parameter is typically set to 0, which represents the start of the mapping from the file header. The prot parameter specifies access rights, with the following values of "or": prot_read (Readable), prot_write (writable), prot_exec (executable), and Prot_none (inaccessible). Parameter addr Specifies that the file should be mapped to the starting address of the user space and is generally specified as NULL, so that the task that selects the start address is done by the kernel, and the return value of the function is the address mapped to the user space. Its type caddr_t is actually void *. */
When the user calls Mmap (), the kernel will handle the following.
① finds a piece of VMA in the virtual space of the process.
② the VMA to the map.
③ if the device driver or the file_operations of the file system defines the mmap () operation, it is called.
④ this VMA into the VMA linked list of the process.
io memory static mapping
Dma
Linux-driven design-memory and IO access