10. Device Tree + Platform Driver 통합
10.1 DT + Flatform Driver 통합의 흐름
Device Tree(DT)와 Platform Driver의 통합은 현대 리눅스 커널 하드웨어 관리의 핵심입니다. 하드웨어의 '명세(Data)'와 이를 제어하는 '로직(Code)'을 완전히 분리하여, 커널을 다시 빌드하지 않고도 다양한 보드에 대응할 수 있게 설계되었습니다.
전체적인 흐름을 [인식 - 매칭 - 자원 획득]의 3단계로 나누어 설명해 드릴게요.
1. 인식: DT 노드가 Platform Device가 되는 과정
커널이 부팅될 때, of_platform_populate() 함수가 호출되면서 디바이스 트리의 노드들을 훑습니다.
- 대상: compatible 속성을 가진 노드들(주로 soc 아래의 자식 노드들)이 대상입니다.
- 결과: 각 노드는 커널 내부에서 struct platform_device라는 객체로 변환됩니다.
- 정보 저장: 이때 노드에 적힌 reg, interrupts 정보는 struct resource 형태로 변환되어 해당 장치 객체 안에 저장됩니다.
2. 매칭: "너 내 동료가 돼라" (compatible 체크)
커널에 로드된 드라이버와 생성된 장치 객체를 연결하는 과정입니다.
- 드라이버 측: struct platform_driver 구조체 내부의 of_match_table에 지원 가능한 compatible 문자열 리스트를 적어둡니다.
- 장치(DT) 측: 노드에 적힌 compatible 문자열을 확인합니다.
- 매칭 성공: 두 문자열이 완벽히 일치하면, 커널은 드라이버의 probe() 함수를 호출하며 장치 객체의 포인터를 인자로 넘겨줍니다.
3. 통합의 정수: probe() 함수에서의 상호작용
드라이버의 probe() 함수 안에서는 앞서 살펴본 OF_API를 사용하여 DT의 데이터를 실제 제어 코드로 가져옵니다.
| 단계 | 수행 작업 | 핵심 함수 (API) |
| 자원 매핑 | DT의 reg 주소를 커널 가상 주소로 변환 | devm_platform_ioremap_resource() |
| 인터럽트 | DT의 interrupts 번호를 가져옴 | platform_get_irq() |
| 커스텀 설정 | 제조사 고유 프로퍼티(fifo-depth 등) 추출 | of_property_read_u32() |
| 클럭/리셋 | 연결된 클럭 및 리셋 라인 제어 | devm_clk_get(), devm_reset_control_get() |
4. 통합 구조의 장점
- Binary Reusability: 동일한 드라이버 바이너리를 수정 없이 여러 SoC에 사용할 수 있습니다. (버전별 차이는 DT 매칭 데이터(.data)로 해결)
- Clean Code: 하드웨어의 물리적 주소가 코드에 하드코딩되지 않아 코드가 깔끔해집니다.
- Dynamic Support: 앞서 설명한 DT Overlay와 결합하면, 실행 중인 시스템에 드라이버와 장치를 동적으로 붙였다 뗄 수 있습니다.
요약 코드 흐름
// 1. 드라이버는 "이 문자열을 가진 장치를 찾습니다"라고 선언
static const struct of_device_id my_match[] = {
{ .compatible = "my,awesome-sensor" },
{ }
};
// 2. 매칭되면 실행되는 함수
static int my_probe(struct platform_device *pdev) {
// 3. DT(pdev->dev.of_node)에서 정보를 꺼내 하드웨어 초기화
struct device_node *np = pdev->dev.of_node;
...
}
결론적으로, Device Tree는 하드웨어의 "설계도"이고, Platform Driver는 그 설계도를 보고 작업을 수행하는 "기술자"입니다. 커널은 이 둘 사이에서 compatible이라는 "계약서"를 확인하여 중매해 주는 역할을 합니다.
10.2 완전한 DT 기반 Platform Driver 예제
아래의 코드는 현대적인 리눅스 커널 플랫폼 드라이버의 정석을 보여주는 아주 깔끔한 예제입니다. 이 드라이버는 "하드웨어 설명서(Device Tree)"를 읽어서 실제 장치를 구동하는 "기술자" 역할을 합니다.
fwnode API (v4.13+): Device Tree와 ACPI 양쪽을 지원하는 드라이버는 of_* 대신 device_property_read_*(fwnode) API를 사용하면 DT/ACPI 코드를 통일할 수 있습니다. 예: device_property_read_u32(dev, "fifo-depth", &val)
각 파트가 어떤 의미를 갖는지, 실무적인 관점에서 핵심만 짚어드릴게요.
💡 한 줄 요약 (이 코드는 "Device Tree에서 하드웨어 정보를 뽑아내어(OF API), 커널의 자원 관리 시스템(devm)을 이용해 안전하고 효율적으로 장치를 초기화하는 모던 드라이버"의 전형입니다.)
1. 버전 관리의 묘미: of_device_id와 Match Data
가장 눈에 띄는 부분은 hw_v1, hw_v2 같은 구조체와 my_of_ids 테이블입니다.
- 왜 이렇게 하나요? 똑같은 기능을 하는 UART라도 SoC 버전에 따라 FIFO 크기가 다를 수 있습니다. 코드 로직은 똑같은데 숫자 몇 개 때문에 드라이버를 새로 만드는 건 낭비죠.
- 어떻게 작동하나요? DT에 적힌 compatible 문자열에 따라 커널이 자동으로 그에 맞는 hw_vX 데이터를 probe함수에 전달해줍니다. 드라이버는 of_device_get_match_data() 한 줄로 "아, 나는 지금 64바이트 FIFO를 가진 v2 장치를 다루고 있구나"라고 바로 알게 됩니다.
2. my_probe(): 하드웨어를 깨우는 6단계 과정
장치가 발견되면 실행되는 probe 함수는 일종의 체크리스트입니다.
- 메모리 할당: devm_kzalloc으로 드라이버가 쓸 메모리를 잡습니다.
- 데이터 매칭: 위에서 말한 버전별 사양 정보를 가져옵니다.
- I/O 매핑: DT의 reg 주소를 가져와 커널이 접근할 수 있는 가상 주소(base)로 바꿉니다. 이제 base + offset으로 레지스터를 읽고 쓸 수 있습니다.
- 인터럽트: 장치가 CPU에 신호를 보낼 통로(IRQ 번호)를 확보합니다.
- 에너지 공급 (Clock & Reset): 하드웨어에 전기를 넣어주고(Clock), 굳어있는 칩을 풀어줍니다(Reset).
- 세부 설정: DT에 적힌 fifo-threshold 같은 추가 옵션을 읽습니다.
3. devm_ (Managed API)의 마법
코드 곳곳에 보이는 devm_ 접두사가 이 코드의 핵심입니다.
- 자동 청소: 예전에는 드라이버가 종료될 때(remove) 할당한 메모리를 풀고, 매핑을 풀고, 클럭을 끄는 코드를 일일이 다 짜야 했습니다. 하나라도 까먹으면 메모리 누수가 발생했죠.
- 편의성: devm_을 쓰면 드라이버가 언로드될 때 커널이 역순으로 모든 자원을 알아서 해제해줍니다. 그래서 my_remove() 함수가 저렇게 짧아질 수 있는 겁니다.
4. 매칭 우선순위 (The Matching Hierarchy)
주석에 달린 우선순위는 시스템이 하드웨어를 찾는 "고집"의 순서입니다.
| 순위 | 방식 | 특징 |
| 1 | Device Tree | 임베디드 리눅스의 표준. compatible 문자열 비교. |
| 2 | ACPI | 주로 x86(PC/서버) 환경에서 사용. |
| 3 | ID Table | 레거시 방식. 특정 이름 목록을 가지고 비교. |
| 4 | Driver Name | 최후의 보루. 드라이버 이름과 장치 이름이 같으면 매칭. |

참고: https://www.minzkn.com/linuxkernel/pages/device-tree.html#dt-compile
'Embedded : : Linux > : : Device Tree' 카테고리의 다른 글
| [Device Tree] 12. Device Tree 디버깅 (0) | 2026.03.04 |
|---|---|
| [Device Tree] 11. 특수 노드와 고급 패턴 (0) | 2026.03.04 |
| [Device Tree] 9. 커널 OF(Open Firmware) API (0) | 2026.03.04 |
| [Device Tree] 8. DTS 컴파일과 디컴파일 (0) | 2026.03.04 |
| [Device Tree] 7. Device Tree Bindings (0) | 2026.03.04 |