9. 커널 OF(Open Firmware) API
9.1 커널 OF_API란?
커널 OF_API (Open Firmware API)는 리눅스 커널 드라이버가 메모리에 로드된 디바이스 트리(Live DT) 데이터에 접근하여 원하는 정보를 추출할 때 사용하는 함수 집합입니다.
디바이스 트리가 "데이터베이스"라면, OF_API는 그 데이터베이스에 쿼리를 날리는 "SQL"과 같은 역할을 합니다.
주로 include/linux/of.h에 정의되어 있습니다.
1. 주요 역할: 데이터 추출의 도구
드라이버는 부팅 시 전달받은 device_node 구조체 포인터를 가지고 다음과 같은 작업을 수행합니다.
- 노드 찾기: 경로, 이름, 또는 compatible 문자열로 특정 노드를 검색합니다.
- 프로퍼티 읽기: 정수(u32), 문자열, 불리언(boolean) 등 노드 내의 값을 가져옵니다.
- 리소스 해석: 주소(reg), 인터럽트, 클럭, GPIO 등 복잡한 하드웨어 자원을 커널 객체로 변환합니다.
2. 자주 사용되는 주요 함수 (Cheat Sheet)
| 분 류 | 함 수 명 | 설 명 |
| 노드 검색 | of_find_node_by_path() | /soc/serial@1c28000 같은 전체 경로로 노드를 찾음 |
| of_find_compatible_node() | compatible 문자열이 일치하는 노드를 찾음 | |
| 단일 값 읽기 | of_property_read_u32() | 32비트 정수 값을 읽음 |
| of_property_read_string() | 문자열 값을 읽음 | |
| of_property_read_bool() | 해당 속성이 존재하는지 여부 확인 (True/False) | |
| 배열/리스트 | of_property_read_u32_array() | 여러 개의 정수 값(배열)을 한꺼번에 읽음 |
| of_property_count_elems_of_size() | 특정 속성에 몇 개의 데이터가 들어있는지 확인 | |
| 리소스 연결 | of_parse_phandle() | 다른 노드를 가리키는 phandle을 따라가 해당 노드 포인터를 반환 |
3. 코드 예시: 드라이버에서의 실제 활용
드라이버의 probe 함수에서 OF_API를 사용하는 전형적인 패턴입니다.
#include <linux/of.h>
static int my_driver_probe(struct platform_device *pdev) {
struct device_node *np = pdev->dev.of_node; // 현재 장치의 DT 노드
u32 temp_limit;
const char *mode;
// 1. "temperature-limit" 이라는 u32 값 읽기
if (of_property_read_u32(np, "temperature-limit", &temp_limit)) {
temp_limit = 80; // 기본값 설정 (에러 시)
}
// 2. "operating-mode" 라는 문자열 읽기
of_property_read_string(np, "operating-mode", &mode);
// 3. "internal-pullup" 이라는 속성이 있는지 확인 (Boolean)
if (of_property_read_bool(np, "internal-pullup")) {
// 풀업 설정 로직 실행
}
return 0;
}
4. 핵심 구조체: struct device_node
OF_API가 대상으로 삼는 핵심 데이터 구조입니다. 커널 내부에서 디바이스 트리의 각 노드는 이 구조체로 관리됩니다.
주의사항: > of_find_... 계열 함수를 사용하여 노드를 직접 찾은 경우, 참조 카운트(Reference Count)가 증가합니다. 작업이 끝난 후에는 반드시 of_node_put(np)를 호출하여 메모리 누수를 방지해야 합니다. (단, pdev->dev.of_node 처럼 자동으로 전달받은 노드는 직접 해제할 필요가 없습니다.)
정리하자면...
OF_API는 하드웨어 배치도(DTS)에 적힌 텍스트 정보를 드라이버가 이해할 수 있는 C언어 변수와 객체로 바꾸어주는 통역사입니다.
9.2 커널 OF API 참조가이드 코드
리눅스 커널 드라이버 개발을 위한 "OF(Open Firmware) API 치트 시트(Cheat Sheet)" 또는 참조용 가이드 코드로 보입니다.
정확히는 include/linux/of.h와 그 하위 헤더 파일들에 정의된 함수들을 실무에서 어떻게 사용하는지 핵심만 모아놓은 요약본입니다.
이 코드가 보여주는 핵심 맥락 3가지
1. 프로퍼티 추출 (Property Extraction)
DTS에 적힌 텍스트 데이터를 C언어 변수로 옮기는 과정입니다.
- of_property_read_u32, of_property_read_string 등은 드라이버의 probe 함수에서 가장 먼저 실행되는 코드들입니다.
- 하드웨어의 설정값(예: 전압 제한, 모드 설정 등)을 가져올 때 사용됩니다.
2. 노드 탐색 및 참조 (Node Navigation)
트리 구조 내에서 원하는 장치를 찾거나 연결된 장치를 추적하는 과정입니다.
- for_each_child_of_node: I2C 컨트롤러 드라이버가 자기 밑에 달린 센서들을 하나씩 확인할 때 사용합니다.
- of_parse_phandle: "이 장치가 쓰는 클럭은 저쪽 클럭 컨트롤러에 있어"라는 연결 고리를 따라갈 때 사용합니다.
3. 리소스 변환 (Resource Mapping)
가장 중요한 부분으로, DTS의 추상적인 숫자를 커널이 제어할 수 있는 실제 메모리 주소와 인터럽트 번호로 바꾸는 과정입니다.
- of_iomap: DTS의 reg 주소를 커널 가상 주소로 매핑하여 직접 레지스터를 읽고 쓸 수 있게 해줍니다.
- of_irq_get: 하드웨어 핀 번호를 커널 시스템의 IRQ 번호로 변환합니다.
위 코드의 성격: 보통 다음과 같은 곳에서 자주 발견됩니다.
- 커널 공식 문서의 예제: Documentation/devicetree/ 경로에 있는 설명 문서들.
- 드라이버 개발 튜토리얼: 임베디드 리눅스 교육 자료나 블로그의 "Hello World" 드라이버 예제.
- 커널 내부 테스트 코드: drivers/of/unittest.c와 같이 API 동작을 검증하기 위한 코드.
💡 팁: 실제 드라이버 작성 시 주의점
위 코드 중 of_find_...나 of_parse_phandle처럼 노드를 직접 찾는 함수들은 사용 후 반드시 of_node_put(node)를 호출해야 합니다. 커널은 내부적으로 노드의 참조 횟수(Reference Count)를 관리하기 때문에, 이를 잊으면 메모리 누수가 발생할 수 있습니다.
반면, pdev->dev.of_node를 통해 전달받은 노드는 플랫폼 버스가 관리해주므로 직접 해제할 필요가 없습니다.

참고: https://www.minzkn.com/linuxkernel/pages/device-tree.html#dt-device-node
'Embedded : : Linux > : : Device Tree' 카테고리의 다른 글
| [Device Tree] 11. 특수 노드와 고급 패턴 (0) | 2026.03.04 |
|---|---|
| [Device Tree] 10. Device Tree + Platform Driver 통합 (0) | 2026.03.04 |
| [Device Tree] 8. DTS 컴파일과 디컴파일 (0) | 2026.03.04 |
| [Device Tree] 7. Device Tree Bindings (0) | 2026.03.04 |
| [Device Tree] 6. Device Tree Overlay (DTBO) (0) | 2026.03.04 |