亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 3178 | 回復(fù): 5
打印 上一主題 下一主題

誰有mmap與用戶層通信的代碼? [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2010-04-30 16:39 |只看該作者 |倒序?yàn)g覽
找了一個(gè)簡(jiǎn)單的,但有問題。
內(nèi)核模塊:
static unsigned long p = 0;
static int __init init(void)
{
     p = __get_free_pages(GFP_KERNEL, 0); //
     SetPageReserved(virt_to_page(p));
     printk("<1> p = 0x%08x\n", p);
     strcpy(p, "Hello world!\n");
     return 0;
}

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

        return;
}
module_init(init);
module_exit(fini);

用戶層程序:
#define PAGE_SIZE (4*1024)
#define PAGE_OFFSET         0xc0000000
#define KERNEL_VIRT_ADDR     0xcf9e5000 //這里是硬編址的, 可以通過ioctl 或者proc來實(shí)現(xiàn)的。


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);//打印共享內(nèi)存的內(nèi)容

     munmap(buf,PAGE_SIZE);

     close(fd);
     return 0;
}

模塊可以正常加載,但用戶程序運(yùn)行會(huì)崩潰,就是物理地址(phy_addr)那里出錯(cuò),應(yīng)該怎樣確定該地址?

論壇徽章:
36
IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-10 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-16 06:20:0015-16賽季CBA聯(lián)賽之廣東
日期:2016-04-16 19:59:32IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-18 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-19 06:20:00每日論壇發(fā)貼之星
日期:2016-04-19 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-04-25 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-06 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-08 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-13 06:20:00IT運(yùn)維版塊每日發(fā)帖之星
日期:2016-05-28 06:20:00每日論壇發(fā)貼之星
日期:2016-05-28 06:20:00
2 [報(bào)告]
發(fā)表于 2010-04-30 16:47 |只看該作者
我這里有一篇總結(jié),還有源碼,LZ看一下:
http://blog.chinaunix.net/u/33048/showart_1271210.html

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2010-04-30 23:19 |只看該作者
GOD老兄,你那篇BLOG里只有提到PROC,沒有說MMAP啊。

回LZ:
#define KERNEL_VIRT_ADDR     0xcf9e5000
這個(gè)地址應(yīng)該是你的KERNEL MODULE 的PRINTK那行打印出來的地址,不同機(jī)器上不一樣的。你改了沒?

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2010-05-01 00:54 |只看該作者
模塊內(nèi)沒有實(shí)現(xiàn)mmap。

示范代碼
  1. /*內(nèi)核模塊加載函數(shù)*/
  2. int __init kmalloc_map_init(void)
  3. {
  4.     //申請(qǐng)?jiān)O(shè)備號(hào),添加cdev結(jié)構(gòu)體
  5.     buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL);
  6.     for (page = virt_to_page(buffer); page < virt_to_page(buffer + BUFFER_SIZE); page++)
  7.     {
  8.         mem_map_reserve(page);//置頁為保留,virt_to_page()將內(nèi)核虛擬地址轉(zhuǎn)化為頁
  9.     }
  10. }
  11. /*mmap()函數(shù)*/
  12. static int kmalloc_map_mmap(struct file *filp, struct vm_area_struct *vma)
  13. {
  14.     unsigned long page, pos;
  15.     unsigned long start = (unsigned long)vma->vm_start;
  16.     unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start);
  17.     if (size > BUFFER_SIZE)
  18.     {
  19.         return - EINVAL;
  20.     }
  21.     pos = (unsigned long)buffer;
  22.     /*映射buffer中的所有頁*/
  23.     while (size > 0)
  24.     {
  25.         page = virt_to_phys((void *)pos);
  26.         if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
  27.             return - EAGAIN;
  28.         start += PAGE_SIZE;
  29.         pos += PAGE_SIZE;
  30.         size -= PAGE_SIZE;
  31.     }

  32. /*

  33. **可否用io_remap_pfn_range(vma, vma->vm_start, virt_to_phys((void *)buffer) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, PAGE_SHARED)來替代remap_page_range?

  34. **在Linux kernel 2.6.27中,已經(jīng)找不到remap_page_range的實(shí)現(xiàn),見Linux kernel change log: Changes remap_page_range to remap_pfn_range for 2.6.10 and above kernels

  35. */
  36.     return 0;
  37. }

復(fù)制代碼
【Note】:mem_map_reserve是2.4版本內(nèi)核的函數(shù),2.6內(nèi)核用SetPageReserved取代之

論壇徽章:
0
5 [報(bào)告]
發(fā)表于 2010-05-01 23:19 |只看該作者
前幾天 在學(xué)習(xí)linux內(nèi)核的內(nèi)存管理時(shí)候找到了這么一個(gè)例子,不知道是否符合樓主的要求:
2.6.tar.gz (3.31 KB, 下載次數(shù): 102)

