天天看點

使用者空間與kernel空間通信的例子(利用mmap) [zt]

使用者空間與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; }

希望對對大家有所幫助 , 其實從這裡我們也可以拓展我們自己的代碼呀 。

比如如何配置設定記憶體什麼的, 我們可以試試很多核心的函數。