나는 리눅스가 파일을 메인 메모리에 저장하는 방법에 관심이 있는데 (내 맥락에서 실행을 위해 mmap 프로세스가 동일하고 쓰기도 동일하다고 생각합니다.)
그래서 리눅스가 보통 4kB 페이지 크기로 페이징을 사용한다는 것을 알고 있습니다 (커널 에서이 크기를 찾을 수 있습니까?). 그러나 이것이 정확히 할당 된 메모리에 대해 의미하는 것은 다음과 같습니다. 몇 천 바이트의 이진 크기가 있다고 가정하면 5812B라고 말하면 실행됩니다. 커널에서 발생하는 일 : 2 * 4kB를 할당 한 다음 5812B를이 공간에 복사하여 두 번째 페이지에서> 3KB의 주 메모리를 낭비합니까?
페이지 크기가 정의 된 커널 소스의 파일을 아는 사람이 있으면 좋을 것입니다.
내 두 번째 질문도 매우 간단합니다. 파일 크기로 5812B를 가정했습니다. 이 크기는 단순히 inode에서 가져온 것입니까?
답변
실행 파일의 크기와 메모리의 크기 사이에는 직접적인 관계가 없습니다. 바이너리가 실행될 때 일어나는 일에 대한 매우 빠른 개요는 다음과 같습니다.
- 커널은 파일을 구문 분석하여 섹션으로 나눕니다. 일부 섹션은 별도의 페이지에서 메모리에 직접로드됩니다. 일부 섹션은 전혀로드되지 않습니다 (예 : 디버깅 기호).
- 실행 파일이 동적으로 링크되면 커널은 동적 로더를 호출하고 필요한 공유 라이브러리를로드하고 필요에 따라 링크 에디션을 수행합니다.
- 프로그램은 코드 실행을 시작하고 일반적으로 데이터를 저장하기 위해 더 많은 메모리를 요청합니다.
실행 파일 형식, 링크 및 실행 파일로드에 대한 자세한 내용은 John R. Levine의 링커 및 로더 를 참조하십시오 .
5kB 실행 파일에서는 헤더를 제외한 모든 것이 메모리로로드되어야하는 코드 또는 데이터 일 가능성이 높습니다. 실행 코드는 적어도 한 페이지, 아마도 두 페이지 일 것이고, 스택을위한 적어도 하나의 페이지, 아마도 한 페이지 또는 힙 (다른 데이터)과 공유 라이브러리가 사용하는 메모리가있을 것입니다.
Linux에서는을 사용하여 실행 파일에 대한 메모리 매핑을 검사 할 수 있습니다 cat /proc/$pid/maps
. 형식은 proc(5)
매뉴얼 페이지에 설명되어 있습니다. Linux / proc / id / maps 이해를 참조하십시오 .
답변
예 : 결국 두 개의 4k 페이지를 얻습니다. 요청시 데이터가로드되므로 두 번째 페이지를 참조하는 것이 없으면 메모리에로드되지 않습니다.
include/asm-i386/param.h:#define EXEC_PAGESIZE 4096
include/asm-i386/elf.h:#define ELF_EXEC_PAGESIZE 4096
이 값을 변경하지 말고 작동 할 것으로 예상하십시오.
예, 파일 크기는 ext2 / 3의 inode에 저장됩니다.
답변
정의 부분의 경우 인텔 아키텍처의 2.6.38 ~ ish 커널에서 :
arch / x86 / include / asm / page_types.h :
/ * PAGE_SHIFT는 페이지 크기를 결정합니다 * /
#define PAGE_SHIFT 12
# PAGE_SIZE 정의 (_AC (1, UL) << PAGE_SHIFT)