11. 특수 노드와 고급 패턴
Device Tree(DT)가 단순히 "하드웨어 목록"을 넘어 복합적인 시스템 제어를 수행할 수 있는 이유는 특수 노드와 고급 데이터 패턴 덕분입니다. 시스템 부팅의 결정적인 설정부터 핀 하나하나의 전기적 특성까지 조율하는 이 요소들을 핵심 위주로 정리해 드릴게요.
11.1 디바이스 트리: 노드 구조
디바이스 트리는 하드웨어 정보를 트리 구조로 설명하며 각 디바이스를 노드(Node)로 표현한다. 각 노드는 부모-자식 관계를 기반으로 조직되고, 트리의 최상단에는 루트 노드(Root Node)가 존재한다.
루트 노드
- 트리 구조의 시작점이며 / 로 식별된다. (다른 노드와 달리 이름이 없다.)
- 모든 디바이스 노드는 루트 노드를 기준으로 참조된다.
- 루트 노드는 시스템에 하나만 존재하며, 디바이스 트리 최상단에 위치한다.
- 루트 노드는 반드시 하나의 /cpus 노드와 최소 하나 이상의 /memory 노드를 포함해야 한다.
노드
- 각 노드는 하드웨어 디바이스를 나타낸다.
- 노드는 속성(Property)을 통데 데이터를 정의한다.
- Property는 Key-Value 쌍으로 정의되며 문자열, 정수, boolean 등 다양한 데이터 유형을 지원한다.
- Property는 Device Tree specification에 따라 작성해야 하며, 표준 속성과 사용자 정의 속성으로 구분된다.
- 노드는 부모-자식 관계를 형성한다. 예를 들어 I2C 컨트롤러는 부모 노드이고 여기에 I2C 버스를 통해 연결된 디바이스들은 자식노드가 된다.

