Linux 메모리 맵(mmap)
http://hi.baidu.com/yoursguang/blog/item/81f77f387720022296ddd814.html
http://mikeconan6.blog.163.com/blog/static/129723052200991811411776/?fromdm&isFromSearchEngine=yes
개술
메모리 맵 은 쉽게 말 하면 사용자 공간의 메모리 영역 을 커 널 공간 에 투사 하 는 것 입 니 다.맵 이 성공 한 후에 사용자 가 이 메모리 영역 에 대한 수정 은 커 널 공간 에 직접 반영 할 수 있 습 니 다.마찬가지 로 커 널 공간 이 이 지역 에 대한 수정 도 사용자 공간 을 직접 반영 합 니 다.그러면 커 널 공간<->사용자 공간 둘 사이 에 대량의 데이터 전송 등 작업 이 필요 하 다 면 효율 이 매우 높다.
다음은 일반적인 파일 을 사용자 공간 에 비 추 는 메모리 영역 설명도 입 니 다.
그림 1:
기본 함수
mmap 함 수 는 유 닉 스/linux 에서 시스템 호출 입 니 다.자세 한 내용 은<유 닉 스 Netword programming>권 2 12.2 절 을 참고 하 십시오.
mmap 시스템 호출 은 메모리 공 유 를 위 한 것 이 아 닙 니 다.프로 세 스 는 일반 파일 에 대한 접근 방식 과 달리 읽 기와 쓰기 메모리 처럼 일반 파일 을 조작 할 수 있 습 니 다.Posix 나 시스템 V 의 공유 메모리 IPC 는 순 전 히 공유 목적 에 사용 된다.물론
mmap()가 공유 메모 리 를 실현 하 는 것 도 주요 응용 중의 하나 이다.
mmap 시스템 호출 은 프로 세 스 간 에 같은 일반 파일 을 매 핑 하여 공유 메모 리 를 실현 합 니 다.일반 파일 이 프로 세 스 주소 공간 에 비 친 후 프로 세 스 는 일반 메모리 에 접근 하 는 것 처럼 파일 에 접근 할 수 있 습 니 다.read(),write()등 을 호출 하지 않 아 도 됩 니 다.mmap 는 공간 을 할당 하지 않 고 호출 프로 세 스 의 주소 공간 에 파일 을 표시 합 니 다.(그러나 virutal memory 를 차지 합 니 다)그리고 memcpy 등 으로 파일 을 쓸 수 있 습 니 다.write()를 사용 하지 않 아 도 됩 니 다.다 쓴 후에 메모리 의 내용 은 파일 에 바로 업데이트 되 지 않 고 일정 시간 지연 되 어 호출 할 수 있 습 니 다.
msync()는 당신 이 쓴 내용 을 즉시 파일 에 저장 할 수 있 도록 명시 적 으로 동기 화 합 니 다.
이 점 은 구동 과 관련 이 있 을 것 이다.통과
mmap 에서 파일 을 쓰 는 방식 은 파일 의 길 이 를 늘 릴 수 없습니다.매 핑 할 길이 가 호출 되 고 있 기 때 문 입 니 다.
mmap()에서 결 정 했 습 니 다.메모리 맵 을 취소 하려 면 호출 할 수 있 습 니 다.
메모리 맵 취소
void *
mmap
(void *
start,
size_t
length
, int
prot
, int
flags
, int
fd
, off_t
offset
)
mmap 는 파일 을 메모리 공간 에 비 추 는 데 사 용 됩 니 다.쉽게 말 하면
mmap
파일 의 내용 을 메모리 에 이미지 로 만 듭 니 다.맵 이 성공 한 후에 사용자 가 이 메모리 구역 에 대한 수정 은 커 널 공간 에 직접 반영 할 수 있 습 니 다.마찬가지 로 커 널 공간 이 이 구역 에 대한 수정 도 사용자 공간 을 직접 반영 합 니 다.그러면 커 널 공간<->사용자 공간 둘 사이 에 대량의 데이터 전송 등 작업 이 필요 하 다 면 효율 이 매우 높다.
start:매 핑 할 메모리 영역의 시작 주 소 는 보통 사용 합 니 다.
NULL(
NULL
0)。
NULL 은 메모리 주 소 를 커 널 에서 지정 합 니 다.
length:매 핑 할 메모리 영역의 크기
prot:원 하 는 메모리 보호 표지 입 니 다.파일 의 열기 모드 와 충돌 할 수 없습니다.아래 의 어떤 값 으로 or 연산 을 통 해 합 리 적 으로 조합 할 수 있 습 니 다.
PROT_EXEC
//페이지 내용 이 실 행 될 수 있 습 니 다.
PROT_READ
//페이지 내용 을 읽 을 수 있 습 니 다.
PROT_WRITE
//페이지 를 쓸 수 있 습 니 다.
PROT_NONE
//페이지 접근 불가
flags:맵 대상 의 종 류 를 지정 합 니 다.맵 옵션 과 맵 페이지 를 공유 할 수 있 습 니까?그것 의 값 은 하나 이상 의 하위 조합 체 일 수 있다.
MAP_FIXED:지정 한 맵 시작 주 소 를 사용 합 니 다.start 와 len 매개 변수 가 지정 한 메모리 영역 이 기 존 맵 공간 에 겹 치면 겹 치 는 부분 이 버 려 집 니 다.지정 한 시작 주 소 를 사용 할 수 없 으 면 작업 이 실 패 됩 니 다.그리고 시작 주 소 는 페이지 의 경계 에 있어 야 합 니 다.
MAP_SHARED:맵 영역 에 대한 기록 데 이 터 는 파일 로 복사 되 며,이 파일 을 비 추 는 다른 프로 세 스 가 공유 할 수 있 습 니 다.
MAP_PRIVATE:기록 할 때 복사 하 는 개인 맵 을 만 듭 니 다.메모리 영역의 기록 은 원본 파일 에 영향 을 주지 않 습 니 다.이 표지 와 상기 표 지 는 서로 배척 하 는 것 으로 그 중의 하나 만 사용 할 수 있다.
MAP_DENYWRITE:이 표 지 는 무시 되 었 습 니 다.
MAP_EXECUTABLE:동상
MAP_NORESERVE:이 맵 을 위해 교환 공간 을 유지 하지 마 세 요.교환 공간 이 유지 되면 맵 영역 수정 이 보 장 될 수 있 습 니 다.교환 공간 이 보존 되 지 않 고 메모리 가 부족 할 때 맵 영역 에 대한 수정 은 세그먼트 위반 신 호 를 일 으 킬 수 있 습 니 다.
MAP_LOCKED:맵 영역의 페이지 를 잠 그 고 페이지 가 메모리 로 교환 되 는 것 을 방지 합 니 다.
MAP_GROWSDOWN:스 택 에 사용 되 며 커 널 VM 시스템 에 맵 영역 을 아래로 확장 할 수 있 음 을 알려 줍 니 다.
MAP_ANONYMOUS :익명 맵,맵 영역 은 파일 과 연결 되 지 않 습 니 다.
MAP_ANON :MAP_애 니 마우스 의 별칭 은 더 이상 사용 되 지 않 는 다.
MAP_FILE :호 환 표지,무시.
MAP_32BIT:프로 세 스 주소 공간의 낮은 2GB,맵FIXED 지정 시 무시 합 니 다.현재 이 표 지 는 x86-64 플랫폼 에서 만 지 원 됩 니 다.
MAP_POPULATE :파일 맵 을 위해 미리 읽 는 방식 으로 페이지 표를 준비 합 니 다.이후 맵 영역 에 대한 접근 은 페이지 위반 으로 막 히 지 않 습 니 다.
MAP_NONBLOCK:MAPPOPULATE 를 함께 사용 할 때 만 의미 가 있 습 니 다.미리 읽 기 를 실행 하지 않 고 메모리 에 존재 하 는 페이지 에 만 페이지 입 구 를 만 듭 니 다.
fd:파일 설명자(open 함수 에서 되 돌아 오기)
offset:비 치 는 대상(즉 파일)이 거기서 부터 비 치 는 것 을 표시 합 니 다.보통 0 을 사용 합 니 다.이 값 은 크기 가 PAGE 여야 합 니 다.SIZE 의 정수 배
설명
성공 적 으로 실 행 될 때,mmap()는 매 핑 된 영역의 바늘 을 되 돌려 주 고,munmap()는 0 을 되 돌려 줍 니 다.실패 시 mmap()를 MAP 로 되 돌려 줍 니 다.FAILED[그 값 은(void*)-1],munmap 반환-1 입 니 다.errno 는 다음 값 으로 설정 되 어 있 습 니 다.
EACCES:접근 오류
EAGAIN:파일 이 잠 겨 있 거나 너무 많은 메모리 가 잠 겨 있 습 니 다.
EBADF:fd 는 올 바른 파일 설명 어가 아 닙 니 다.
EINVAL:하나 이상 의 인자 가 잘못 되 었 습 니 다.
ENFILE:파일 열기 에 대한 시스템 제한 에 도 달 했 습 니 다.
ENODEV:파일 이 있 는 파일 시스템 은 메모리 맵 을 지원 하지 않 습 니 다.
ENOMEM:메모리 가 부족 하거나 프로 세 스 가 최대 메모리 맵 수 를 초과 하 였 습 니 다.
EPERM:권한 부족,조작 불가
ETXTBSY:이미 작 성 된 방식 으로 파일 을 열 고 MAP 를 지정 합 니 다.DENYWRITE 로고
SIGSEGV:읽 기 전용 영역 에 쓰기
SIGBUS:프로 세 스 에 속 하지 않 는 메모리 에 접근 해 보십시오
int
munmap
(void *
start,
size_t
length)
start:매 핑 된 메모리 영역의 시작 주 소 를 취소 합 니 다.
length:맵 의 메모리 영역 크기 를 취소 합 니 다.
설명
성공 적 으로 실행 되 었 을 때 munmap()는 0 을 되 돌려 줍 니 다.실패 시 munmap 반환-1
int
msync
(const void *start, size_t length, int flags);
맵 메모리 의 내용 변경 은 파일 에 바로 업데이트 되 지 않 고 일정 시간 지연 되 어 호출 할 수 있 습 니 다.
msync()메모리 업데이트 가 파일 에 바로 저 장 될 수 있 도록 디 스 플레이 동기 화 합 니 다.
start:동기 화 할 메모리 영역의 시작 주소 입 니 다.
length:동기 화 할 메모리 영역의 크기
flag:flags 는 다음 세 가지 값 중 하나 일 수 있 습 니 다.
MS_ASYNC:Kernel 에서 자 료 를 빨리 기록 해 주세요.
MS_SYNC:msync 가 끝나 고 돌아 오기 전에 자 료 를 기록 합 니 다.
MS_INVALIDATE:핵심 이 쓰기 여 부 를 스스로 결정 하고 특수 한 상황 에서 만 사용 하도록 합 니 다.
3.사용자 공간 과 드라이버 의 메모리 맵
3.1 기본 과정
우선,드라이버 는 먼저 메모리 한 토막 을 분배 하고,이어서 사용자 프로 세 스 는 라 이브 러 리 함 수 를 통과 한다
mmap()
커 널 이 커 널 공간 에 얼마나 큰 메모 리 를 비 추 는 지 알려 줍 니 다.커 널 은 일련의 함수 호출 을 거 쳐 해당 하 는 드라이버 를 호출 합 니 다.
file_operation
지정
mmap
함수
remap_pfn_range()
맵 관 계 를 맺 습 니 다.
3.2 매 핑 의 실현
먼저 드라이버 에 한 페이지 크기 의 메모 리 를 할당 한 다음,사용자 프로 세 스 는 mmap()를 통 해 사용자 공간의 크기 도 한 페이지 의 메모리 로 커 널 공간 이라는 메모리 에 표시 합 니 다.맵 이 완료 되면 드라이버 는 이 메모리 에 10 개의 바이트 데 이 터 를 쓰 고 사용자 프로 세 스 는 이 데 이 터 를 표시 합 니 다.
드라이버:
1
#include
<linux/miscdevice.h>
2
#include
<linux/delay.h>
3
#include
<linux/kernel.h>
4
#include
<linux/module.h>
5
#include
<linux/init.h>
6
#include
<linux/mm.h>
7
#include
<linux/fs.h>
8
#include
<linux/types.h>
9
#include
<linux/delay.h>
10
#include
<linux/moduleparam.h>
11
#include
<linux/slab.h>
12
#include
<linux/errno.h>
13
#include
<linux/ioctl.h>
14
#include
<linux/cdev.h>
15
#include
<linux/string.h>
16
#include
<linux/list.h>
17
#include
<linux/pci.h>
18
#include
<linux/gpio.h>
19
20
21
#define
DEVICE_NAME
"mymap"
22
23
24
static
unsigned
char
array
[
10
]={
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
};
25
static
unsigned
char
*
buffer
;
26
27
28
static
int
my_open
(
struct
inode
*
inode
,
struct
file
*
file
)
29
{
30
return
0
;
31
}
32
33
34
static
int
my_map
(
struct
file
*
filp
,
struct
vm_area_struct
*
vma
)
35
{
36
unsigned
long
page
;
37
unsigned
char
i
;
38
unsigned
long
start
=
(
unsigned
long
)
vma
->
vm_start
;
39
//unsigned long end = (unsigned long)vma->vm_end;
40 unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start);
41
42 //
43 page = virt_to_phys(buffer);
44 // vma page
45 if(remap_pfn_range(vma,start,page>>PAGE_SHIFT,size,PAGE_SHARED))// , PAGE_SHIFT
46 return -1;
47
48 // 10
49 for(i=0;i<10;i++)
50 buffer[i] = array[i];
51
52 return 0;
53 }
54
55
56 static struct file_operations dev_fops = {
57 .owner = THIS_MODULE,
58 .open = my_open,
59 .mmap = my_map,
60 };
61
62 static struct miscdevice misc = {
63 .minor = MISC_DYNAMIC_MINOR,
64 .name = DEVICE_NAME,
65 .fops = &dev_fops,
66 };
67
68
69 static int __init dev_init(void)
70 {
71 int ret;
72
73 //
74 ret = misc_register(&misc);
75 //
76 buffer = (unsigned char *)kmalloc(PAGE_SIZE,GFP_KERNEL);
77 //
78 SetPageReserved(virt_to_page(buffer));
79
80 return ret;
81 }
82
83
84 static void __exit dev_exit(void)
85 {
86 //
87 misc_deregister(&misc);
88 //
89 ClearPageReserved(virt_to_page(buffer));
90 //
91 kfree(buffer);
92 }
93
94
95 module_init(dev_init);
96 module_exit(dev_exit);
97 MODULE_LICENSE("GPL");
98 MODULE_AUTHOR("LKN@SCUT");
응용 프로그램:
1
#include
<unistd.h>
2
#include
<stdio.h>
3
#include
<stdlib.h>
4
#include
<string.h>
5
#include
<fcntl.h>
6
#include
<linux/fb.h>
7
#include
<sys/mman.h>
8
#include
<sys/ioctl.h>
9
10
#define
PAGE_SIZE
4096
11
12
13
int
main
(
int
argc
,
char
*
argv
[])
14
{
15
int
fd
;
16
int
i
;
17
unsigned
char
*
p_map
;
18
19
//
20 fd = open("/dev/mymap",O_RDWR);
21 if(fd < 0)
22 {
23 printf("open fail
");
24 exit(1);
25 }
26
27 //
28 p_map = (unsigned char *)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);
29 if(p_map == MAP_FAILED)
30 {
31 printf("mmap fail
");
32 goto here;
33 }
34
35 // 10
36 for(i=0;i<10;i++)
37 printf("%d
",p_map[i]);
38
39
40 here:
41 munmap(p_map, PAGE_SIZE);
42 return 0;
43 }
먼저 드라이버 를 불 러 온 후 프로그램 을 실행 합 니 다.사용자 공간 인쇄 는 다음 과 같 습 니 다.
0
1
2
3
4
5
6
7
8
9
끝나다
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
용감한 바로 가기 및 우분투 응용 프로그램안녕하세요 여러분, 이 기사에서는 모든 사이트에서 pwa를 생성하고 실행기 응용 프로그램으로 추가하는 방법을 설명하고 싶습니다. 일부 웹사이트는 PWA로 설치를 허용하지 않지만 유사한 애플리케이션을 원합니다. 1. ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.