본문 중간의 쿠팡 추천 상품 구매시 쿠팡 파트너스에서 일정액의 수수료를 제공받습니다.

리눅스 Device Tree #address-cells와 #size-cells 기준 정리
#address-cells와 #size-cells는 Device Tree에서 자식 노드의 reg, ranges, dma-ranges 같은 주소 관련 속성을 몇 개의 32비트 셀로 해석할지 정하는 기준이다. 2026년 7월 18일 확인 기준 Devicetree Specification은 이 두 속성이 자식 노드의 주소와 길이 인코딩 방식을 정의하며, 상위 조상에서 자동 상속되지 않으므로 자식을 가진 노드마다 명시적으로 정의해야 한다고 설명한다.
실무에서 가장 많이 헷갈리는 지점은 세 가지다. 루트와 버스 노드에서 어떤 값을 써야 하는지, #size-cells = <0>일 때 reg를 어떻게 적어야 하는지, 그리고 ranges를 해석할 때 어느 노드의 셀 수를 따라야 하는지다. 이 글은 그 세 가지를 중심으로 안전한 작성 기준만 정리한다.
#address-cells와 #size-cells는 무엇을 정할까?
Devicetree Specification에 따르면 #address-cells는 자식 노드의 reg 속성 안에서 주소 필드를 표현하는 <u32> 셀 개수를 뜻하고, #size-cells는 길이 필드를 표현하는 셀 개수를 뜻한다. 여기서 셀 하나는 32비트 정수다.
즉 #address-cells = <1>, #size-cells = <1>이면 자식 노드의 reg 한 항목은 <address size> 두 셀로 끝난다. 반대로 주소를 64비트로 표현해야 하면 주소 쪽 셀 수를 2로 늘려야 하고, 버스 특성에 따라 길이도 2셀을 쓸 수 있다.
이 값은 어디에 적어야 할까?
핵심은 "자식을 해석하는 부모에 적는다"는 점이다. 어떤 노드의 reg를 읽을 때 기준이 되는 셀 수는 그 노드 자신이 아니라 부모 노드의 #address-cells, #size-cells다.
Devicetree Specification과 Linux 커널 문서는 공통으로 이 값이 상위 조상에서 자동 상속되지 않는다고 설명한다. 그래서 자식 노드를 가진 버스나 루트 노드는 필요한 값을 직접 선언하는 편이 맞다. Linux 커널 문서는 특히 루트 노드에 이 속성이 있어야 프로세서 버스에 직접 매핑된 장치 주소 형식을 해석할 수 있다고 설명한다.
루트 노드와 일반 버스 노드의 무난한 기준은?
| 상황 | 무난한 기준 | 이유 |
|---|---|---|
| 일반적인 32비트 SoC 루트 버스 | #address-cells = <1>#size-cells = <1> |
Linux 커널 문서는 대부분의 32비트 구현에서 1/1 형식이 32비트 값 표현에 맞는다고 설명한다 |
| 32비트 CPU지만 물리 주소가 32비트를 넘을 수 있다 | #address-cells = <2> 검토 |
커널 문서는 이런 경우 주소를 2셀로 표현하는 편이 맞다고 설명한다 |
| 자식 주소만 필요하고 크기 개념이 없는 버스 | #size-cells = <0> |
길이 셀을 생략해야 하는 버스에서는 reg에서 size 필드를 빼야 한다 |
| 단순 MMIO 버스 | 부모 버스 정의와 실제 주소 폭에 맞춰 명시 | 기본값 추정에 기대기보다 DTS에 드러내는 편이 안전하다 |
reg는 어떻게 달라질까?
Devicetree Specification은 reg가 주소와 길이의 쌍으로 이루어진 배열이라고 설명한다. 여기서 주소 셀 수와 길이 셀 수는 자식 노드의 부모가 선언한 #address-cells, #size-cells를 따른다.
예를 들어 부모 버스가 1/1 형식이면 아래처럼 쓴다.
soc {
#address-cells = <1>;
#size-cells = <1>;
serial@4600 {
reg = <0x4600 0x100>;
};
};
반대로 부모가 #size-cells = <0>이면 Devicetree Specification 기준으로 reg의 길이 필드를 생략해야 한다. Linux 커널 usage model 문서의 I2C 예제도 자식 장치 쪽에서 reg = <0x1a>처럼 주소만 남는 형태를 보여 준다.
i2c@7000c000 {
#address-cells = <1>;
#size-cells = <0>;
codec@1a {
reg = <0x1a>;
};
};
ranges를 볼 때는 무엇이 기준일까?
ranges는 자식 버스 주소 공간과 부모 버스 주소 공간 사이의 매핑을 설명하는 속성이다. Devicetree Specification은 각 항목이 (child-bus-address, parent-bus-address, length) 순서의 triplet이라고 설명한다.
여기서 셀 수는 한 곳에서 모두 결정되지 않는다. 자식 버스 주소 셀 수는 현재 노드의 #address-cells, 부모 버스 주소 셀 수는 상위 부모의 #address-cells, 길이 셀 수는 현재 노드의 #size-cells를 따른다. 그래서 버스 노드를 옮기거나 계층을 바꾸면 ranges 인코딩도 같이 다시 봐야 한다.
값을 생략하면 기본값에 기대도 될까?
Devicetree Specification은 값이 빠졌을 때 클라이언트가 #address-cells = 2, #size-cells = 1을 가정할 수 있다고 적고 있다. 다만 같은 문서가 DTSpec 호환 부트 프로그램은 자식을 가진 모든 노드에 이 두 속성을 공급해야 한다고도 설명한다.
실무 기준으로는 기본값 추정에 기대지 않는 편이 안전하다. 루트와 버스 노드에 실제 의도를 드러내면 DTS를 읽는 사람과 도구가 같은 해석을 하기가 쉬워지고, 계층 변경 시에도 실수를 줄일 수 있다.
자주 틀리는 패턴은?
| 실수 | 문제점 | 확인 기준 |
|---|---|---|
| 조상 노드의 셀 정의가 자동 상속된다고 생각한다 | 자식 reg 길이를 잘못 계산할 수 있다 |
자식을 가진 각 노드에 값이 있는지 직접 본다 |
#size-cells = <0>인데도 reg에 크기 셀을 넣는다 |
스펙과 다른 인코딩이 된다 | 길이 필드가 정말 생략되어 있는지 본다 |
ranges의 세 구간 셀 수를 한 노드 값만 보고 계산한다 |
부모 주소 영역 셀 수를 틀릴 수 있다 | 현재 노드와 상위 부모 노드를 함께 본다 |
| 32비트 CPU라는 이유만으로 항상 1셀 주소라고 단정한다 | 물리 주소 폭이 더 큰 SoC를 놓칠 수 있다 | 실제 주소 공간 폭과 바인딩 문서를 같이 확인한다 |
FAQ
Q. #address-cells와 #size-cells는 자식 노드에 적어야 할까?
아니다. 자식 노드의 주소 표현 방식을 정하는 값이므로 부모 노드에 적는다. 자식의 reg는 그 부모가 선언한 셀 수를 따라 해석한다.
Q. #size-cells = <0>이면 reg에 0 길이를 넣으면 될까?
그렇게 보면 안 된다. Devicetree Specification은 이 경우 reg에서 길이 필드를 생략해야 한다고 설명한다. 즉 0을 넣는 것이 아니라 size 항목 자체가 없어야 한다.
Q. 스펙 기본값이 있으니 생략해도 괜찮을까?
권장하기 어렵다. 스펙은 누락 시 가정값을 설명하지만, 동시에 자식을 가진 노드에는 이 속성을 명시적으로 제공해야 한다고 적고 있다. Linux DTS 유지보수 관점에서도 명시가 더 안전하다.
정리
#address-cells와 #size-cells를 볼 때 핵심은 네 가지다. 셀 하나는 32비트이고, 자식 노드의 reg와 주소 관련 속성 해석은 부모가 정하며, 이 값은 조상에서 자동 상속되지 않고, #size-cells = <0>이면 reg에서 길이 필드를 빼야 한다.
실무에서 가장 무난한 기준은 "버스 계층마다 셀 수를 명시하고, reg와 ranges를 그 정의에 맞춰 다시 계산한다"는 원칙이다. 주소 폭이 커질 수 있는 SoC나 I2C처럼 size 셀이 없는 버스에서는 이 원칙이 특히 중요하다.
참고 자료
'프로그래밍 > 리눅스 커널' 카테고리의 다른 글
| 리눅스 Device Tree dma-ranges 기준 정리 (0) | 2026.07.23 |
|---|---|
| 리눅스 Device Tree stdout-path 기준 정리 (0) | 2026.07.13 |
| 리눅스 Device Tree aliases 기준 정리 (0) | 2026.07.06 |
| 리눅스 Device Tree label과 overlay 기준 정리 (0) | 2026.05.25 |
| 리눅스 Device Tree status 기준 정리 (0) | 2026.05.24 |





