Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1638706
  • 博文数量: 197
  • 博客积分: 10046
  • 博客等级: 上将
  • 技术积分: 1983
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-07 12:36
个人简介

在外企做服务器开发, 目前是项目经理, 管理两个server开发的项目。不做嵌入式好久了。

文章分类
文章存档

2011年(2)

2010年(6)

2009年(18)

2008年(30)

2007年(100)

2006年(41)

分类: LINUX

2006-12-14 12:37:42

前些日子看到linuxforum上wheelz发的一个帖子, kernel空间和用户空间通信的经典的例子 。
 
 
特整理一下:
 
kernel代码:
 
 

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>

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 <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

#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;
}

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

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

确实是个好例子。

 

 

 

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

chinaunix网友2011-06-27 09:49:05

有必要这么复杂吗? 内核可以随便读写内存,开一块内存共享给所有进程就可以了。