Pages

2008年12月31日 星期三

mmap()

mmap 函式是用來將檔案映射到記憶體,video for linux two 就是透過這種方式,將 device memory mapping into user space,而 uvcvideo driver 會實作這個 file operation,來幫 camera application 建立 VMA 區段。mmap() 的原型如下:##ReadMore##

void *mmap(void *addr, size_t len, int prot,
      int
flags,int fildes, off_t off);
  • addr:用來告知從哪個記憶體位址開始映射,不過通常是擺 NULL,直接給作業系統決定,否則還要考慮對齊問題(alignment)
  • len:映射的大小
  • prot:對此記憶體的操作限制,如:PROT_READ、PROT_WRITE、PROT_EXEC、PROT_NONE
  • flags:對此記憶體的存取方式,如:MAP_SHARED、MAP_PRIVATE、MAP_FIXED,使用 MAP_SHARED 時,如果某一個行程有對 mmap 的記憶體做修改,那其他同樣有做 mmap 的行程會看到相同結果。(對同一個檔案)
  • fildes:open file 所得到的 fd。
  • off:指定檔案從哪裡開始對映
在此用 mmap 做個小實驗。首先建立一般的實體檔案,然後關閉它,接著透過映射到的記憶體來間接寫入字串到該檔案中。
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#define FILE_LENGTH 0x400 /* 1024 */

int main(int argc, char *argv[])
{
    int fd;
    void *map_memory;

    if(argc < 2) {
        printf("Usage: ./a.out <string>\n");
        return 1;
    }

    /*
     * Open a file to be mapped.
     * S_IRUSR: read permission, owner
     * S_IWUSR: write permission, owner
     */
    fd = open("/tmp/shared_file", O_RDWR | O_CREAT,
        S_IRUSR | S_IWUSR);
        lseek(fd, FILE_LENGTH-1, SEEK_SET);
        write(fd, "", 1);
        lseek(fd, 0, SEEK_SET);

    /* Create map memory. */
    map_memory = mmap(0, FILE_LENGTH,
        PROT_WRITE, MAP_SHARED,
        fd, 0);
    
    close(fd);

    /* Write to mapped memory. */
    if(strlen(argv[1]) < FILE_LENGTH)
        sprintf((char*)map_memory, "%s", argv[1]);

    munmap(map_memory, FILE_LENGTH);
    return 0;
}
這樣的作法還是可以將內容寫入檔案,而且速度比單純寫入檔案還要快,但似乎 mmap有大小的限制,因為我設定到 0x40000000,程式執行完後,系統變得怪怪的 =.=?。以下是該測試程式的 VMA 區段,位於 /proc/xxxx/maps,其中 xxxx 是 process id,可以在執行程式時輸入 &,如:./mmaptest input_string &。
08048000-08049000 r-xp 00000000 08:06 606289 /home/linly/Sample/mmap_write
...
b7df2000-b7f4a000 r-xp 00000000 08:06 1497227 /lib/tls/i686/cmov/libc-2.8.90.so
...
b7f61000-b7f62000 -w-s 00000000 08:06 686791 /tmp/shared_file
...
b7f80000-b7f81000 rw-p 0001b000 08:06 1479875 /lib/ld-2.8.90.so
bff6c000-bff81000 rw-p bffeb000 00:00 0 [stack]

沒有留言:

 
Blogger Templates