为了在video设备中分配大块连续物理内存,移植android Pmem
驱动部分:
1、 pmem driver 文件从android linux中copy,并配置好makefile和config
2、在devs.c中添加
#ifdef CONFIG_ANDROID_PMEM #include <linux/android_pmem.h> #include <linux/memblock.h> #endif
#ifdef CONFIG_ANDROID_PMEM static struct android_pmem_platform_data pmem_pdata = { .name = "pmem", .no_allocator = 1, .cached = 1, .start = 0, .size = 0, }; struct platform_device pmem_device = { .name = "android_pmem", .id = 0, .dev = { .platform_data = &pmem_pdata }, }; void __init s5p_pmem_reserve_mem(phys_addr_t base, unsigned int size) { if (memblock_remove(base, size)) { printk(KERN_ERR "Failed to reserve memory for PMEM device (%ld bytes at 0x%08lx)\n", size, (unsigned long)base); base = 0; return; } printk(KERN_INFO "reserve memory for PMEM device (%ld bytes at 0x%08lx)\n", size, (unsigned long)base); pmem_pdata.start = base; pmem_pdata.size = size; } #endif
#ifdef CONFIG_ANDROID_PMEM extern struct platform_device pmem_device; extern void __init s5p_pmem_reserve_mem(phys_addr_t base, unsigned int size); #endif
static void __init smdkv210_reserve(void) { s5p_mfc_reserve_mem(0x3b800000, 36 << 20, 0x3dc00000, 36 << 20); #ifdef CONFIG_ANDROID_PMEM s5p_pmem_reserve_mem(0x3b000000, 8 << 20); #endif }
#ifdef CONFIG_ANDROID_PMEM
&pmem_device,
#endif
测试程序:
#include <stdio.h> #include <stdarg.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <time.h> #include <sys/mman.h> #include <assert.h> #include <linux/videodev2.h> #include <linux/fb.h> #include <pthread.h> #include <poll.h> #include <semaphore.h> #include "android_pmem.h" int main() { int pmem_fd; void *pmem_base; unsigned int size; struct pmem_region region; pmem_fd = open("/dev/pmem", O_RDWR, 0);//打开设备,为了操作硬件引擎,要noncache的 printf("pmem_fd:%d\n", pmem_fd); if (pmem_fd >= 0) { if (ioctl(pmem_fd, PMEM_GET_TOTAL_SIZE, ®ion) < 0) //获取全部空间 perror("PMEM_GET_TOTAL_SIZE failed\n"); size = region.len; printf("region.len:0x%08x offset:0x%08x\n",region.len, region.offset); pmem_base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);//mmap操作 if (pmem_base == MAP_FAILED) { pmem_base = 0; close(pmem_fd); pmem_fd = -1; perror("mmap pmem error!\n"); } printf("pmem_base:0x%08x\n", pmem_base); } if ( ioctl(pmem_fd, PMEM_GET_PHYS, ®ion) < 0) {//获取物理地址 perror("PMEM_GET_PHYS failed\n"); } printf("region:0x%08x\n",region.offset); if(munmap(pmem_base, size) < 0) { perror("munmap error\n"); } close(pmem_fd); return 0; }