11.2 시스템 제어를 위한 특수 노드 (Standard Special Nodes)
이 노드들은 특정 하드웨어 장치를 나타내지 않고, OS와 커널의 동작 방식을 결정하는 메타데이터를 담고 있습니다.
/chosen 노드
부트로더(U-Boot 등)가 커널에게 보내는 "쪽지" 같은 노드입니다. 하드웨어 소스 코드(.dts)에는 보통 비어있거나 기본값만 있고, 부트로더가 실행 중에 내용을 채워 넣습니다.
| 프로퍼티 | 설명 |
| bootargs | 커널 부팅 파라미터 (예: console=ttyS0,115200 root=/dev/mmcblk0p2) |
| stdout-path | 시스템 로그가 출력될 기본 시리얼 포트 경로 |
| kaslr-seed | 커널 주소 공간 무작위화(KASLR)를 위한 랜덤 시드 값 |
/aliases 노드
긴 경로명을 가진 노드에 "별명"을 붙여줍니다. 예를 들어 /soc/serial@1c28000 대신 serial0이라는 짧은 이름으로 접근하게 하여, 드라이버가 인덱스 번호(UART0, UART1 등)를 쉽게 지정하게 돕습니다.
/reserved-memory 노드
리눅스 커널이 일반적인 용도로 사용하지 못하도록 물리 메모리의 특정 구역을 보호합니다.
- CMA (Contiguous Memory Allocator): 카메라나 멀티미디어 장치용 연속 메모리 확보.
- Framebuffer: 디스플레이 출력을 위한 전용 메모리 영역.
11.3 고급 설계 패턴 (Advanced Patterns)
단순한 속성 정의를 넘어, 노드 간의 복잡한 관계를 정의하는 패턴들입니다.
Phandle (Pointer Handle)
노드와 노드를 연결하는 "포인터"입니다.
- 패턴: 어떤 노드가 다른 노드(예: 클럭 컨트롤러, GPIO 컨트롤러)의 기능을 빌려 쓸 때 사용합니다.
- 예시: clocks = <&ccu CLK_UART0>; 여기서 &ccu가 바로 phandle입니다.
Pinctrl (Pin Control) & Pinmux
하나의 물리적 핀을 UART로 쓸지, GPIO로 쓸지, I2C로 쓸지 결정하는 매우 중요한 패턴입니다.
- Pattern: 장치 노드 안에 pinctrl-0 = <&uart0_pins>;와 같이 설정하여, 해당 장치가 활성화될 때 핀 설정도 자동으로 바뀌게 합니다.
DT Overlays (.dtbo)
이미 컴파일된 DTB를 수정하지 않고, 실행 중에 새로운 하드웨어를 추가하는 패턴입니다.
- 활용: 라즈베리 파이의 HAT이나 비글본의 캡(Capes)처럼, 사용자가 나중에 꽂는 확장 보드의 정보를 기존 시스템에 "합체"시킬 때 사용합니다.
11.4 계층적 관계 (Hierarchy) 패턴
DT는 트리 구조이므로, 자원(Resource)의 흐름도 트리 형태로 관리됩니다.
- Interrupt Tree: 하위 장치의 인터럽트가 상위 인터럽트 컨트롤러(GIC 등)로 어떻게 타고 올라가는지 정의합니다. (interrupt-parent 속성 활용)
- Clock Tree: 크리스탈 오실레이터에서 시작된 원천 클럭이 분주기(Divider)와 배율기(PLL)를 거쳐 각 장치로 퍼져나가는 계층을 표현합니다.
💡정리하자면...
특수 노드는 커널과의 대화 통로이고, 고급 패턴은 하드웨어 간의 유기적인 연결 고리입니다. 특히 pinctrl이나 phandle은 드라이버 개발 시 가장 많이 접하게 되는 실무적인 부분입니다.
11.5 실전 특수 노드와 고급 패턴
위 코드는 Device Tree(DT)의 "고급 설정 기술"들을 총망라하고 있습니다. 일반적인 장치 등록을 넘어 시스템의 메모리 관리, 전력 최적화, 그리고 부팅 초기 상태를 결정하는 핵심적인 노드들입니다.
각 섹션이 가진 실무적 의미를 쉽게 풀어서 설명해 드릴게요.
1. reserved-memory: 커널로부터 메모리 보호하기
커널이 마음대로 사용하지 못하도록 물리 메모리(RAM)의 특정 구역을 미리 찜해두는 설정입니다.
- linux,cma (Contiguous Memory Allocator): 카메라 영상 처리나 GPU처럼 거대한 연속 메모리가 필요한 장치를 위한 전용 주차장입니다. reusable이 붙으면 평소에는 커널이 쓰다가, 장치가 달라고 하면 즉시 비워줍니다.
- no-map: 이 설정이 핵심입니다. 커널이 이 영역에 대해 가상 주소 매핑 자체를 하지 않도록 하여, CPU의 예측 실행(Speculative execution)으로 인한 데이터 오염 등을 원천 차단합니다. 주로 보안 펌웨어나 하드웨어 전용 버퍼로 씁니다.
2. GPIO hog: "부팅되자마자 켜져 있어!"
원래 GPIO는 드라이버가 올라간 뒤에야 제어할 수 있습니다. 하지만 gpio-hog는 GPIO 컨트롤러 드라이버가 로드되는 즉시 해당 핀을 특정 상태로 고정합니다.
- 용도: 시스템 상태 LED, 외부 장치 전원 인에이블(Enable) 핀 등 드라이버 로드까지 기다릴 수 없는 최우선 순위 설정에 사용합니다.
- 특징: 별도의 소비 드라이버(Consumer) 없이 GPIO 컨트롤러가 스스로 "독점(Hog)"합니다.
3. Fixed Clock/Regulator: 하드웨어 추상화
시스템에는 제어할 수 없는 "고정된 것들"이 있습니다. 이를 DT 노드로 만들어 다른 장치들이 참조하게 합니다.
- fixed-clock: 외부 크리스탈 오실레이터처럼 전원만 넣으면 항상 $24\text{ MHz}$를 뿜어내는 클럭 소스를 정의합니다.
- regulator-fixed: 전원 라인을 노드로 만듭니다. regulator-always-on 덕분에 커널은 이 전원을 끌 시도조차 하지 않으며, 다른 장치(예: Wi-Fi 모듈)가 "나 전원 필요해"라고 할 때 이 노드를 가리키게(®_3v3) 됩니다.
4. OPP (Operating Performance Points): CPU 성능표
CPU가 낼 수 있는 "속도와 전압의 짝꿍" 리스트입니다.
- DVFS (Dynamic Voltage and Frequency Scaling): CPU 부하가 적으면 $600\text{ MHz} / 0.9\text{ V}$로 낮춰 전기를 아끼고, 부하가 높으면 $1.8\text{ GHz} / 1.3\text{ V}$로 올려 성능을 냅니다.
- opp-suspend: 시스템이 절전 모드(Suspend)에 들어갈 때 사용할 최적의 지점을 지정합니다.
5. interrupt-map: 복잡한 인터럽트 배선도
주로 PCI/PCIe 버스에서 사용되는 "인터럽트 번역기"입니다.
- 상황: PCIe 슬롯에는 수많은 장치가 꽂힐 수 있는데, 각 장치의 인터럽트(INTA, INTB...)를 메인 인터럽트 컨트롤러(GIC)의 몇 번 핀에 연결할지 매핑합니다.
- interrupt-map-mask: 주소와 인터럽트 번호 중 어떤 비트를 보고 매핑할지 결정하는 필터 역할을 합니다.
💡 요약하자면
이 코드는 시스템의 뼈대와 규칙을 정의합니다.
- 메모리 어디를 비워둘지 (reserved-memory)
- 핀 초기 상태는 무엇인지 (gpio-hog)
- 에너지 소스는 무엇인지 (fixed-clock/regulator)
- 달리기 규칙은 무엇인지 (OPP)
- 신호 전달은 어떻게 할지 (interrupt-map)
이 코드들은 모두 커널이 부팅될 때 "준비 단계"에서 처리되어 시스템의 안정성을 보장합니다.

참고: https://www.minzkn.com/linuxkernel/pages/device-tree.html#dt-compile
'Embedded : : Linux > : : Device Tree' 카테고리의 다른 글
| [Device Tree] 13. FDT 바이너리 포맷 (Flattened Device Tree) (1) | 2026.03.04 |
|---|---|
| [Device Tree] 12. Device Tree 디버깅 (0) | 2026.03.04 |
| [Device Tree] 10. Device Tree + Platform Driver 통합 (0) | 2026.03.04 |
| [Device Tree] 9. 커널 OF(Open Firmware) API (0) | 2026.03.04 |
| [Device Tree] 8. DTS 컴파일과 디컴파일 (0) | 2026.03.04 |