임베디드 스터디 - 리눅스 커널 소스 트리
임베디드 스터디 - 리눅스 커널 소스 트리
커널 소스 트리 개요
- 리눅스 커널은 단일 파일이 아닌, 목적에 따라 나뉜 디렉토리 구조로 관리됨
- 아키텍처 의존 코드와 공통 코드를 분리하여 다양한 플랫폼을 지원함
- 디바이스 드라이버, 메모리 관리, 파일시스템 등 독립적인 서브시스템으로 구성
- 커널 소스는 Elixir Cross Referencer에서 브라우저로 탐색 가능
1
2
3
4
5
6
7
8
9
10
11
linux/
├── arch/ ← CPU 아키텍처별 코드
├── drivers/ ← 디바이스 드라이버
├── fs/ ← 파일시스템
├── mm/ ← 메모리 관리
├── kernel/ ← OS 핵심 기능
├── net/ ← 네트워크 스택
├── include/ ← 공통 헤더 파일
├── init/ ← 커널 초기화 진입점 (start_kernel)
├── lib/ ← 커널 내부 유틸리티 함수
└── ...
디렉토리별 역할
arch/ — CPU 아키텍처별 코드
- 특정 CPU 아키텍처에 종속된 코드를 모두 이 디렉토리 하위에 분리하여 관리
- CPU 레지스터 배치, 예외 벡터 처리, 부팅 진입점 등이 아키텍처마다 다름
- 커널 공통 코드는
arch/를 직접 참조하지 않고 추상화된 API를 통해 호출함
1
2
3
4
5
6
7
8
arch/
├── arm/ ← ARMv7 (Cortex-A, Cortex-R)
│ ├── boot/ ← 부팅 진입점, zImage 압축 해제
│ ├── kernel/ ← 컨텍스트 스위칭, 예외 처리
│ └── mm/ ← ARM용 MMU/TLB 제어
├── arm64/ ← ARMv8 (AArch64)
├── x86/ ← x86/x86_64
└── mips/ ← MIPS
- 임베디드 분야에서
arch/arm/과arch/arm64/가 가장 자주 다루게 되는 디렉토리
drivers/ — 디바이스 드라이버
- 하드웨어 주변장치를 제어하는 드라이버를 장치 종류별로 분류하여 관리
- 아키텍처와 무관한 공통 드라이버 로직이 위치함
- 아키텍처 종속적인 부분은
arch/로 분리됨
1
2
3
4
5
6
7
8
9
10
drivers/
├── tty/
│ └── serial/ ← UART 드라이버 (8250, pl011 등)
├── i2c/ ← I2C 버스 드라이버
├── spi/ ← SPI 버스 드라이버
├── net/ ← 이더넷, Wi-Fi NIC 드라이버
├── gpio/ ← GPIO 드라이버
├── dma/ ← DMA 엔진 드라이버
├── mtd/ ← 플래시(NAND/NOR) MTD 드라이버
└── usb/ ← USB 호스트/디바이스 드라이버
fs/ — 파일시스템
- 다양한 파일시스템 구현체와 VFS(Virtual File System) 추상화 레이어를 포함
- VFS : 파일시스템의 종류에 관계없이 동일한 시스템 콜(
open,read,write)을 사용할 수 있게 하는 추상화 레이어
- VFS : 파일시스템의 종류에 관계없이 동일한 시스템 콜(
1
2
3
4
5
6
7
fs/
├── ext4/ ← 리눅스 기본 파일시스템
├── fat/ ← FAT12/FAT16/FAT32 (이동식 저장장치)
├── jffs2/ ← NAND 플래시용 저널링 파일시스템
├── ubifs/ ← UBI 기반 NAND 파일시스템
├── nfs/ ← 네트워크 파일시스템
└── proc/ ← /proc 가상 파일시스템
mm/ — 메모리 관리 (Memory Management)
- OS 레벨에서 물리 메모리·가상 메모리를 관리하는 서브시스템
- 페이지 테이블, TLB, 페이지 폴트 처리의 소프트웨어 구현이 여기에 위치함
1
2
3
4
5
6
mm/
├── page_alloc.c ← 버디 시스템 기반 물리 페이지 할당
├── slub.c ← 슬랩(Slab) 할당자 — kmalloc 구현
├── mmap.c ← 가상 주소 공간 매핑 (mmap 시스템 콜)
├── memory.c ← 페이지 폴트 핸들러
└── vmalloc.c ← 가상 연속 메모리 할당
| 기능 | 위치 | 설명 |
|---|---|---|
| 물리 페이지 할당 | mm/page_alloc.c | 버디 시스템으로 물리 프레임 관리 |
| 소형 객체 할당 | mm/slub.c | kmalloc의 내부 구현 |
| 페이지 폴트 처리 | mm/memory.c | 가상→물리 주소 매핑 처리 |
| ARM TLB 제어 | arch/arm/mm/ | 아키텍처 종속 MMU 조작 |
kernel/ — OS 핵심 기능
- 스케줄러, 프로세스 관리, 시그널, 타이머 등 운영체제의 핵심 메커니즘을 포함
1
2
3
4
5
6
7
8
kernel/
├── sched/ ← CFS 스케줄러, 실시간 스케줄러
├── fork.c ← 프로세스 생성 (fork/clone 시스템 콜)
├── exit.c ← 프로세스 종료
├── signal.c ← 시그널 처리 (SIGKILL, SIGTERM 등)
├── time/ ← 커널 타이머, hrtimer
├── irq/ ← 인터럽트 처리 프레임워크
└── power/ ← PM Core (System Sleep / Runtime PM)
net/ — 네트워크 스택
- TCP/IP 프로토콜 스택과 소켓 인터페이스 구현을 포함
- 소켓 API(
socket,bind,connect,send,recv)의 커널 쪽 구현이 여기에 위치
- 소켓 API(
1
2
3
4
5
net/
├── socket.c ← 소켓 시스템 콜 인터페이스
├── ipv4/ ← IPv4, TCP, UDP 구현
├── ipv6/ ← IPv6 구현
└── core/ ← 네트워크 디바이스 프레임워크 (netdev)
include/ — 공통 헤더 파일
- 커널 내부 여러 서브시스템이 공통으로 참조하는 헤더 파일의 저장소
- 드라이버에서
#include <linux/kernel.h>로 참조하는 파일들이 여기에 위치
- 드라이버에서
1
2
3
4
5
6
7
8
include/
├── linux/ ← 커널 내부 공통 헤더
│ ├── kernel.h ← printk, ARRAY_SIZE 등 기본 매크로
│ ├── module.h ← 커널 모듈 등록 매크로
│ ├── serial.h ← UART 드라이버 공통 구조체
│ └── pm.h ← dev_pm_ops 구조체 정의
├── uapi/linux/ ← 유저스페이스 공개 헤더 (시스템 콜 인터페이스)
└── asm-generic/ ← 아키텍처 공통 어셈블리 헤더
arch/와 drivers/의 분리 원칙
- 동일한 UART 드라이버라도 아키텍처에 따라 달라지는 부분이 존재함
- 공통 로직 (데이터 송수신, 버퍼 관리) →
drivers/tty/serial/ - 아키텍처 종속 (DMA 처리 방식, 인터럽트 라우팅) →
arch/arm/
- 공통 로직 (데이터 송수신, 버퍼 관리) →
1
2
3
4
5
UART 드라이버 예시
drivers/tty/serial/pl011.c ← 공통 UART 송수신 로직
arch/arm/mach-xxx/dma.c ← ARM 전용 DMA 채널 설정
include/linux/amba/serial.h ← 공통 구조체 정의
- 이 분리 원칙 덕분에 ARM → ARM64 포팅 시
drivers/코드는 그대로 재사용하고arch/만 교체하면 됨
핵심 정리
| 디렉토리 | 역할 | 대표 파일/서브디렉토리 |
|---|---|---|
arch/ | CPU 아키텍처별 종속 코드 | arm/, arm64/, x86/ |
drivers/ | 디바이스 드라이버 | tty/serial/, i2c/, mtd/ |
fs/ | 파일시스템 구현 + VFS | ext4/, ubifs/, nfs/ |
mm/ | 메모리 관리 | page_alloc.c, slub.c |
kernel/ | OS 핵심 기능 | sched/, signal.c, power/ |
net/ | 네트워크 스택 | ipv4/, socket.c |
include/ | 공통 헤더 | linux/kernel.h, linux/module.h |
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.