너무 길어요. 도대체 커널이 /proc/$PID/maps
.
다음 C 프로그램 설명을 고려하십시오.
static char page1[PAGE_SIZE] __attribute__ ((aligned (PAGE_SIZE)))
이제 초기화되지 않은 변수는 처음에는 0입니다. 내가 이해한 바는 프로그램 시작 시 커널이 초기화되지 않은 변수를 페이지 0에 매핑하고 페이지의 쓰기 시 복사 지연 할당을 수행한다는 것입니다. 페이지 오류가 발생할 때 커널이 더티 페이지의 초기화되지 않은 부분을 설명할 수 있으므로 좋습니다.
이제 이 말을 생각해 보세요.
static char page1[PAGE_SIZE] __attribute__ ((aligned (PAGE_SIZE))) = {'c'}
여기서 로더는 프로그램 초기화 중에 page1의 값을 로드하고 해당 페이지를 RW로 표시합니다. 따라서 프로그램에서 수행한 모든 쓰기는 페이지 오류가 발생하지 않으므로 커널에 표시되지 않아야 합니다.
이것은 제가 실험을 위해 작성한 프로그램입니다.
#define PAGE_SIZE (4*1024)
static char page1[PAGE_SIZE] __attribute__ ((aligned (PAGE_SIZE))) = {'c'};
int main()
{
char c; int i; int *d;
scanf("%c", &c); // --------- tag 1
for(i = 0; i < PAGE_SIZE; i++)
{
page1[i] = c; // --------- tag 2
}
d = malloc(sizeof(int));
while(1);
return 0;
}
이제 레이블 1(코드의 주석) 앞뒤에 /proc/$PID/smaps
포함된 섹션의 출력이 page1
아래 표에 붙여넣어집니다.
스투 | 1개 전 태그 | TAG-2 이후 |
---|---|---|
크기: | 8KB | 8KB |
커널 페이지 크기: | 4KB | 4KB |
MMU 페이지 크기: | 4KB | 4KB |
RSS: | 8KB | 8KB |
첨부된: | 8KB | 8KB |
공유_클린: | 0KB | 0KB |
공유_더러운: | 0KB | 0KB |
개인 청소: | 4KB | 0KB |
개인_더러운: | 4KB | 8KB |
인용하다: | 8KB | 8KB |
익명의: | 4KB | 8KB |
보시다시피 굵은 색상에 대한 매개변수가 변경되었습니다.
질문
- 내가 이 페이지를 썼다는 것을 커널은 어떻게 알았는가?
- 이 익명 필드는 무엇이며 왜 변경됩니까?
모든 작업을 자세히 설명하는 다른 페이지/블로그/매뉴얼이 도움이 될 것입니다.
나는 추측한다:
아마도 커널은 페이지가 RW임에도 불구하고 페이지를 RO로 표시하여 페이지 오류가 발생하고 계산될 수 있습니다. 또는 프로세스의 페이지 테이블을 지속적으로 순회하는 다른 프로세스가 있을 수도 있지만 비용이 너무 많이 듭니다.
답변1
Linux가 지원하는 대부분의(아마도 전부는 확인하지 않았습니다) 아키텍처에서 MMU는 어떤 페이지가 더티인지 추적합니다. 따라서 커널은 페이지가 초기화될 때 내용이 0이 아니더라도 페이지 테이블 항목의 더티 비트를 지울 수 있으며, MMU는 페이지가 수정될 때 이를 업데이트합니다.
익명 메모리는 파일 백업이 없는 메모리입니다. 페이지를 작성하면 파일이 지원되지 않는 메모리의 양이 늘어납니다. 초기화 시에는 실행 가능한 이미지로 지원되지만 일단 변경되면 더 이상 지원되지 않습니다.
커널이 더티 페이지를 확인하는 위치를 보려면 다음을 참조하세요.참고로pte_dirty
.
커널은 또한약간 "부드럽고 더러운", 사용자 공간에서 지워지고 체크포인트 복구에 사용될 수 있습니다.