使用者空間與kernel空間通信的例子(利用mmap)
http://blog.chinaunix.net/u/22617/showart_215420.html
前些日子看到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;
}
希望對對大家有所幫助 , 其實從這裡我們也可以拓展我們自己的代碼呀 。
比如如何配置設定記憶體什麼的, 我們可以試試很多核心的函數。