下面是這個(gè)例子的說明:
實(shí)例希望利用內(nèi)存映射,將系統(tǒng)內(nèi)核中的一部分虛擬內(nèi)存映射到用戶空間,以供應(yīng)用程序讀取——你可利用它進(jìn)行內(nèi)核空間到用戶空間的大規(guī)模信息傳輸。因此我們將試圖寫一個(gè)虛擬字符設(shè)備驅(qū)動(dòng)程序,通過它將系統(tǒng)內(nèi)核空間映射到用戶空間——將內(nèi)核虛擬內(nèi)存映射到用戶虛擬地址。我們的例子程序?qū)⒀菔景裿malloc分配的內(nèi)核虛擬地址映射到用戶地址空間的全過程。

程序里主要應(yīng)解決兩個(gè)問題:

第一是將vmalloc分配的內(nèi)核虛擬內(nèi)存正確地轉(zhuǎn)化成物理地址

因?yàn)閮?nèi)存映射先要獲得被映射的物理地址,然后才能將其映射到要求的用戶虛擬地址上。我們已經(jīng)看到內(nèi)核物理內(nèi)存映射區(qū)域中的地址可以被內(nèi)核函數(shù)virt_to_phys轉(zhuǎn)換成實(shí)際的物理內(nèi)存地址,但對(duì)于vmalloc分配的內(nèi)核虛擬地址無法直接轉(zhuǎn)化成物理地址,所以我們必須對(duì)這部分虛擬內(nèi)存格外“照顧”——先將其轉(zhuǎn)化成內(nèi)核物理內(nèi)存映射區(qū)域中的地址,然后在用virt_to_phys變?yōu)槲锢淼刂贰?br />
轉(zhuǎn)化工作需要進(jìn)行如下步驟:

a)         找到vmalloc虛擬內(nèi)存對(duì)應(yīng)的頁表,并尋找到對(duì)應(yīng)的頁表項(xiàng)。

b)        獲取頁表項(xiàng)對(duì)應(yīng)的頁面指針

c)        通過頁面得到對(duì)應(yīng)的內(nèi)核物理內(nèi)存映射區(qū)域地址。
第二是當(dāng)訪問vmalloc分配區(qū)時(shí),如果發(fā)現(xiàn)虛擬內(nèi)存尚未被映射到物理頁,則需要處理“缺頁異!薄R虼诵枰覀儗(shí)現(xiàn)內(nèi)存區(qū)域中的nopaga操作,以能返回被映射的物理頁面指針,在我們的實(shí)例中就是返回上面過程中的內(nèi)核物理內(nèi)存映射區(qū)域中的地址。由于vmalloc分配的虛擬地址與物理地址的對(duì)應(yīng)關(guān)系并非分配時(shí)就可確定,必須在缺頁現(xiàn)場(chǎng)建立頁表,因此這里不能使用remap_page_range方法,只能用vma的nopage方法一頁一頁的建立

程序組成
map_driver.c,它是以模塊形式加載的虛擬字符驅(qū)動(dòng)程序。該驅(qū)動(dòng)負(fù)責(zé)將一定長(zhǎng)的內(nèi)核虛擬地址(vmalloc分配的)映射到設(shè)備文件上。其中主要的函數(shù)有——vaddress_to_kaddress()負(fù)責(zé)對(duì)vmalloc分配的地址進(jìn)行頁表解析,以找到對(duì)應(yīng)的內(nèi)核物理映射地址(kmalloc分配的地址);map_nopage()負(fù)責(zé)在進(jìn)程訪問一個(gè)當(dāng)前并不存在的VMA頁時(shí),尋找該地址對(duì)應(yīng)的物理頁,并返回該頁的指針。

test.c 它利用上述驅(qū)動(dòng)模塊對(duì)應(yīng)的設(shè)備文件在用戶空間讀取讀取內(nèi)核內(nèi)存。結(jié)果可以看到內(nèi)核虛擬地址的內(nèi)容(ok!),被顯示在了屏幕上

PS:我也是內(nèi)核新手,對(duì)這個(gè)例子是看到云里霧里的。如果這個(gè)例子真的對(duì)樓主有幫助,而樓主又能將其輕易看懂的話,希望能給我這個(gè)菜鳥講解一下

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2010-07-30 17:01 |只看該作者
前幾天 在學(xué)習(xí)linux內(nèi)核的內(nèi)存管理時(shí)候找到了這么一個(gè)例子,不知道是否符合樓主的要求:


下面是這個(gè)例 ...
cu_liang 發(fā)表于 2010-05-01 23:19



    它這段代碼應(yīng)該是有問題的,不知道LS發(fā)現(xiàn)了沒?
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP