2012年11月11日 星期日

ioremap , mmap

[ioremap]
    1: 驅動程式,不能夠直接存取實體記憶體,必須存取相對應的虛擬記憶體.

    2: 用於kernel mode.

    3: 實質code的轉換為  #define io_p2v(x) ((x) | 0xa0000000) <---broadcom 也是用這個,但
        是 為啥是 0xa0000000?

[mmap]
    1: 檔案對映到記憶體空間,高速存取.
   
    2: 檔案當成記憶體來用. 變成共享記憶體的觀念(但是實質上為檔案讀寫,類似fifo)

    3:I/O device存取. (不用buffer的方式存取,效率較高)


[有用的函數]
   void * ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags);
    void iounmap(void * addr);
   
    #define readb(addr) (*(volatile unsigned char *) __io_virt(addr))
    #define readw(addr) (*(volatile unsigned short *) __io_virt(addr))
    #define readl(addr) (*(volatile unsigned int *) __io_virt(addr))

    #define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b))
    #define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b))
    #define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b))

    #define memset_io(a,b,c) memset(__io_virt(a),(b),(c))
    #define memcpy_fromio(a,b,c) memcpy((a),__io_virt(b),(c))
    #define memcpy_toio(a,b,c) memcpy(__io_virt(a),(b),(c))



    size_t getpagesize(void);   //記憶體以page作為單位(intel x86 ,4096 Bytes(4K))
    void  *  mmap(void  *start,  size_t length, int prot , int flags, int fd, off_t offset);
    int munmap(void *start, size_t length); 
    start指定記憶體位置,通常都是用NULL。offset指定檔案要在那裡開始對映,通常都是用
    0。
    protections
    PROT_READ
    PROT_WRITE
    PROT_EXEC
    PROT_NONE

    flags
    MAP_FIXED
    MAP_PRIVATE
    MAP_SHARED

    MAP_ANONYMOUS
    MAP_DENYWRITE
    MAP_GROWSDOWN
    MAP_LOCKED
 
    munmap關閉。


    int msync(const void *start, size_t length, int flags);  <---立即寫入(記憶體對映的對象是檔案)
    flags:
    MS_ASYNC : 請Kernel快將資料寫入。
    MS_SYNC : 在msync結束返回前,將資料寫入。
    MS_INVALIDATE : 讓核心自行決定是否寫入,僅在特殊狀況下使用。

    int mlock(const void *addr, size_t len);
    int munlock(const void *addr, size_t len);

    int mlockall(int flags);
    int munlockall(void);



    

        



    

   

    













 


沒有留言:

張貼留言