免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2164 | 回复: 1
打印 上一主题 下一主题

内存映射mmap [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-03-29 16:49 |只看该作者 |倒序浏览
本帖最后由 zzappled 于 2011-03-29 16:57 编辑

内核态程序创建1页面的缓存,同时用户程序进行mmap映射,并向其中写入数据,出现错误
segfault at ffffffffffffffff ip 00007ffc307d5782 sp 00007ffff299fb38 error 6 in libc-2.13.so[7ffc306ab000+191000]
不知道是怎么回事,请各位指教
内核态程序
#define PROC_PHYADDR "mem_addr"

unsigned long kernel_addr=0;
unsigned long kernel_start=0;

#define PAGES_ORDER         0
#define PAGES                1

static int proc_mem_addr(char *page, char **start, off_t off, int count,int* eof, void* data)
{
  return sprintf(page, "%lu\n", __pa(kernel_start));
}

static int init_sk_buff(void)
{
  unsigned long page=0;
  char *addr=NULL;
  create_proc_read_entry(PROC_PHYADDR, 0, NULL, proc_mem_addr,NULL);
  kernel_addr=__get_free_pages(GFP_ATOMIC,PAGES_ORDER);
  addr=(char*)kernel_addr;
  kernel_start=kernel_addr;
  memset(addr, 0, PAGE_SIZE << PAGES_ORDER);
  if(addr)
  {
    while(page<=PAGES-1)
    {
      SetPageReserved(virt_to_page(kernel_addr));
      kernel_addr+=PAGE_SIZE;
      page++;
    }
    return 1;
  }
  return 0;
}

static int __init ring_init(void)
{
  if(!init_sk_buff())
    printk("init skb_buff error!");
  return 0;
}

static void __exit ring_exit(void)
{
  int page=0;
  char *addr=NULL;
  kernel_addr=kernel_start;
  addr=(char *)kernel_start;
  if(!addr)
    return;
  printk("The content written by user is: %s\n", addr);
  while(page<=PAGES-1)
  {
    ClearPageReserved(virt_to_page(kernel_addr));
    kernel_addr+=PAGE_SIZE;
    page++;
  }
  free_pages(kernel_start,PAGES_ORDER);
  remove_proc_entry(PROC_PHYADDR, NULL);
  return;
}

module_init(ring_init);
module_exit(ring_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("test");
MODULE_DESCRIPTION("Kernel memory share module.");


用户态程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mman.h>

#define PAGES        1       

int main(int argc, char* argv[])
{
        if(argc != 2)
        {
                printf("Usage: %s string\n", argv[0]);
                return 0;
        }
        
        unsigned long phymem_addr;
        char *map_addr=NULL;
        char s[256];
        int fd;
        
        fd = open("/proc/mem_addr", O_RDONLY);
        if(fd < 0)
        {
                printf("cannot open file /proc/mem_addr\n");
                return 0;
        }
        read(fd, s, sizeof(s));
        sscanf(s, "%lu", &phymem_addr);
        close(fd);

        printf("phymem_addr=%lu\n", phymem_addr);
        /*memory map*/
        int map_fd = open("/dev/mem", O_RDWR);
        if(map_fd < 0)
        {
                printf("cannot open file /dev/mem\n");
                return 0;
        }
        
        map_addr = mmap(0, PAGES*4*1024, PROT_READ|PROT_WRITE, MAP_SHARED, map_fd, phymem_addr);
        strcpy(map_addr, argv[1]);
        munmap(map_addr, PAGES*4*1024);
        close(map_fd);
        return 0;
}

论坛徽章:
0
2 [报告]
发表于 2011-03-30 09:00 |只看该作者
结贴,重新编译内核,去掉CONFIG_X86_PAT和CONFIG_STRICT_DEVMEM
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP