(Linux) Memory Layout, Segment + Kernel
2017/01/04 - [System/LINUX & UNIX] - procfs
- stack의 최대 크기는
RLIMIT_STACK ( usually 8MB, 0x08000000 )
이다.- 한 번 확장된 stack top은 다시 줄어들지 않는다.
- Text segment의 시작지점은 보통
0x08048000
이지만, 항상 그런 것은 아니다. - dynamic library는 stack과 heap의 중간 Memory Mapping Region에 mapping되고, static library는 text segment에 mapping된다.
- Memory Mapping Region의 경우 library mapping 이외의 용도로도 사용되는데, anonymous memory mapping 이라고 부르며,
malloc()
으로 요청하는 size가MMAP_THRESHOLD
이상일 경우 heap을 사용하는 대신mmap()
을 이용해 anonymous mapping한다.
Data segment, rodata segment, BSS segment
stack, heap, data, text segment 이외에 BSS segment가 존재한다. Data segment가 heap+BSS+data를 의미하는 경우가 종종있긴 하지만, 분명 다른 segment다.
Data segment는 object file의 .data 부분이며, 다음 항목을 담고있다.
- initialized static variable
- initialized global variable
rodata segment ( read-only )는 object file의 .rodata 부분이며, 다음 항목을 담고있다.
- initialized constant
BSS segment는 object file의 .bss 부분이며, 다음 항목을 담고있다.
- uninitialized static variable
- uninitialized global variable
- uninitialized constants
* variable은 0으로 초기화하면 초기화 안한 것으로 보고 BSS로 들어간다. * constant는 0으로 초기화하면 초기화 한 것으로 보고 rodata로 간다.
- 구식 OS의 경우, 또는
RLIMIT_STACK
이 정의되어 있지 않은 경우에는 classic layout으로 돌아가게 되는데, Memory Mapping Region이 stack 방향으로 자라며 0x40000000 부터 자란다.
Kernel
Process가 page를 필요로 하면, Physical frame을 할당하고 page table에 등록하면서 page와 mapping한다. page table은 process마다 존재하며, 이 역시 context switch 하면서 switch된다. 그러나 kernel space는 user space처럼 각 process마다 다른 physical memory와 mapping되는 것이 아니다.
kernel page table entries는 모든 process’s page table로 복제되기 때문에 어떤 process에서든 같은 virtual addr로 접근하게 되며 이는 같은 physical frame으로 사상된다.
반면 user space는 process switch가 발생할 때 마다 같은 virtual address라도 다른 physical memory를 가리키게 된다.
1
2
3
4
PAGE_OFFSET ~ high_memory-1 // Kernel direct-mapped RAM region.
TASK_SIZE ~ PAGE_OFFSET-1 // Kernel module space
0x00001000 ~ TASK_SIZE-1 // User space
0x00000000 ~ 0x00000fff // CPU vector page / null pointer trap.
kernel mode에서든 user mode에서든 NULL deref가 발생하는건 null pointer trap 덕분. x86에서는 TASK_SIZE == PAGE_OFFSET
다.
Kernel Symbols
1
2
3
4
5
6
7
8
9
PHYS_OFFSET : physical base
/* Physical start address of the first bank of RAM */
PAGE_OFFSET : virtual base
/* Virtual start address of the first bank of RAM. During the kernel boot phase,
virtual address PAGE_OFFSET will be mapped to physical address PHYS_OFFSET. */
TASK_SIZE : virtual base
/* The maximum size of a user process in bytes */