Device Tree

markyang92·2022년 3월 4일
0

boot

목록 보기
2/6
post-thumbnail
  • U-Boot 내 Device Tree
    • U-Boot Version: 2021.07

  • 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번지 ~0x40000000Byte 길이의 '단일 뱅크 메모리'이다.
    • 0~0x40000000: 4167{4*16^7}Byte = 1024MByte{1024 MByte} = 1GByte{1 GByte}

  • 64bit 주소를 사용하는 장치의 경우 각각 두 셀이 필요하다.
/ {
    #address-cells = <2>;
    #size-cells = <2>;
    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 시스템으로 빌드하면된다.
    • KbuildCPP#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를 사용하자.
profile
pllpokko@alumni.kaist.ac.kr

0개의 댓글