1¡¢mmapϵͳµ÷Ó㨹¦ÄÜ£©
void* mmap ( void * addr , size_t len , int prot , int flags ,int fd , off_t offset )
ÄÚ´æÓ³É亯Êýmmap, ¸ºÔð°ÑÎļþÄÚÈÝÓ³Éäµ½½ø³ÌµÄÐéÄâÄÚ´æ¿Õ¼ä, ͨ¹ý¶ÔÕâ¶ÎÄÚ´æµÄ¶ÁÈ¡ºÍÐ޸ģ¬À´ÊµÏÖ¶ÔÎļþµÄ¶ÁÈ¡ºÍÐÞ¸Ä,¶ø²»ÐèÒªÔÙµ÷ÓÃread£¬writeµÈ²Ù×÷¡£
2¡¢mmapϵͳµ÷Ó㨲ÎÊý£©
1£©addr£º Ö¸¶¨Ó³ÉäµÄÆðʼµØÖ·, ͨ³£ÉèΪNULL, ÓÉϵͳָ¶¨¡£
2£©length: Ó³Éäµ½ÄÚ´æµÄÎļþ³¤¶È¡£
3£© prot£º Ó³ÉäÇøµÄ±£»¤·½Ê½, ¿ÉÒÔÊÇ:
PROT_EXEC: Ó³ÉäÇø¿É±»Ö´ÐÐ
PROT_READ: Ó³ÉäÇø¿É±»¶ÁÈ¡
PROT_WRITE: Ó³ÉäÇø¿É±»Ð´Èë
4£©flags: Ó³ÉäÇøµÄÌØÐÔ, ¿ÉÒÔÊÇ:
MAP_SHARED:дÈëÓ³ÉäÇøµÄÊý¾Ý»á¸´ÖÆ»ØÎļþ, ÇÒÔÊÐíÆäËûÓ³Éä¸ÃÎļþµÄ½ø³Ì¹²Ïí¡£
MAP_PRIVATE:¶ÔÓ³ÉäÇøµÄдÈë²Ù×÷»á²úÉúÒ»¸öÓ³ÉäÇøµÄ¸´ÖÆ(copy-on-write), ¶Ô´ËÇøÓòËù×öµÄÐ޸IJ»»áд»ØÔÎļþ¡£
5£©fd: ÓÉopen·µ»ØµÄÎļþÃèÊö·û, ´ú±íÒªÓ³ÉäµÄÎļþ¡£
6£©offset: ÒÔÎļþ¿ªÊ¼´¦µÄÆ«ÒÆÁ¿, ±ØÐëÊÇ·ÖÒ³´óСµÄÕûÊý±¶, ͨ³£Îª0, ±íʾ´ÓÎļþÍ·¿ªÊ¼Ó³Éä¡£
3¡¢½â³ýÓ³Éä
int munmap(void *start,size_t length)
¹¦ÄÜ£ºÈ¡Ïû²ÎÊýstartËùÖ¸ÏòµÄÓ³ÉäÄڴ棬²ÎÊýlength±íʾÓûÈ¡ÏûµÄÄÚ´æ´óС¡£
·µ»ØÖµ£º½â³ý³É¹¦·µ»Ø0£¬·ñÔò·µ»Ø£1£¬´íÎóÔÒò´æÓÚerrnoÖС£
ʵÀý·ÖÎö
mmapϵͳµ÷ÓÃ
4¡¢ÐéÄâÄÚ´æÇøÓò
ÐéÄâÄÚ´æÇøÓòÊǽø³ÌµÄÐéÄâµØÖ·¿Õ¼äÖеÄÒ»¸öͬÖÊÇø¼ä£¬¼´¾ßÓÐͬÑùÌØÐÔµÄÁ¬ÐøµØÖ··¶Î§¡£Ò»¸ö½ø³ÌµÄÄÚ´æÓ³ÏóÓÉÏÂÃæ¼¸²¿·Ö×é³É£º³ÌÐò´úÂë¡¢Êý¾Ý¡¢BSS
ºÍÕ»ÇøÓò£¬ÒÔ¼°ÄÚ´æÓ³ÉäµÄÇøÓò¡£
Ò»¸ö½ø³ÌµÄÄÚ´æÇøÓò¿ÉÒÔͨ¹ý²é¿´£º/proc/pid/maps
08048000-0804f000 r-xp 00000000 08:01 573748 /sbin/rpc.statd #text
0804f000-08050000 rw-p 00007000 08:01 573748 /sbin/rpc.statd #data
08050000-08055000 rwxp 00000000 00:00 0 #bss
040000000-40015000 r-xp 00000000 08:01 933965 /lib/ld2.3.2.so #text
40015000-40016000 rw-p 00014000 08:01 933965 /lib/ld-2.3.2.so #data
ÿһÐеÄÓòΪ£ºstart_end perm offset major:minor inode
1£© Start: ¸ÃÇøÓòÆðʼÐéÄâµØÖ·
2£© End: ¸ÃÇøÓò½áÊøÐéÄâµØÖ·
3£© Perm: ¶Á¡¢Ð´ºÍÖ´ÐÐȨÏÞ£»±íʾ¶ÔÕâ¸öÇøÓò£¬ÔÊÐí½ø³Ì×öʲô¡£Õâ¸öÓòµÄ×îºóÒ»¸ö×Ö·ûҪôÊÇp±íʾ˽Óеģ¬ÒªÃ´ÊÇs±íʾ¹²ÏíµÄ¡£
4£© Offset: ±»Ó³É䲿·ÖÔÚÎļþÖÐµÄÆðʼµØÖ·
5£© Major¡¢minor£ºÖ÷´ÎÉ豸ºÅ
6£© Inode£ºË÷Òý½áµã
5¡¢vm_area_struct
LinuxÄÚºËʹÓýṹvm_area_struct£¨£©À´ÃèÊöÐéÄâÄÚ´æÇøÓò£¬ÆäÖм¸¸öÖ÷Òª³ÉÔ±ÈçÏ£º
1£©unsigned long vm_start ÐéÄâÄÚ´æÇøÓòÆðʼµØÖ·
2£©unsigned long vm_end ÐéÄâÄÚ´æÇøÓò½áÊøµØÖ·
3£©unsigned long vm_flags ¸ÃÇøÓòµÄ±ê¼Ç¡£Èç:VM_IOºÍVM_RESERVED¡£VM_IO½«¸ÃVMA±ê¼ÇΪÄÚ´æÓ³ÉäµÄIOÇøÓò£¬VM_IO»á×èֹϵͳ½«¸ÃÇøÓò°üº¬ÔÚ½ø³ÌµÄ´æ·Åת
´æ(core dump )ÖУ¬VM_RESERVED±êÖ¾ÄÚ´æÇøÓò²»Äܱ»»»³ö¡£
6¡¢mmapÉ豸²Ù×÷
Ó³ÉäÒ»¸öÉ豸ÊÇÖ¸°ÑÓû§¿Õ¼äµÄÒ»¶ÎµØÖ·¹ØÁªµ½É豸ÄÚ´æÉÏ¡£µ±³ÌÐò¶ÁдÕâ¶ÎÓû§¿Õ¼äµÄµØÖ·Ê±£¬Ëüʵ¼ÊÉÏÊÇÔÚ·ÃÎÊÉ豸¡£
mmapÉ豸·½·¨ÐèÒªÍê³Éʲô¹¦ÄÜ£¿
mmap·½·¨ÊÇfile_oprations½á¹¹µÄ³ÉÔ±£¬ÔÚmmapϵͳµ÷Ó÷¢³öʱ±»µ÷Óá£ÔÚ´Ë֮ǰ£¬ÄÚºËÒѾÍê³ÉÁ˺ܶ๤×÷¡£mmapÉ豸·½·¨ËùÐèÒª×öµÄ¾ÍÊǽ¨Á¢
ÐéÄâµØÖ·µ½ÎïÀíµØÖ·µÄÒ³±í¡£
int (*mmap) (struct file *, struct vm_area_struct *)
mmapÈçºÎÍê³ÉÒ³±íµÄ½¨Á¢£¿
·½·¨Óжþ£º
1£©Ê¹ÓÃremap_pfn_rangeÒ»´Î½¨Á¢ËùÓÐÒ³±í;
2£©Ê¹ÓÃnopage VMA·½·¨Ã¿´Î½¨Á¢Ò»¸öÒ³±í¡£
¹¹ÔìÒ³±íµÄ¹¤×÷¿ÉÓÉremap_pfn_rangeº¯ÊýÍê³É£¬ÔÐÍÈçÏ£º
int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,unsigned long pfn, unsigned long size, pgprot_t prot)
vma: ÐéÄâÄÚ´æÇøÓòÖ¸Õë
virt_addr: ÐéÄâµØÖ·µÄÆðʼֵ
pfn: ÒªÓ³ÉäµÄÎïÀíµØÖ·ËùÔÚµÄÎïÀíÒ³Ö¡ºÅ£¬¿É½«ÎïÀíµØÖ·>>PAGE_SHIFTµÃµ½¡£
size: ÒªÓ³ÉäµÄÇøÓòµÄ´óС¡£
prot: VMAµÄ±£»¤ÊôÐÔ¡£
int memdev_mmap(struct file*filp, struct vm_area_struct *vma)
{
Vma->vm_flags |= VM_IO;
Vma->vm_flags |= VM_RESERVED;
if (remap_pfn_range(vma, vma->vm_start,
virt_to_phys(dev- >data)>> PAGE_SHIFT,
size,
vma->vm_page_prot))
return -EAGAIN;
return 0;
}