The "Digest"/dev/mem is a full image of physical memory that can be used to access physical memory, and the general usage is open ("/dev/mem", o_rdwr| O_sync), then mmap, then you can use the Mmap address to access the physical memory, which is actually a way to implement the user space driver.
http://blog.csdn.net/wlp600/article/details/6893636#
1, user space-driven advantages
There are several arguments in favor of user-space programming, and sometimes writing a so-called user-space device driver versus delving into the kernel is a wise choice, and the benefits of user-space-driven are:
1, the complete C library can be linked, the driver can do a lot of strange tasks, without relying on the outside of the program (implement the use of policy tools, often with the drive itself released).
2, programmers can run the common debugger on the driver code, without having to debug a running kernel detour.
3. If a user space driver hangs, you can simply kill it. The problem with user space drivers is that it is impossible to suspend the entire system unless the hardware being controlled is really crazy.
4, the user memory is exchangeable, not like kernel memory. Such a device that is not often used but has a large drive does not occupy the RAM that other programs can use, except when it is actually in use.
5. A well-designed driver can still allow parallel access to the device as if it were a kernel-space driver.
6, if you have to write a closed-source driver, user-space options make it easy to identify the circumstances of an ambiguous license and change the kernel interface to bring problems.
2. User space Drive Disadvantage
However, there are several drawbacks to device drivers for user space, and most importantly:
1. Interrupts are not available in user space, there are workarounds for this limitation on some platforms, such as VM86 system calls on IA32 architectures.
2. DMA is only possible with memory mapped/dev/mem, and only privileged users can do so.
3, access to the I/O port can only be called ioperm or IOPL only, in addition, not all platforms support these system calls, and access/dev/port may be too slow and inefficient, these system calls and device files require privileged users.
4. Response time is slow because context switches are required to pass messages and actions between the user and the hardware.
5, worse, if the driver has been swapped to the hard disk, the response time will be unacceptable, the use of mlock system calls may be helpful, but you need to lock up a lot of memory pages, because a user space program relies on a large number of library code, Mlock also limited to authorized users.
The most important devices cannot be processed in user space, including network interfaces and block devices.
In summary, there are too many things that the user space driver cannot do, and the application of interest is still there: support for the SCSI scanner device (implemented by the sane package) and a CD burner (implemented by Cdrecord and other tools). In both cases, the user-level device is dependent on the "SCSI generic" kernel driver, which outputs the underlying SCSI functionality to the user program, so they can drive their own hardware.
When you start working on new, unused hardware, you can learn to manage your hardware by developing a user-space drive, without worrying about suspending the entire system, and once you're done, encapsulating the software in a kernel module can be a simple operation.
Notes: The new kernel has limited 1M of memory access in/dev/mem, which is a configurable option Config_strict_devmem has chosen n on my machine, but it seems that only 1M of physical memory can be mapped.
In ULCC, the physical memory address is mapped to the virtual address through mmap, which is achieved by the noncacheable of the physical page, mainly through mapping/dev/mem modifying the page properties in Pat. X86 's Page property sheet (PAT) is capable of setting memory properties on page granularity, and Pat is a supplement to MTRR, where the memory type can be set for the physical address area, but Pat is more flexible than MTRR because it can set properties at the page level and does not limit the number of property settings on the hardware. Pat is quite flexible, and even if multiple virtual addresses are mapped to the same physical memory address, there is no memory type conflict, and Pat is able to set many types of memory properties, the most common of which are 4: Write-back, ucached, write-combined, Uncached-minux.
open("/dev/mem", O_RDWR|O_SYNC);mmap((void *)addr, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, fm, pfn<<PAGE_SHIFT);
/dev/kmem: The kernel sees a full image of the virtual memory that can be used to access the contents of the kernel.
What Is/proc/kcore?
None of the files In/proc is really there–they ' re all, ' Pretend, ' files made up by the kernel, to give you information a Bout the system and don ' t take up any hard disk space.
/proc/kcore is a "alias" for the memory in your computer. Its size was the same as the amount of RAM you had, and if you read it as a file, the kernel does memory reads.
3. Reference Code
#include <stdio.h>#include <unistd.h>#include <sys/mman.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>intMain () {unsigned Char* MAP_BASE; FILE *f;intN, FD; FD = open ("/dev/mem", o_rdwr| O_sync);if(FD = =-1) {return(-1); } map_base = Mmap (NULL,0xFF, prot_read| Prot_write, map_shared, FD,0x20000);if(Map_base = =0) {printf("NULL pointer!\n"); }Else{printf("successfull!\n"); }unsigned LongAddrunsigned CharContentinti =0; for(; I <0xFF; ++i) {addr = (unsigned Long) (map_base + i); Content = Map_base[i];printf("ADDRESS:0X%LX content 0x%x\t\t", addr, (unsigned int) content); Map_base[i] = (unsigned CharI Content = Map_base[i];printf("Updated ADDRESS:0X%LX content 0x%x\n", addr, (unsigned int) content); } close (FD); Munmap (Map_base,0xFF);return(1);}
The above example maps the starting address 0x20000 (physical address) to 0xFF in length. You can then manipulate the memory like a normal array.
Here are the output results
address:0x7f3f95391000 content 0x0 Updated address:0x7f3f95391000 content 0x0
address:0x7f3f95391001 content 0x0 Updated address:0x7f3f95391001 content 0x1
address:0x7f3f95391002 content 0x0 Updated address:0x7f3f95391002 content 0x2
address:0x7f3f95391003 content 0x0 Updated address:0x7f3f95391003 content 0x3
address:0x7f3f95391004 content 0x0 Updated address:0x7f3f95391004 content 0x4
。。。
My test machine is a 64-bit machine. This example maps the physical address 0x20000 to the virtual address 0x7f3f95391000.
The content under the current address is first output and then the new value is written.
You can verify that the new value has been written by Hexedit/dev/mem.
This can be done if you want to handle kernel assigned addresses in the user state. The memory is first allocated with VIRT_ADDR = Get_free_pages (Gfp_kernel, order), the physical address is obtained by PHY_ADDR = __pa (virt_addr), and then the/DEV/MEM is mapped with mmap in the user state. Offset is phy_addr, length is set to 2^order. In this case, the memory allocated by the kernel can be read and written in the user.
Note: This operation requires root access.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Open ("/dev/mem", O_RDWR | O_sync)