- Device Tree Source:
u-boot/arch/<$arch>/boot/dts
u-boot/arch/<$arch>/dts
- 아래는
u-boot/arch/arm/dts
디렉토리
수많은 soc별 dts
(device tree source) 가 있다.
- Beaglebone Black이 사용하는 dts를 살펴보자.
$ grep -nrH "AM335x"
u-boot/arch/arm/dts/am335x-boneblack.dts
를 살펴본다.
Device Tree의 구성
u-boot/arch/arm/dts/am335x-boneblack.dts
루트(/
) 노드 내에 chosen
노드가 있다.
나중에 접근시 /chosen
으로 노드에 접근한다.
u-boot/arch/arm/dts/bcm2837-rpi-3-b-plus.dts
루트(/
) 노드 내에 memory@0
노드가 있다.
노드 이름 끝에 @주소
를 쓰는 것은 같은 종류의 다른 노드와 구별하기 위해서이다.(관례)
/
노드에 compatible
property가 있다.
- 리눅스 커널은 이
compatible
property를 이용해 디바이스 드라이버가 of_device_id
구조체에 저장해둔 문자열과 비교하여 일치하는 디바이스 드라이버를 찾는다.
reg 프로퍼티
- 레지스터 공간에 있는 구성 단위의 범위를 나타낸다.
reg
프로퍼티는 <범위의 시작 주소와 크기(길이)>
로 이뤄지는데, 둘다 Cell이라는 0개 이상의 32bit 정수로 나타낸다.
따라서, 여기서(rpi 3 b+
) 메모리노드는 0
번지 ~0x40000000
Byte 길이의 '단일 뱅크 메모리'이다.
0~0x40000000
: 4∗167Byte = 1024MByte = 1GByte
- 64bit 주소를 사용하는 장치의 경우 각각 두 셀이 필요하다.
/ {
memory@80000000 {
device_type = "memory";
reg = <0x00000000 0x80000000 0 0x80000000>;
};
}
- 필요한 셀의 개수에 대한 정보는 조상 노드의
#address-cells
, #size-cells
에 선언되어 있다.
- 즉,
reg
프로퍼티를 이해하려면, #address-cells
, #size-cells
property를 찾을 때까지 노드 계층 구조를 되짚어봐야한다.
- 찾을 수 없다면, 기본값은
1
이다.
- CPU의 경우
/cpus
노드에서 #address-cells = <1>
이고, #size-cells = <0>
이다. 즉, 깊이가 없는 1차원 배열이다.
/cpus/cpu@0
노드의 reg
프로퍼티는 <0>
이다.
레이블, 인터럽트
- 인터럽트 컨트롤러, 클록 소스, 전압 조정기등이 연결되어 있다.
- 이들의 연결을 나타내기 위해, 노드에 레이블을 추가하가고, 다른 노드에서 그 레이블을 참조 할 수 있다.
- 이러한 레이블을
phandle
이라고 한다.
- 장치 트리가 컴파일되면, 다른 노드에서 참조하는 노드에
phandle
이라는 프로퍼티에 고유한 수치가 할당되기 때문이다.
- 장치 트리 바이너리(
dtb
)를 디컴파일하면 그 수치를 볼 수 있다.
- 인터럽트를 만들 수 있는
LCD 컨트롤러
와 인터럽트 컨트롤러
를 갖고 있는 시스템을 예로 들어본다.
- 그 밖의 인터럽트 컨트롤러는 인터럽트의 특징(예: 에지 트리거인지 레벨 트리거인지 등)를 나타내기 위해 셀을 추가로 사용할 수 있다.
- 인터럽트 셀의 수와 의미는 인터럽트 컨트롤러별 바인딩에 설명되어 있다.
- 바인딩은
Documentation/devicetree/bindings/
디렉토리의 리눅스 커널 소스에서 찾을 수 있다.
Device Tree include
- 비슷한 종류의 SoC사이에는 공통점이 많기 때문에 공통 부분을
include
파일로 분리할 수 있다.
u-boot/arch/arm/dts/bcm2837-rpi-3-b-plus.dts
의 경우
u-boot/arch/arm/dts/bcm2837.dtsi
u-boot/arch/arm/dts/bcm283x.dtsi
u-boot/include/dt-bindings/gpio/gpio.h
- 이 모든 Device Tree Source(dts)를 커널 Kbuild 시스템으로 빌드하면된다.
- Kbuild의 CPP 로
#include
, #define
문을 처리하여 device tree compiler에 알맞은 일반 텍스트로 변환된다.
bbb mmc1
- 비글본 블랙의 mmc1은 위의 레이블을 사용한다.
device tree compile
- 부트로더와 커널은 device tree의 binary 표현을 요구하므로, dtc(
device tree compile
)로 컴파일해야한다.
- 결과:
<name>.
dtb
= 디바이스 트리 바이너리, 디바이스 트리 덩이(blob)라 불림
- dtc:
u-boot/scripts/dtc/dtc
를 이용해 컴파일할 수 있다.
$ dtc simpledts-1.dts -o simpledts-1.dtb
DTC: dts->dts on file "simpledts-1.dts"
- 좀더 복잡한 빌드를 하려면, 커널
Kbuild
를 사용하자.