Device Tree Syntax의 약자이며, Kernel 와 Uboot에 존재하며, 보통 두개의 dts 파일은 동일하다
- Kernel PATH: arch/arm/boot/dts
- Uboot PATH: arch/arm/dts/
Device Tree Boot 방식
https://ahyuo79.blogspot.com/2015/08/am437x-kernel-device-tree.html
https://ahyuo79.blogspot.com/2015/08/device-tree-2-am437xam335x.html
Device Tree Syntax 구성방법
https://ahyuo79.blogspot.com/2015/08/device-tree.html
지향하는 바는 DTS를 한번 설정하면 손쉽게 Uboot 와 Kernel 의 HW 설정변경 가능하도록하는 것이다.
물론 예외적으로 보면, 각 Image들과 결합을 하게되어 사용을 한다면, 따로 사용도 가능하겠다.
DTSI와 DTS파일이 존재하며, DTSI는 DTS에서 include하는 파일이며, 구조 또한 동일하다.
하지만, dt-bindings도 include를 하지만 header 파일로 사용이 된다.
Build 전에는 DTS와 DTSI만 존재하지만, Build 후에 DTB가 생성이된다.
- Main files: ./arch/arm/boot/dts
- Include Files: ./arch/arm/boot/dts/include/dt-bindings
- Makefile: ./arch/arm/boot/dts/Makefile
1.1 AM437x Example
$ ls arch/arm/boot/dts/am4* am4372.dtsi am437x-gp-evm.dtb am437x-sk-evm.dtb am43x-epos-evm-hdmi.dts am43x-epos-evm.dts am437x-gp-evm-hdmi.dts am437x-gp-evm.dts am437x-sk-evm.dts am43x-epos-evm.dtb am43xx-clocks.dtsi
1.2 I.MX6 인 Example
I.MX6를 수정을 할때, 참고하던 Device Tree 예제들이며, 현재 Device Tree로 대부분의 CPU들이 지원을 하는 것 같다.
특히 한 것은 pinctl (iomuxc) 하는 방식이 TI와 다르게 사용되며, 관련부분은 별도로 봐야한다.
$ cat arch/arm/boot/dts/imx6ull-pinfunc.h // 핀확인 IOMUXC Register 확인 (Kernel 소스) $ vi arch/arm/boot/dts/imx6ul* // &iomuxc { ... pinctrl_can_int: canintgrp { fsl,pins = < /* IOMUXC_SW_MUX_CTL_PAD : MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04 IOMUXC_SW_PAD_CTL_PAD : 0x13010 (세부설정가능 Open Drain / Pull / Hysteresis Enable) : 0x80000000 상위 설정과 다르게 PAD Register를 변경을 막는다고 하는데, bit31/30은 자세한내용은 커널문서 */ MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04 0x13010 /* SODIMM 73 */ >; }; ... };
/sys/kernel/debug 가 되는 경우 아래와 같이 Pin 설정확인
$ ls /sys/kernel/debug/pinctrl/ // Target Device에서 debug 모드로 연결하여 확인 $ cat /sys/kernel/debug/pinctrl/pinctrl-handles // Target Device에서 설정확인 Requested pin control handlers their pinmux maps: device: 20e0000.iomuxc current state: default ........ $ cat /sys/kernel/debug/pinctrl/pinctrl-maps // 관련정보 $ cat /sys/kernel/debug/pinctrl/20e0000.iomuxc/pingroups // GPIO 의 경우 sysfs에서 도 사용가능하지만, 직접 device tree의 모듈에 연결이 되어 사용가능하므로 주의 // 이때 아래와 같이 확인한 후 device tree에서 연결된 모듈의 gpio부분을 제거한 후 사용 $ cat /sys/kernel/debug/gpio // GPIO 정보 Debug .......... gpio-112 ( |peri_3v3 ) out hi gpio-114 ( |sysfs ) out lo gpio-116 ( |sysfs ) out lo gpio-117 ( |sysfs ) out lo gpio-118 ( |sysfs ) out lo gpio-119 ( |sysfs ) out lo gpio-122 ( |sysfs ) out lo gpio-123 ( |can-stby ) out hi gpio-127 ( |sysfs ) out lo
최근에 찾은 자료이며, i.MX6의 Device Tree 구조를 아래 사이트에서 쉽게 볼수 있어 업데이트한다.
- i.MX의 Device Tree
i.MX6 관련내용
http://developer.toradex.com/device-tree-customization
https://developer.toradex.com/device-tree-customization#2-imx-6ull-based-modules
/sys/kernel/debug 관련내용
https://www.linuxtopia.org/online_books/linux_kernel/kernel_configuration/ch09s07.html
2. Device Tree 의 수정 및 사용법
Device Tree를 이해한다고, ARM BOOT를 다시 전체 분석을 할 필요는 없다.
지금 현재 제대로 동작을 하고 있으며, 필요한 모듈과 그기능을 찾아 그 부분만 수정을 하면 되기에 dts 파일과 dtsi파일을 이해하고 수정을 하면 되겠다.
2.1 DTS와 각 Driver의 구조 (AM437x 인 경우)
DTS파일과 각 Driver의 기본구조는 다음과 같다.
device tree의 기본동작 방식은 dts파일 안의 compatible의 이름과 driver의 맞을 경우 그 해당하는 driver에게 맞게 동작하게 되어있다.
그러므로, Kernel을 빌드후 다음과 같이 dts의 compatible의 이름을 검색하여 찾아 수정을하면 된다.
Device Tree의 위치는 위에서 설명했듯이 arch/arm/boot/dts/ 보면될 것이지만,관련된 부분을 전부 검색을 해보자.
2.2 DTS파일 수정 및 추가방법 (AM437x 경우)
상위에서 DTS파일을 수정하고, 추가한다면, Kernel 내부의 Makefile 수정하면된다.
새로운 dtb/dts을 추가한다고 하면 Kernel 내부의 dts 관련 Makefile 파일을 수정하자.
아래의 *.cmd는 실행한 결과들이며, 이것을 확인을 하면, 어떻게 생성이 되었는지 쉽게 이해를 할수 있다.
그리고 Filesystem 안의 boot에는 dtb 파일과 zImage는 File 형태로 존재하며 아래의 NFS File system에서도 동일하다.
3. How To compile DTS Files
다만 새로 추가했다면, Kernel 내부 Makefile을 수정해야하며, DTS에 맞는 Kernel Config를 확인하자.
만약, 위의 Makefile 파일에 추가 및 Makefile Config가 추가 되지 않았다면, target이 추가되지 않아 dtb를 compile를 할수가 없다.
3.1 How To use DTC(Device Tree Compiler)
위와 같이 Kernel Makefile를 이용하여 빌드하는 방법도 있지만,
직접 dtc를 사용하여 compile 하는 방법도 가능하다
*참고사항: 처음 Kernel source를 받으면, dtc file은 존재하지 않는다. build 도중 생김
http://www.wiki.xilinx.com/Build+Device+Tree+Blob
https://developer.toradex.com/device-tree-customization#2-imx-6ull-based-modules
/sys/kernel/debug 관련내용
https://www.linuxtopia.org/online_books/linux_kernel/kernel_configuration/ch09s07.html
2. Device Tree 의 수정 및 사용법
Device Tree를 이해한다고, ARM BOOT를 다시 전체 분석을 할 필요는 없다.
지금 현재 제대로 동작을 하고 있으며, 필요한 모듈과 그기능을 찾아 그 부분만 수정을 하면 되기에 dts 파일과 dtsi파일을 이해하고 수정을 하면 되겠다.
2.1 DTS와 각 Driver의 구조 (AM437x 인 경우)
DTS파일과 각 Driver의 기본구조는 다음과 같다.
device tree의 기본동작 방식은 dts파일 안의 compatible의 이름과 driver의 맞을 경우 그 해당하는 driver에게 맞게 동작하게 되어있다.
그러므로, Kernel을 빌드후 다음과 같이 dts의 compatible의 이름을 검색하여 찾아 수정을하면 된다.
Device Tree의 위치는 위에서 설명했듯이 arch/arm/boot/dts/ 보면될 것이지만,관련된 부분을 전부 검색을 해보자.
- Device Tree Source 관련소스 (driver) 검색
- Kernel을 빌드 후, find들 이용하여 *.o file list 생성된다.
- 이 file list들을 *.o에서 *.c 변경한다.
- 빌드된 file list의 *.c 중심으로 dts파일의 'compatible'로 검색진행
$ cd kernel source $ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs 'ti,am4372' $ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs 'arm,coretex-a9-gic' $ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs 'syscon' or $ MY_KERENL=./kernel_source $ find $MY_KERENL -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs 'syscon' $MY_KERENL
2.2 DTS파일 수정 및 추가방법 (AM437x 경우)
상위에서 DTS파일을 수정하고, 추가한다면, Kernel 내부의 Makefile 수정하면된다.
DTS파일을 빌드를 원한다면, Kernel로 이동 후에 빌드를 하자.
- AM437x는 기본 Makefile 구성 (DTS관련부분만)
- Main Makefile ( U-BOOT , Kernel, Filesystem 모두 관리)
- Rule.make ( 관련 설정)
- Kernel Source 내부 Makefile
- Main Makefile (DTB File Build 수정)
$ vi Makefile linux: linux-dtbs ### linux kernel 부분 build @echo ================================= @echo Building the Linux Kernel @echo ================================= $(MAKE) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) $(DEFCONFIG) $(MAKE) -j $(MAKE_JOBS) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zImage $(MAKE) -j $(MAKE_JOBS) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) modules ..... # Kernel DTB build targets linux-dtbs: @echo ===================================== @echo Building the Linux Kernel DTBs @echo ===================================== $(MAKE) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) $(DEFCONFIG) $(MAKE) -j $(MAKE_JOBS) -C $(LINUXKERNEL_INSTALL_DIR) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) am43x-epos-evm.dtb am437x-gp-evm.dtb am437x-sk-evm.dtb
- Linux Kernel/Uboot 에서 상위 dtb 생성확인 (check DTB files)
$ cd board-support/linux* // Linux Kernel Source 이동 $ find . -name *dtb // 상위 Makefile로 인하여 dtb 파일은 이미 3개 생성됨 확인 ./arch/arm/boot/dts/am437x-sk-evm.dtb ./arch/arm/boot/dts/am43x-epos-evm.dtb ./arch/arm/boot/dts/am437x-gp-evm.dtb ./include/config/arm/atag/dtb
- Linux Kernel/Uboot 에서 내부 Makefile 수정 (for new DTS File)
새로운 dtb/dts을 추가한다고 하면 Kernel 내부의 dts 관련 Makefile 파일을 수정하자.
$ cd board-support/linux* // Linux Kernel Source 이동 $ vi .config // Kernel Config 확인 ... CONFIG_SOC_AM43XX=y # CONFIG_SOC_DRA7XX is not set CONFIG_ARCH_OMAP2PLUS=y .... $ vi arch/arm/boot/dts/Makefile // new dts file 추가 , 본인의 dts 설정파일 만들어 추가하자 dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ omap2430-sdp.dtb \ omap2420-n800.dtb \ omap2420-n810.dtb \ omap2420-n810-wimax.dtb \ omap3430-sdp.dtb \ omap3-beagle.dtb \ omap3-cm-t3730.dtb \ omap3-sbc-t3730.dtb \ omap3-devkit8000.dtb \ omap3-beagle-xm.dtb \ omap3-evm.dtb \ omap3-evm-37xx.dtb \ omap3-ldp.dtb \ omap3-n900.dtb \ omap3-n9.dtb \ omap3-n950.dtb \ omap3-overo-tobi.dtb \ omap3-overo-storm-tobi.dtb \ omap3-gta04.dtb \ omap3-igep0020.dtb \ omap3-igep0030.dtb \ omap3-zoom3.dtb \ omap4-panda.dtb \ omap4-panda-a4.dtb \ omap4-panda-es.dtb \ omap4-var-som.dtb \ omap4-sdp.dtb \ omap4-sdp-es23plus.dtb \ omap5-uevm.dtb \ am335x-evm.dtb \ am335x-evmsk.dtb \ am335x-bone.dtb \ am335x-boneblack.dtb \ am335x-nano.dtb \ am335x-base0033.dtb \ am3517-craneboard.dtb \ am3517-evm.dtb \ am3517_mt_ventoux.dtb \ am43x-epos-evm.dtb \ am43x-epos-evm-hdmi.dtb \ am437x-gp-evm.dtb \ am437x-gp-evm-hdmi.dtb \ am437x-sk-evm.dtb \ dra7-evm.dtb \ dra7-evm-lcd10.dtb \ dra72-evm.dtb \ dra72-evm-lcd10.dtb \ am57xx-beagle-x15.dtb \ am57xx-evm.dtb
- Linux Kernel 내부 Makefile 에서 zImage 확인
아래의 *.cmd는 실행한 결과들이며, 이것을 확인을 하면, 어떻게 생성이 되었는지 쉽게 이해를 할수 있다.
$ cd board-support/linux* // Linux Kernel Source 이동 $ find . -name zImage //zImage 와 Image 위치파악 ./arch/arm/boot/zImage $ ls -a arch/arm/boot/ // zImage와 Image 생성 부분 분석 ( Makefile , *.cmd) . .. .Image.cmd .gitignore .zImage.cmd Image Makefile bootp compressed dts install.sh zImage $ cat ./arch/arm/boot/.zImage.cmd //제대로 빌드되었다면 아래와 같이 확인가능 cmd_arch/arm/boot/zImage := /home/jhlee/am437x/works/linux-devkit/sysroots/i686-arago-linux/usr/bin/arm-linux-gnueabihf-objcopy -O binary -R .comment -S arch/arm/boot/compressed/vmlinux arch/arm/boot/zImage $ vi arch/arm/boot/Makefile // zImage 확인 .... targets := Image zImage xipImage bootpImage uImage ifeq ($(CONFIG_XIP_KERNEL),y) // 현재 XIP 모드가 아님 ( NOR NAMD 이면, 가능하겠지만?) $(obj)/xipImage: vmlinux FORCE $(call if_changed,objcopy) @$(kecho) ' Kernel: $@ is ready (physical address: $(CONFIG_XIP_PHYS_ADDR))' $(obj)/Image $(obj)/zImage: FORCE @echo 'Kernel configured for XIP (CONFIG_XIP_KERNEL=y)' @echo 'Only the xipImage target is available in this case' @false else $(obj)/xipImage: FORCE @echo 'Kernel not configured for XIP (CONFIG_XIP_KERNEL!=y)' @false $(obj)/Image: vmlinux FORCE $(call if_changed,objcopy) @$(kecho) ' Kernel: $@ is ready' $(obj)/compressed/vmlinux: $(obj)/Image FORCE $(Q)$(MAKE) $(build)=$(obj)/compressed $@ $(obj)/zImage: $(obj)/compressed/vmlinux FORCE $(call if_changed,objcopy) ## OBJCOPYFLAGS 사용하며, objcopy를 이용하여 object를 binary를 만들때 사용한다 @$(kecho) ' Kernel: $@ is ready' ## 자세한 내용은 Kernel 문서와 GCC 참조 endif
- Filesytem 에서 DTB와 Kernel zImage 확인
그리고 Filesystem 안의 boot에는 dtb 파일과 zImage는 File 형태로 존재하며 아래의 NFS File system에서도 동일하다.
$ cd board-support/linux* // Linux Kernel Source 이동 $ sudo cp arch/arm/boot/zImage/boot // File System의 Boot에 저장 $ sudo cp arch/arm/boot/dts/ .dtb /boot // File System의 Boot에 저장 $ targetNFS/boot //Kernel Image 와 *.dtb File 확인 (File system 안에 존재) $ ll drwxr-xr-x 2 jhlee jhlee 4096 7월 7 2015 ./ drwxr-xr-x 21 jhlee jhlee 4096 7월 7 2015 ../ lrwxrwxrwx 1 jhlee jhlee 40 7월 7 2015 am437x-gp-evm-hdmi.dtb -> devicetree-zImage-am437x-gp-evm-hdmi.dtb lrwxrwxrwx 1 jhlee jhlee 35 7월 7 2015 am437x-gp-evm.dtb -> devicetree-zImage-am437x-gp-evm.dtb lrwxrwxrwx 1 jhlee jhlee 35 7월 7 2015 am437x-sk-evm.dtb -> devicetree-zImage-am437x-sk-evm.dtb lrwxrwxrwx 1 jhlee jhlee 41 7월 7 2015 am43x-epos-evm-hdmi.dtb -> devicetree-zImage-am43x-epos-evm-hdmi.dtb lrwxrwxrwx 1 jhlee jhlee 36 7월 7 2015 am43x-epos-evm.dtb -> devicetree-zImage-am43x-epos-evm.dtb -rw-r--r-- 1 jhlee jhlee 49048 7월 7 2015 devicetree-zImage-am437x-gp-evm-hdmi.dtb -rw-r--r-- 1 jhlee jhlee 48112 7월 7 2015 devicetree-zImage-am437x-gp-evm.dtb -rw-r--r-- 1 jhlee jhlee 42675 7월 7 2015 devicetree-zImage-am437x-sk-evm.dtb -rw-r--r-- 1 jhlee jhlee 48544 7월 7 2015 devicetree-zImage-am43x-epos-evm-hdmi.dtb -rw-r--r-- 1 jhlee jhlee 47461 7월 7 2015 devicetree-zImage-am43x-epos-evm.dtb -rw-r--r-- 1 jhlee jhlee 105402448 7월 7 2015 vmlinux-3.14.43-g875c69b lrwxrwxrwx 1 jhlee jhlee 23 7월 7 2015 zImage -> zImage-3.14.43-g875c69b -rw-r--r-- 1 jhlee jhlee 4355472 7월 7 2015 zImage-3.14.43-g875c69b
- TI-Kernel User Guide
3. How To compile DTS Files
다만 새로 추가했다면, Kernel 내부 Makefile을 수정해야하며, DTS에 맞는 Kernel Config를 확인하자.
$ cd board-support/linux* // linux kernel 이동 $ ls .config // DTS에 맞는 config 설정이 되어있어야 함. $ make ARCH=arm CROSS_COMPILE=arm-xxxxx $ make ARCH=arm CROSS_COMPILE=arm-xxxxx am43x-epos-evm.dtb
만약, 위의 Makefile 파일에 추가 및 Makefile Config가 추가 되지 않았다면, target이 추가되지 않아 dtb를 compile를 할수가 없다.
3.1 How To use DTC(Device Tree Compiler)
위와 같이 Kernel Makefile를 이용하여 빌드하는 방법도 있지만,
직접 dtc를 사용하여 compile 하는 방법도 가능하다
*참고사항: 처음 Kernel source를 받으면, dtc file은 존재하지 않는다. build 도중 생김
- DTC (Device Tree Compiler)
$ cd board-support/linux* // linux kernel 이동 $ ./scripts/dtc/dtc -I dtb -O dts -o (devicetree name).dts (devicetree name).dtb // 직접 build
http://www.wiki.xilinx.com/Build+Device+Tree+Blob
4. Device Tree Guide
https://www.devicetree.org/specifications/ (문법)
http://devicetree.org/Device_Tree_Usage (수정방법)
https://www.kernel.org/doc/Documentation/arm/Booting
http://www.elinux.org/images/a/ad/Arm-soc-checklist.pdf
http://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf
http://schedule2012.rmll.info/IMG/pdf/LSM2012_ArmKernelConsolidation_Petazzoni.pdf
http://events.linuxfoundation.org/sites/events/files/slides/presentation_3.pdf
http://lxr.free-electrons.com/source/Documentation/devicetree/booting-without-of.txt
- Device Tree Syntax Spec (중요)
https://www.devicetree.org/specifications/ (문법)
http://devicetree.org/Device_Tree_Usage (수정방법)
- TI Device Tree 사용법
- Kernel/Uboot 내부 문서
https://www.kernel.org/doc/Documentation/arm/Booting
- 쉽게 Device Tree를 설명해주는 사이트
http://www.elinux.org/images/a/ad/Arm-soc-checklist.pdf
http://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf
http://schedule2012.rmll.info/IMG/pdf/LSM2012_ArmKernelConsolidation_Petazzoni.pdf
http://events.linuxfoundation.org/sites/events/files/slides/presentation_3.pdf
http://lxr.free-electrons.com/source/Documentation/devicetree/booting-without-of.txt