• 카테고리

    질문 & 답변
  • 세부 분야

    시스템

  • 해결 여부

    미해결

mmap의 동작을 올바르게 이해했는지 질문 드리고 싶습니다.

21.02.01 02:41 작성 조회수 778

1

안녕하세요. 강의를 수강하면서 mmap을 설명하시는 부분을 제가 기존에 알고 있던 지식과 연결짓는 과정에서 제대로 연결을 지었는지 궁금하여 확인을 받았으면 하여 질문을 남기게 되었습니다.

 posix 계열의 file api(read, write) 와 같은 경우에는stream을 개방한 뒤에, read 요청이 있을 경우, kernel space에 할당된 버퍼에 device driver로 부터 가져온 내용을 block 단위로 읽어 들인 뒤, 이를 다시, user space에 존재하는 process의 메 메모리 공간에 read함수에 파라미터로 들어가는 size만큼 읽어 들이는 것으로 이해했습니다. 이 os의 paging과 연관지어 볼 때, user process와 kernel process가 다른 (정말 극악의 확률로 같을 수...도 있지만) virtual address를 물리적으로 다른 page frame을 사용하는 것으로 볼 수 있을것 같았습니다. 하지만 mmap은 file과 memory가 mapping 돠는 것으로 보아서, device driver의 io와 연결된 kernel space에 user space에서 direct하게 접근 가능한 것으로 이해했습니다. 이 방식이 가능하려면, paging을 해줄 때, kernel space와 process가 동작하는 user space에서 해당 파일을 요청한 공간이 동일한 page frame을 사용해서 동일한 physical address에 매핑이 되는 것 같았습니다. 제가 이해한 내용이 맞는지, 틀렸다면 올바른 이해가 무엇인지 궁금합니다.

답변 1

답변을 작성해보세요.

0

안녕하세요. 이종희님.

커널의 메모리 관리 방법에 대해 이 댓글을 통해 알려드리기는 힘들 것 같습니다. 주제가 워낙 커서 정확한 답변을 드리려면 저도 관련 주제에 대해 다시 공부하고 정리해서 알려드려야 할텐데, 거기까지는 이 강좌의 범위를 벗어나는 것으로 판단했습니다. 그래서 mmap() syscall의 실제 연결 고리인 device driver의 mmap()이 어떻게 구현되어 physical address와 virtual address가 연결되는지 간단히 소개드리려고 합니다. 이것을 시작점으로 하여 연구해보시면 좋은 결과 있을 것 같습니다 :)

mmap()은 user space에서 kernel space의 memory를 사용할 수 있도록 해주는 syscall 입니다. 개념적으로는 user space에서 사용하는 메모리 영역이 physical address에 그대로 매핑되는 것으로 이해할 수 있습니다. 실제 동작 과정에서는 user space에서 mmap()을 호출하면 결과적으로 해당 디바이스 드라이버의 file operations 중 mmap() 메서드를 호출하게 됩니다. 이 메서드의 원형은 다음과 같습니다.

int (*mmap)(struct file *filp, struct vm_area_struct *vma);

filp는 디바이스 파일을 열었을 때의 struct file의 포인터이고, vma가 이 디바이스에 의해 매핑되어야 할 virtual address space를 나타냅니다. 디바이스 드라이버에서는 이 mmap() 메서드 내에서 kmalloc/vmalloc 등의 방법으로 메모리를 할당받아 파라미터로 넘어온 vma에 적혀있는 메모리에 매핑을 해야 하는데, 이 때 사용되는 함수가 remap_pfn_range()라는 함수 입니다. 이 함수는 함수 이름처럼 pfn(page frame number) 영역(즉, physical address space)을 vma 영역에 매핑해줍니다. 결국, 사용자가 요구한 virtual address를 physical address에 매핑하게 되는 것이죠.

구글링을 해보시면 remap_pfn_range()를 이용해 mmap() 메서드를 구현한 간단한 예제들을 찾을 수 있습니다. 저는 아래의 코드를 찾았는데요, 한번 살펴보시고 다른 예제도 참고해보시면 좋을 것 같습니다.

// helper function, mmap's the kmalloc'd area which is physically contiguous  
int mmap_kmem(struct file *filp, struct vm_area_struct *vma)  
{  
        int ret;  
        long length = vma->vm_end - vma->vm_start;  
  
        /* check length - do not allow larger mappings than the number of 
           pages allocated */  
        if (length > NPAGES * PAGE_SIZE)  
                return -EIO;  
  
        /* map the whole physically contiguous area in one piece */  
        if ((ret = remap_pfn_range(vma,  
                                   vma->vm_start,  
                                   virt_to_phys((void *)kmalloc_area) >> PAGE_SHIFT,  
                                   length,  
                                   vma->vm_page_prot)) < 0) {  
                return ret;  
        }  
          
        return 0;  
}  

source link