NIUCLOUD是一款SaaS管理后台框架多应用插件+云编译。上千名开发者、服务商正在积极拥抱开发者生态。欢迎开发者们免费入驻。一起助力发展! 广告
https://www.cnblogs.com/Ph-one/p/6844184.html 比如驱动(内核空间)中 ``` vir_addr = kmalloc( size, GFP_KERNEL | GFP_DMA ) phy_addr = __pa( vir_addr ); ``` 申请了一段内存,然后得到__pa()得到它的物理地址,然后将该物理地址传到用户空间 然后在应用程序(用户空间)中 ``` int map_fd = open("/dev/mem", O_RDWR); map_addr = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, phy_addr); ``` 这样就可以得到 在应用程序中 访问驱动程序中申请的内存的指针map_addr,可以实现应用程序和驱动程序访问同段内存,节省开销,实现内存共享 这是一种方法,把内核空间的内存映射到用户空间,内核空间内存-->物理地址(PA)-->用户空间 通过/dev/mem 和系统调用mmap ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/poll.h> #include <sys/mman.h> int page_size; #define PAGE_SIZE page_size #define PAGE_MASK (~(PAGE_SIZE-1)) void get_var (unsigned long addr) { off_t ptr = addr & ~(PAGE_MASK); off_t offset = addr & PAGE_MASK; int i = 0; char *map; static int kfd = -1; kfd = open("/dev/kmem",O_RDONLY); if (kfd < 0) { perror("open"); exit(0); } map = mmap(NULL,PAGE_SIZE,PROT_READ,MAP_SHARED,kfd,offset); if (map == MAP_FAILED) { perror("mmap"); exit(-1); } printf("%s\n",map+ptr); return; } int main(int argc, char **argv) { FILE *fp; char addr_str[11]="0x"; char var[51]; unsigned long addr; char ch; int r; if (argc != 2) { fprintf(stderr,"usage: %s System.map\n",argv[0]); exit(-1); } if ((fp = fopen(argv[1],"r")) == NULL) { perror("fopen"); exit(-1); } do { r = fscanf(fp,"%8s %c %50s\n",&addr_str[2],&ch,var); if (strcmp(var,"modprobe_path")==0) break; } while(r > 0); if (r < 0) { printf("could not find modprobe_path\n"); exit(-1); } page_size = getpagesize(); addr = strtoul(addr_str,NULL,16); printf("found modprobe_path at (%s) %08lx\n",addr_str,addr); get_var(addr); } ``` 上面这段代码通过检查/dev/kmem查看是否打了补丁。