Chinaunix首页 | 论坛 | 博客
  • 博客访问: 642790
  • 博文数量: 75
  • 博客积分: 7001
  • 博客等级: 少将
  • 技术积分: 1465
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-11 17:39
文章分类

全部博文(75)

文章存档

2010年(1)

2009年(25)

2008年(49)

我的朋友

分类: LINUX

2008-04-14 10:18:58

用户空间与kernel空间通信的例子(利用mmap)
 


前些日子看到linuxforum上wheelz发的一个帖子, kernel空间和用户空间通信的经典的例子 。


特整理一下:

kernel代码:


#include
#include
#include
#include

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Wheelz");
MODULE_DESCRIPTION("mmap demo");

static unsigned long p = 0;

static int __init init(void)
{
     //分配共享内存(一个页面)
     p = __get_free_pages(GFP_KERNEL, 0); //得到的当然是一个虚拟地址了
     SetPageReserved(virt_to_page(p)); //#define virt_to_page(kaddr)     (mem_map + (__pa(kaddr) >> PAGE_SHIFT)) //12
     printk("<1> p = 0x%08x\n", p);
     //在共享内存中写上一个字符串
     strcpy(p, "Hello world!\n");
     return 0;
}

static void __exit exit(void)
{
     ClearPageReserved(virt_to_page(p));
     free_pages(p, 0);
}

module_init(init);
module_exit(exit);

用户空间的测试程序:
#include
#include
#include
#include
#include

#define PAGE_SIZE (4*1024)

#define PAGE_OFFSET         0xc0000000
#define KERNEL_VIRT_ADDR     0xcf9e5000 //这里是硬编址的, 可以通过ioctl 或者proc来实现的。


int main()
{
     char *buf;
     int fd;
     unsigned long phy_addr;

     fd=open("/dev/mem",O_RDWR);
     if(fd == -1)
         perror("open");
     phy_addr=KERNEL_VIRT_ADDR - PAGE_OFFSET;

     buf=mmap(0, PAGE_SIZE,
         PROT_READ|PROT_WRITE, MAP_SHARED,
         fd, phy_addr);
     if(buf == MAP_FAILED)
         perror("mmap");
     puts(buf);//打印共享内存的内容

     munmap(buf,PAGE_SIZE);

     close(fd);
     return 0;
}


希望对对大家有所帮助 , 其实从这里我们也可以拓展我们自己的代码呀 。

比如如何分配内存什么的, 我们可以试试很多内核的函数。

确实是个好例子。

原文地址:http://blog.chinaunix.net/u/22617/showart_215420.html

阅读(1374) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinavte2009-04-18 21:21:12

学习一下!!