ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [리눅스 커널] devicetree overlay
    Linux/kernel 2023. 8. 7. 19:22

    글의 참고

    - https://docs.kernel.org/devicetree/overlay-notes.html

    - https://github.com/raspberrypi/documentation/blob/develop/documentation/asciidoc/computers/configuration/device-tree.adoc

    - https://www.microchip.com/forums/m1212896.aspx

    - https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README

    - https://www.cnblogs.com/qiengo/p/5915508.html


    글의 전제

    - 밑줄로 작성된 글은 강조 표시를 의미한다.

    - 그림 출처는 항시 그림 아래에 표시했다.

    - 라즈베리파이에서만 테스트를 진행했다. 다른 리눅스 배포판에서는 적용되지 않을 수 있다.


    글의 내용

    - 디바이스트리 오버레이

    : 기존에 한글로 나와있는 디바이스트리 오버레이 설명들이 오버레이를 너무 직역한 느낌들이 많이 들어서 최대한 쉽게 설명해보도록 하려고 합니다. 디바이스 오버레이를 쓰는 이유는 `동적으로 커널의 디바이스 트리를 수정해야 할 경우`에 입니다. 오버레이를 동적으로 적용하기 위해 2가지 방식을 사용합니다.

    1. overlay를 만들고 config.txt에 적용하여 reboot.
      • 여기서 동적은 완전한 동적은 아닙니다. 왜냐면, 수정 내역을 반영하기 위해 결국 reboot을 해야하기 때문입니다... 일단 그래도 dtc로 하나의 dts만 컴파일하는 것은 시간도 거의 걸리지 않기 때문에 아주 활용성이 좋다고 볼 수 있을 듯 합니다. 그리고 overlay는 동적으로 기능을 수정하기 위해 나오기는 했지만, 요즘은 기능의 분할 측면에서도 상당히 자주 활용되어 보입니다.
    2. dtoverlay 명령어를 통해 동적으로 적용.
      • 진짜 동적으로 디바이스트리를 수정합니다. dtoverlay ${DEVICETREE_NME} 을 작성하여 동적으로 적용이 됩니다. 그러나 자주 사용하지는 않습니다. 여기서는 dtoverlay 명령어 대해서는 다루지 않겠습니다.
    • 다시 본래의 목적으로 돌아와서 디바이스 오버레이를 사용하면 아래와 같은 기능을 수행할 수 있습니다.
      1. 어딘가에 이미 작성딘 노드의 프로퍼티를 변경 할 수 있습니다.
      2. 새로운 노드를 추가할 수 있습니다. 
    • 그리고 오버레이를 활용하여 하나의 파일안에(특히 공통 부분인 *.dtsi) 늘어나는 코드양을 작은 단위별로 분할 할 수 있습니다. 

     

    구조

    • DT overlay는 여러 fragment라고 하는 것들로 구성되어 있습니다. 각 framgment들은 하나의 노드만을 가질 수 있습니다. 그런데 그 노드는 여러 자식 노드를 가 질 수 있습니다.
    • RPI4 버전이면 compatible = "brcm,bcm2711" 입니다. 나머지 RPI들은 모두 compatbile = "brcm,bcm2835"입니다.
    /dts-v1/;  
    /plugin/;  
    
    / {
        compatible = "brcm,bcm2835";
    
        fragment@0 {
            target = <&a>;
            a: __overlay__ {
                phandle = <1>;
    
                a1: a1@0 {
                    status = "okay";
                };
                
                a2: a2@1 {
                	status = "okay";
                };
            };
        };
    
        fragment@1 {
            target = <&b>;
            __overlay__ {
                s1: s1 {
                    phandle = <2>;
                };
    
                s2: s2 {
                    status = "okay";
                };
            };
        };
        
         fragment@2 {
            target = <&c>;
            __overlay__ {
                c = "temp";
            };
        };
    };

     

    • fragment는 0부터 순차적으로 번호가 매겨집니다. 이 규칙은 반드시 지켜야 합니다. 
    • 그리고 각 fragment는 2개의 파트로 구성된다. 
    1.  target  : 기존의 어딘가에 작성된 노드를 참조할지 나타내는 속성입니다.
    2. __overlay__ : target 프로퍼티에 참조하는 노드를 나타냅니다.

     

    • 위의 내용은 아래와 같다고 보시면 됩니다.
    /dts-v1/;  
    /plugin/;  
    
    / {
        compatible = "brcm,bcm2835";
    };
    
    &a {
    	phandle = <1>;
    	a1: a1@0 {
    		status = "okay";
    	};
                
    	a2: a2@1 {
    		status = "okay";
    	};
    };
    
    
    &b {
        s1: s1 {
    		phandle = <2>;
    	};
    
    	s2: s2 {
        	status = "okay";
    	};
    };
        
    &c {
    	c = "temp";
    };
    • target과 __overlay__ 가 참조된 노드들로 대체된 것을 확인할 수 있습니다.

     

    • 파일을 만들었으니 빌드를 해보겠습니다. 파일 이름은 test.dts로 하겠습니다. 빌드는 dtc를 이용할 겁니다.

     

    • 먼저 dtc를 설치해야 합니다. 아마 라즈베리파이에는 dtc가 설치가 되어 있지 않을겁니다. 아래의 명령어를 통해 설치가 필요합니다.
    sudo apt-get update -y
    sudo apt-get install device-tree-compiler

     

    • 아래의 명령어로 빌드를 진행합니다. 각 파라미터의 대한 설명은 기본적인 부분이므로 dtc -h 입력 해보시기 바랍니다.
    dtc -@ -Hepapr -I dts -O dtb -o test.dtbo test.dts

     

    : `-@ -Hepapr`은 참조에 대한 에러 발생을 막기 위해서 사용한다. 위에서 우리는 &a, &b, &c 라는 노드를 참조하는데, `dtc -@ -Hepapr -I dts -O dtb -o test.dtbo test.dts` 명령어에서는 어디에도 해당 노드를 작성한 파일이 없습니다. 그래서 원래라면 빌드 에러가 발생한다. 그 에러를 막기 위해서 `-@ -Hepapr` 옵션을 추가로 넣어주는 것입니다. 실제로 `unresolved references`를 해결해주는 옵션은 `-@`이다.

     

    ...
    This shouldn’t be too unexpected, since there is no reference to the base .dtb or .dts file to allow the compiler to find the i2s label. Trying again, this time using the original example and adding the `-@` option to allow unresolved references (and `-Hepapr` to remove some clutter):
    ...

    - 참고 : https://github.com/raspberrypi/documentation/blob/develop/documentation/asciidoc/computers/configuration/device-tree.adoc

    : 빌드를 하면 경고 문구들이 나올 수 있다. 당연히 참조 관련 경고 문구일 것이다. 현재 상황에서는 당연한 문제이고 일단은 에러 문구가 아니므로, 신경쓰지 않아도 된다. 빌드를 완료하면 `test.dtbo` 라는 파일이 생성되어 있을 것이다. 해당 파일의 권한을 755로 변경 후,  /boot/overlay 폴더에 복사한다.

     

    : 그리고 config.txt를 수정해야 한다. 라즈베리파이에서는 디바이스트리의 사용여부를 전적으로 config.txt에 의존하기 때문에, config.txt를 수정해야 한다. 참고로 `/boot/config.txt`에 `device_tree=` 라고 작성하면 라즈베리파이가 디바이스트리를 비활성화하여 부팅한다. 그리고 `/boot/config.txt`의 아래와 같이 입력하고 `리부트` 된다. 그리고 `/proc/device-tree/`에서 본인이 반영한 내용이 들어가 있는지 확인해보자.

    dtoverlay=test // dtbo는 생략
Designed by Tistory.