1. 실행 파일 로딩이란?
- 정의: 디스크에 저장된 실행 파일을 메모리에 복사하고, 그 프로그램의 첫 명령어로 점프(jump)하여 실행하는 과정.
- 시작 방식: 리눅스 쉘에서 ./prog처럼 실행하면 loader가 호출되어 시작됨.
2. 누가 실행하는가?
- loader (로더): 운영체제 안에 항상 상주하는 커널 코드.
- 프로그램을 실행할 때 execve() 시스템 호출을 통해 로더가 프로그램을 메모리에 올림.
3. 로더의 역할
- ELF 실행 파일을 열고, 내부의 program header table을 분석.
- .text, .data, .rodata, .bss 등 각 섹션을 지정된 런타임 주소에 복사.
- .bss는 0으로 초기화.
- entry point(첫 명령어 위치)로 점프하여 실행 시작.
런타임 메모리 구조 (Figure 7.15 참고)

- x86-64 리눅스 메모리 배치도:
0xFFFFFFFF_FFFFFFFF ← 커널 공간
|
사용자 스택 (아래로 성장)
|
공유 라이브러리 영역
|
힙 (malloc이 쓰는 공간, 위로 성장)
|
.data 섹션
|
.text 섹션 (실행 코드, 0x400000부터 시작)
0x00000000_00000000
- 주소 예시:
- .text 시작 주소: 0x400000
- .data: .text 뒤쪽에 위치
- .bss: .data 끝에 있고 0으로 초기화됨
- 힙: .bss 위에 위치하고 malloc()으로 동적 증가
- 스택: 높은 주소에서 시작해 아래로 감소
ELF 실행 파일이 로딩되는 이유
- 실행 파일은 이미 링커에 의해 모든 심볼과 주소가 결정된 상태.
- 따라서 로더는 단순히 “정해진 주소에 옮기기만 하면 된다.”
- 이로 인해 실행 속도가 빠르고, 추가적인 링크 단계가 필요 없음.
메모리 정렬 (Alignment)
- 데이터나 코드 섹션을 올릴 때는 align 조건을 만족해야 함.
- 예: .data가 0x200000 (2MB) 정렬을 요구한다면, 시작 주소가 그 배수여야 함.
- 이는 페이지 단위 전송 최적화를 위해 필요하며, 가상 메모리와 관련 있음.
핵심 정리
| 용어 | 설명 |
|---|---|
| Loader | execve() 호출 시 실행 파일을 메모리에 올리고 첫 명령어로 jump하는 커널 코드 |
| execve() | 실행 파일을 로딩하는 시스템 콜 |
| Program Header Table | ELF 파일의 로딩 정보를 담은 테이블. 어떤 섹션을 어디에 옮길지 명시 |
| Entry Point | 프로그램 실행이 시작되는 주소 |
| .bss | 초기값 없는 전역/정적 변수의 공간. 런타임에 0으로 초기화됨 |
| Alignment | 특정 메모리 주소 배치 조건 (예: 2MB 정렬) |
요약
OS는 실행 파일(예: ELF)을 메모리에 로딩하고, 프로그램을 실행할 준비를 한다. 이 과정에서 주소 공간을 설정함.
실행할 때 시스템 콜 execve()가 호출됨:
execve("./main", argv, envp);
- ELF 포맷을 파싱 (ELF header + program header table)
- .text, .data, .rodata, .bss 등 섹션을 메모리에 매핑
- stack과 heap 영역 생성
- entry point 주소로 점프 → main() 실행됨
추가 정보
- OS는 가상 메모리(Virtual Memory)를 사용하여 각 프로세스에 독립적인 주소 공간 제공
- 주소 무작위화(ASLR)는 .text, .heap, .stack 위치를 실행할 때마다 바꿔 보안 강화
728x90
'CS:APP' 카테고리의 다른 글
| 시그널 (0) | 2025.08.10 |
|---|---|
| 예외상황 (0) | 2025.08.10 |
| ELF, Executable and Linkable Format (재배치 가능 목적파일) (0) | 2025.08.08 |
| 컴파일러 드라이버 (0) | 2025.08.04 |
| 함수는 추상화의 결과다 - CS:APP 3.7 프로시저 호출 (0) | 2025.04.08 |