#include <unistd.h>
#include <sys/mman.h>
#ifdef _POSIX_MAPPED_FILES
void * mmap(void *start, size_t length, int prot, int
flags, int fd, off_t offset);
int munmap(void *start, size_t length);
#endif
1.2. 설명
mmap() 함수는 fd로 지정된 파일(혹은 다른 객체)에서
offset을 시작으로 length바이트
만큼을 start주소로 대응시키도록 한다. start주소는
단지 그 주소를 사용했으면 좋겠다는 정도로 보통 0을 지정한다. mmap는
지정된 영역이 대응된 실제 시작위치를 반환한다.
prot인자는 원하는 메모리:::보호모드(:12)를 설정한다.
사용할 수 있는 비트는 다음과 같다.
PROT_EXEC
페이지는 실행가능하다.
PROT_READ
페이지는 읽을 수 있다.
PROT_WRITE
페이지는 쓰여질 수 있다.
PROT_NONE
페이지는 접근할 수 없다.
flags는 대응된 객체의 타입, 대응 옵션, 대응된
페이지 복사본에 대한 수정이 그 프로세스(:12)에서만 보일 것인지 아니면,
다른 참조하는 프로세스와 공유할 것인지를 설정한다. 다음과 같은 비트들을
사용할 수 있다.
MAP_FIXED
지정된 주소 이외의 다른 주소를 선택하지 않는다.
지정된 주소가 사용될 수 없다면 mmap()는 실패한다.
만일 MAP_FIXED가 지정되면, start는
페이지 크기의 배수이어야 한다. 이 옵션은 사용하지 않는 것이
좋다.
MAP_FIXED
지정된 주소 이외의 다른 주소를 선택하지 않는다.
지정된 주소가 사용될 수 없다면 mmap()는 실패한다.
만일 MAP_FIXED가 지정되면, start는
페이지 크기의 배수이어야 한다. 이 옵션은 사용하지 않는 것이
좋다.
MAP_SHARED
대응된 객체를 다른 모든 프로세스와 공유한다.
MAP_PRIVATE
개별적인 copy-on-write(:12) 대응을 만든다.(다른 프로세스와
대응 영역을 공유하지 않는다).
위의 3개의 플래그는 POSIX.1b에 규정되어 있다. 리눅스는 MAP_DENYWRITE,
MAP_EXECUTABLE, MAP_ANON(YMOUS)도 지원한다.
munmap() 는 지정된 주소 공간에 대한 대응을 푼다. 범위내의 주소에 대한
참조 계수를 늘려서 유효하지 않은 메모리 참조로 만든다.
1장. mmap(2)
파일이나 장치를 메모리에 대응시키거나 푼다.
1.1. 사용법
#include <unistd.h> #include <sys/mman.h> #ifdef _POSIX_MAPPED_FILES void * mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); int munmap(void *start, size_t length); #endif1.2. 설명
mmap() 함수는 fd로 지정된 파일(혹은 다른 객체)에서 offset을 시작으로 length바이트 만큼을 start주소로 대응시키도록 한다. start주소는 단지 그 주소를 사용했으면 좋겠다는 정도로 보통 0을 지정한다. mmap는 지정된 영역이 대응된 실제 시작위치를 반환한다. prot인자는 원하는 메모리:::보호모드(:12)를 설정한다. 사용할 수 있는 비트는 다음과 같다.
페이지는 실행가능하다.
페이지는 읽을 수 있다.
페이지는 쓰여질 수 있다.
페이지는 접근할 수 없다.
지정된 주소 이외의 다른 주소를 선택하지 않는다. 지정된 주소가 사용될 수 없다면 mmap()는 실패한다. 만일 MAP_FIXED가 지정되면, start는 페이지 크기의 배수이어야 한다. 이 옵션은 사용하지 않는 것이 좋다.
지정된 주소 이외의 다른 주소를 선택하지 않는다. 지정된 주소가 사용될 수 없다면 mmap()는 실패한다. 만일 MAP_FIXED가 지정되면, start는 페이지 크기의 배수이어야 한다. 이 옵션은 사용하지 않는 것이 좋다.
대응된 객체를 다른 모든 프로세스와 공유한다.
개별적인 copy-on-write(:12) 대응을 만든다.(다른 프로세스와 대응 영역을 공유하지 않는다).
munmap() 는 지정된 주소 공간에 대한 대응을 푼다. 범위내의 주소에 대한 참조 계수를 늘려서 유효하지 않은 메모리 참조로 만든다.
1.3. 반환값
성공시, mmap()는 내응된 영역의 포인터(:12)를 반환한다. 에러시에는 -1(MAP_FAILED)이 리턴되며, errno는 적당한 값으로 설정된다. munmap()는 0을 리턴하며, 실패시 -1이 리턴되며, errno가 설정된다.
1.4. 에러
fd가 유효한 파일 기술자가 아니다.
MAP_PRIVATE가 설정되어 있지만 fd가 읽을 수 있도록 열려 있지 않다. 또는 MAP_SHARED와 RPOT_WRITE가 설정되어 있지만 fd가 쓸 수 있도록 열려있지 않다.
start나 length나 offset이 적당하지 않다. 보통 너무 크거나 PAGESIZE 경계로 정렬되어 있지 않을 경우.
MAP_DENYWRITE가 설정되어 있으나 fd로 지정된 객체가 쓰기 위해 열려있다.
파일이 잠겨 있다.
사용할 수 있는 메모리가 없다.
1.5. 예제
#include <stdio.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <unistd.h> #include <fcntl.h> int main(int argc, char **argv) { int fd; char *file = NULL; struct stat sb; char buf[80] ={0x00,}; int flag = PROT_WRITE | PROT_READ; if (argc < 2) { fprintf(stderr, "Usage: input\n"); exit(1); } if ((fd = open(argv[1], O_RDWR|O_CREAT)) < 0) { perror("File Open Error"); exit(1); } if (fstat(fd, &sb) < 0) { perror("fstat error"); exit(1); } file = (char *)malloc(40); // mmap를 이용해서 열린 파일을 메모리에 대응시킨다. // file은 대응된 주소를 가리키고, file을 이용해서 필요한 작업을 // 하면 된다. if ((file = (char *) mmap(0, 40, flag, MAP_SHARED, fd, 0)) == -1) { perror("mmap error"); exit(1); } printf("%s\n", file); memset(file, 0x00, 40); mnumap(file); close(fd); }1.6. 참고문헌
메모리맵의 사용
리눅스 시스템 프로그래밍 8장 IPC
Recent Posts
Archive Posts
Tags