Github Page

레이블이 SoC-OMAP인 게시물을 표시합니다. 모든 게시물 표시
레이블이 SoC-OMAP인 게시물을 표시합니다. 모든 게시물 표시

12/08/2016

DM814x SDK 설치 및 관련 설정

1. EZSDK 설치

수정중
Memory Map 과 구조도 및 Firmware 이해 필요,
Linux File system 부분 수정 부분

1.1 GCC Tool Chain and SDK Download 

  • arm-2009q1-203-arm-none-linux-gnueabi.bin (Code Sourcery ARM GCC Tool Chain)
  • ezsdk_dm814x-evm_5_05_02_00_setuplinux
  http://www.ti.com/tool/linuxezsdk-davinci

1.2 개발환경구성 

  • 환경변수 재설정
아래의 환경변수는 CROSS_COMPILE과 INSTALL_MOD_PATH 등 Makefile과 Rule.make를
보고 필요한부분을 넣었다.
기본정의 Rule.make에 정의가 되어있으면 동작이 제대로 되어야겠지만,
본인이 원하는 대로 동작이 안된다면, 두 파일을 비교하여 오동작되는 부분을 파악해서
환경변수 고치던지 하는것이 편할 것이다.
나는 source 를 이용하여 아래와 같이 그냥 외부에서 설정을 해놓았다.  

$ vi setPATH.sh
#!/bin/sh
# source setPATH.sh
# INSTALL_MOD_PATH : Kernel Module 
# SYSLINK_INSTALL_DIR : syslink.ko 

export PATH=$PATH:/home/jhlee/dm8148/CodeSourcery/Sourcery_G++_Lite/bin
export EZSDK="${HOME}/dm8148/ti-ezsdk_dm814x-evm_xx_xx_xx_xx" 
export CROSS_COMPILE=arm-none-linux-gnueabi-
export ARCH=arm

export INSTALL_MOD_PATH="${HOME}/dm8148/targetfs"     // Kernel module    

$ source setPATH.sh 

  • 개발환경구성설정 (TI에서 제공)
  1. NFS Server 환경구성 
  2. TFTP 설정 
$ cd ~/dm8148/ti-ezsdk_dm814x-evm_5_05_02_00 
$./setup.sh              // 자동으로 설정 NFS/TFTP 



1.3 EZSDK 설치시 구조 및 빌드방법



  • EZSDK 설치시 구조

$ cd ~/dm8148/ti-ezsdk_dm814x-evm_5_05_02_00 
$ tree -d -L 2 
.
├── bin
├── board-support
│   ├── docs
│   ├── external-linux-kernel-modules
│   ├── host-tools
│   ├── linux-2.6.37-psp04.04.00.01
│   ├── media-controller-utils_3_00_00_05
│   ├── prebuilt-images
│   └── u-boot-2010.06-psp04.04.00.01
├── component-sources
│   ├── bios_6_33_05_46
│   ├── c674x-aaclcdec_01_41_00_00_elf
│   ├── codec_engine_3_22_01_06
│   ├── edma3lld_02_11_05_02
│   ├── framework_components_3_22_01_07
│   ├── graphics-sdk_4.04.00.02
│   ├── gst-openmax_GST_DM81XX_00_07_00_00
│   ├── ipc_1_24_03_32
│   ├── linuxutils_3_22_00_02
│   ├── omx_05_02_00_48
│   ├── osal_1_22_01_09
│   ├── rpe_1_00_01_13
│   ├── slog_04_00_00_02
│   ├── syslink_2_20_02_20
│   ├── uia_1_01_01_14
│   ├── xdais_7_22_00_03
│   └── xdctools_3_23_03_53
├── docs
│   └── licenses
├── dsp-devkit
│   ├── cgt6x_7_3_4
│   ├── docs
│   └── packages
├── etc
├── example-applications
│   ├── am-benchmarks-1.1
│   ├── am-sysinfo-1.0
│   ├── linux-driver-examples-psp04.04.00.01
│   ├── matrix-gui-e-1.3
│   └── omtb_01_00_01_07
├── filesystem
├── linux-devkit
│   ├── arm-none-linux-gnueabi
│   ├── bin
│   ├── etc
│   ├── include
│   ├── lib
│   ├── mkspecs
│   ├── share
│   └── usr
└── usr
    ├── lib
    └── share


$ vi Rules.make  // 아래와 같이 수정 
....
#EXEC_DIR=/home/jhlee/dm8148/targetfs/home/root/dm814x-evm   // 기본으로 이것으로 설정하며, 진행한다. 
EXEC_DIR=/home/jhlee/dm8148/targetfs                         // 필요한 것이 있다면 그 때만 이것으로 설정 
                     // 위와 같이 진행하지 않으면 Filesystem이 필요없는것을 다 포함하게되어서 커진다. 

//예를들어 아래와 같이 진행하면, EXEC_DIR/usr/lib/....   설치되므로 필요할때만 위와 같이 변경 
$ make syslink
$ make syslink_install  

//전체 명령어 확인 및 Install 될 주소 확인                                                                
$ make help

Available build targets are  :

    components_linux               : Build the Linux components
    components_dsp                 : Build the DSP components
    components                     : Build the components for which a rebuild is necessary to enable all other build targets listed below. You must do this at least once upon installation prior to attempting the other targets.
    components_clean               : Remove files generated by the 'components' target

    apps                           : Build all Examples, Demos and Applications
    apps_clean                     : Remove all files generated by 'apps' target
    install                        : Install all Examples, Demos and Applications the targets in /home/jhlee/dm8148/targetfs/home/root/dm814x-evm

    linux-devkit                   : Populate the linux devkit
    dsp-devkit                     : Populate the dsp devkit

    cmem                           : Build the CMEM kernel module
    cmem_clean                     : Remove generated cmem files.
    cmem_install                   : Install cmemk module

    syslink                        : Configure and build SYS Link for HLOS and HLOS without sample examples
    syslink_clean                  : Remove generated SysLink files
    syslink_install                : Install HLOS and RTOS link files

    linux                          : Build Linux kernel uImage and module
    linux_clean                    : Remove generated Linux kernel files
    linux_install                  : Install kernel binary and  modules

    u-boot                         : Build the u-boot boot loader
    u-boot_clean                   : Remove generated u-boot files
    u-boot_install                 : Install the u-boot image

    psp-examples                   : Build the driver examples
    psp-examples_clean             : Remove generated driver example files
    psp-examples_install           : Install the psp examples

    osal                           : Build the OSAL
    osal_clean                     : Remove generated OSAL files

    matrix                         : Build matrix application launcher
    matrix_clean                   : Remove all matrix files
    matrix_install                 : Install matrix

    omx                            : Build OMX and OMX IL Clients
    omx_clean                      : Remove OMX generated files
    omx_install                    : Install OMX IL Clients

    omtb                           : Build OMTB IL Clients
    omtb_clean                     : Remove OMTB generated files
    omtb_install                   : Install OMTB IL Clients

    media-controller-utils         : Build media controller utils
    media-controller-utils_clean   : Remove media controller utils generated files
    media-controller-utils_install : Install media controller utils

    edma3lld                       : Build the EDMA3LLD Libraries
    edma3lld_clean                 : Remove generated EDMA3LLD files

    sgx-driver                     : Build SGX kernel module
    sgx-driver_clean               : Remove SGX generated files
    sgx-driver_install             : Install SGX kernel module

    gstomx                         : Build TI GST OpenMax Plugin
    gstomx_clean                   : Remove TI GST OpenMax generated files
    gstomx_install                 : Install TI GST OpenMax Plugin

    rpe                            : Build Remote Processor Execute
    rpe_clean                      : Remove Remote Processor Execute generated files
    rpe_install                    : Install Remote Processor Execute

    all                            : Rebuild everything
    clean                          : Remove all generated files

    install                        : Install all the targets in 
                            /home/jhlee/dm8148/targetfs/home/root/dm814x-evm // 중요: EXEC_DIR 수정 후 변경됨 


  • TI에서 제공하는 User Manual
  http://processors.wiki.ti.com/index.php/Category:EZSDK

  http://developer.ridgerun.com/wiki/index.php/Getting_Started_Guide_for_DM8148_EVM

  http://processors.wiki.ti.com/index.php/DM814x_AM387x_PSP_User_Guide

  http://processors.wiki.ti.com/index.php/DM814x_AM387x_PSP_User_Guide#Linux_Kernel

1.4 Video TEST

  • MPEG4 HDMI Decoding TEST 
$ gst-launch filesrc location= test1.mp4 ! qtdemux name=mux mux.video_00 ! queue  ! h264parse output-format=1 ! omx_h264dec ! omx_scaler ! omx_ctrl display-mode=OMX_DC_MODE_1080P_30 ! omx_videosink enable-last-buffer=false

  • IP Camera TEST
$ gst-launch -v rtspsrc location=rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264 caps="video/x-h264,mapping=/video " ! rtph264depay ! queue ! h264parse ! omx_h264dec ! omx_mdeiscaler name=d d.src_00 ! omx_ctrl display-mode=OMX_DC_MODE_1080P_30 ! omx_videosink enable-last-buffer=false 

$ gst-launch rtspsrc location=rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264 ! rtph264depay ! queue ! \
h264parse output-format=1 ! omx_h264dec ! omx_scaler ! omx_ctrl display-mode=OMX_DC_MODE_1080P_30 ! omx_videosink enable-last-buffer=false
  • IP Camera TEST (1080P Resize)
$ gst-launch rtspsrc location=rtsp://192.168.1.168:8556/PSIA/Streaming/channels/2?videoCodecType=H.264  ! rtph264depay ! queue ! h264parse access-unit=true ! queue ! omx_h264dec ! omx_mdeiscaler name=d d.src_00 ! 'video/x-raw-yuv, width=(int)1920, height=(int)1080' ! queue ! omx_ctrl \
display-mode=OMX_DC_MODE_1080P_30 ! gstperf print-fps=true print-arm-load=true ! omx_videosink sync=false enable-last-buffer=false

  • Gstreamer Examples
  https://developer.ridgerun.com/wiki/index.php/Gstreamer_pipelines_for_DM816x_and_DM814x
  https://developer.ridgerun.com/wiki/index.php/Gstreamer_pipelines_for_DM816x_and_DM814x#RTSP_-_Video_H264_1080.4030fps_2

  • DM8168 Firmware Debug
  https://developer.ridgerun.com/wiki/index.php?title=How_to_build_DM8168_M3_Firmware_and_debug_messages

3. KERNEL Config & Build 

위의 CROSS_COMPILE과 ARCH 환경변수가 설정이 되지 않을 경우 매번 설정하면서 실행.
미리 설정된 File은 아래 존재하며 이곳에서 보자.

$ cd ~/dm8148/
$ source setPATH.sh 
$ cd ti-ezsdk_dm814x-evm_5_05_02_00/board-support/linux-2.6.37-psp04.04.00.01
$ ls ./arch/arm/configs/       // 지원되는 Configs 확인    


$ make ti8148_evm_defconfig   // Kernel Config 설정 
$ make menuconfig             // 상위 setPATH.sh를 설정을 안했다면, ARCH=arm 선언하자.
$ make uImage                 // 상위 setPATH.sh를 설정을 안했다면  setARCH=arm 와 CROSS_COMPILE=arm-none-linux-gnueabi- 

$ cp /arch/arm/boot/uImage  /tftpboot/uImage

3.1 Kernel 분석 및 수정 

  • CTAGS와 CSCOPE 생성
vi 에서 소스분석을 더 용이하게 하기 위해서 아래와 같이 설치 및 사용하자.
  http://ahyuo79.blogspot.com/search?q=sudo+apt-get+install+ctags

  http://processors.wiki.ti.com/index.php/TI81xx_PSP_Porting_Guide


$ vi ./arch/arm/mach-omap2/board-ti8148evm.c
....
MACHINE_START(TI8148EVM, "ti8148evm")
        /* Maintainer: Texas Instruments */
        .boot_params    = 0x80000100,
        .map_io         = ti8148_evm_map_io,    // 변경된 device memory map check 
        .reserve         = ti81xx_reserve,
        .init_irq       = ti8148_evm_init_irq,   // 점검 
        .init_machine   = ti8148_evm_init,       // 변경된 device check , EVM과 현재보드와 사용하는 Device가 다름 (HDMI 변경 및 기타 IO및 사용안함)
        .timer          = &omap_timer,       
MACHINE_END


$ make uImage
  CHK     include/linux/version.h
  CHK     include/generated/utsrelease.h
make[1]: `include/generated/mach-types.h'는 이미 갱신되었습니다.
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  LD      vmlinux.o

drivers/built-in.o: In function `pcf8575_ths7375_enable':
notify_shm_drv.c:(.text+0x15f14): multiple definition of `pcf8575_ths7375_enable'
arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9ce8): first defined here
drivers/built-in.o: In function `vps_ti816x_set_tvp7002_filter':
notify_shm_drv.c:(.text+0x15f8c): multiple definition of `vps_ti816x_set_tvp7002_filter'
arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9d60): first defined here
drivers/built-in.o: In function `vps_ti816x_select_video_decoder':
notify_shm_drv.c:(.text+0x15f78): multiple definition of `vps_ti816x_select_video_decoder'
arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9d4c): first defined here
drivers/built-in.o: In function `ti816x_pcf8575_init':
notify_shm_drv.c:(.text+0x15f50): multiple definition of `ti816x_pcf8575_init'
arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9d24): first defined here
drivers/built-in.o: In function `pcf8575_ths7360_sd_enable':
notify_shm_drv.c:(.text+0x15f28): multiple definition of `pcf8575_ths7360_sd_enable'
arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9cfc): first defined here
drivers/built-in.o: In function `pcf8575_ths7360_hd_enable':
notify_shm_drv.c:(.text+0x15f3c): multiple definition of `pcf8575_ths7360_hd_enable'
arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9d10): first defined here
drivers/built-in.o: In function `ti816x_pcf8575_exit':
notify_shm_drv.c:(.text+0x15f64): multiple definition of `ti816x_pcf8575_exit'
arch/arm/mach-omap2/built-in.o:gpmc-nand.c:(.text+0x9d38): first defined here
make: *** [vmlinux.o] 오류 1

$ arm-none-linux-gnueabi-readelf -s arch/arm/mach-omap2/built-in.o | grep -r pcf8575_ths7375_enable
  2521: 00009ce8    20 FUNC    GLOBAL DEFAULT    1 pcf8575_ths7375_enable

$ arm-none-linux-gnueabi-readelf -s drivers/built-in.o | grep -r pcf8575_ths7375_enable
 21182: 00015f14    20 FUNC    GLOBAL DEFAULT    1 pcf8575_ths7375_enable

$ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs pcf8575_ths7375_enable
./drivers/video/ti81xx/vpss/dctrl.c:  r = pcf8575_ths7375_enable(TI816X_THSFILTER_ENABLE_MODULE);

$ grep -r pcf8575_ths7375_enable .
이진파일 ./drivers/built-in.o 와(과) 일치
이진파일 ./drivers/video/built-in.o 와(과) 일치
이진파일 ./drivers/video/ti81xx/built-in.o 와(과) 일치
./drivers/video/ti81xx/vpss/dctrl.c:  r = pcf8575_ths7375_enable(TI816X_THSFILTER_ENABLE_MODULE);
이진파일 ./drivers/video/ti81xx/vpss/dctrl.o 와(과) 일치
이진파일 ./drivers/video/ti81xx/vpss/built-in.o 와(과) 일치
이진파일 ./drivers/video/ti81xx/vpss/vpss.o 와(과) 일치
./tags:pcf8575_ths7375_enable arch/arm/mach-omap2/board-ti8168evm.c /^EXPORT_SYMBOL(pcf8575_ths7375_enable);$/;" v
./tags:pcf8575_ths7375_enable arch/arm/mach-omap2/board-ti8168evm.c /^int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl)$/;" f
./tags:pcf8575_ths7375_enable arch/arm/mach-omap2/include/mach/board-ti816x.h /^int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl)$/;" f
./arch/arm/mach-omap2/include/mach/board-ti816x.h:int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl);
./arch/arm/mach-omap2/include/mach/board-ti816x.h:int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl)
이진파일 ./arch/arm/mach-omap2/built-in.o 와(과) 일치
./arch/arm/mach-omap2/board-ti8168evm.c:int pcf8575_ths7375_enable(enum ti816x_ths_filter_ctrl ctrl)
./arch/arm/mach-omap2/board-ti8168evm.c:EXPORT_SYMBOL(pcf8575_ths7375_enable);
이진파일 ./arch/arm/mach-omap2/ti81xx_vpss.o 와(과) 일치


$ make menuconfig   // 필요 module을 yes로 변경 및 필요 없은 것들을 제거. 

$ make uImage
  CHK     include/linux/version.h
  CHK     include/generated/utsrelease.h
make[1]: `include/generated/mach-types.h'는 이미 갱신되었습니다.
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  LD      drivers/built-in.o
drivers/media/built-in.o: In function `vps_ti816x_set_tvp7002_filter':        // 이곳에서 에러가 나서 현재 complier가 혼동하는 것 같음 
ti81xxvin_lib.c:(.text+0x30eac): multiple definition of `vps_ti816x_set_tvp7002_filter'
drivers/video/built-in.o:sii9022a_drv.c:(.text+0x72d0): first defined here
drivers/media/built-in.o: In function `pcf8575_ths7375_enable':
ti81xxvin_lib.c:(.text+0x30e34): multiple definition of `pcf8575_ths7375_enable'
drivers/video/built-in.o:sii9022a_drv.c:(.text+0x7258): first defined here
drivers/media/built-in.o: In function `ti816x_pcf8575_init':
ti81xxvin_lib.c:(.text+0x30e70): multiple definition of `ti816x_pcf8575_init'
drivers/video/built-in.o:sii9022a_drv.c:(.text+0x7294): first defined here
drivers/media/built-in.o: In function `ti816x_pcf8575_exit':
ti81xxvin_lib.c:(.text+0x30e84): multiple definition of `ti816x_pcf8575_exit'
drivers/video/built-in.o:sii9022a_drv.c:(.text+0x72a8): first defined here
drivers/media/built-in.o: In function `pcf8575_ths7360_sd_enable':
ti81xxvin_lib.c:(.text+0x30e48): multiple definition of `pcf8575_ths7360_sd_enable'
drivers/video/built-in.o:sii9022a_drv.c:(.text+0x726c): first defined here
drivers/media/built-in.o: In function `vps_ti816x_select_video_decoder':
ti81xxvin_lib.c:(.text+0x30e98): multiple definition of `vps_ti816x_select_video_decoder'
drivers/video/built-in.o:sii9022a_drv.c:(.text+0x72bc): first defined here
drivers/media/built-in.o: In function `pcf8575_ths7360_hd_enable':
ti81xxvin_lib.c:(.text+0x30e5c): multiple definition of `pcf8575_ths7360_hd_enable'
drivers/video/built-in.o:sii9022a_drv.c:(.text+0x7280): first defined here
make[1]: *** [drivers/built-in.o] 오류 1
make: *** [drivers] 오류 2

$ vi drivers/media/.built-in.o.cmd  // compile되어 만들어지는 build-in.o를 다시 분석  (video 가 dm8168로 인식)

$ find . -name plat   //             plat/cpu.h 찾아 설정이 제대로 있는지 확인 
./drivers/dsp/syslink/omap_notify/plat
./arch/arm/plat-pxa/include/plat
./arch/arm/plat-s5p/include/plat
./arch/arm/plat-versatile/include/plat
./arch/arm/plat-samsung/include/plat
./arch/arm/plat-omap/include/plat
./arch/arm/plat-nomadik/include/plat
./arch/arm/plat-spear/include/plat
./arch/arm/plat-s3c24xx/include/plat
./arch/arm/plat-orion/include/plat


$ vi ./arch/arm/mach-omap2/ti81xx_vpss.c 

$ vi ./arch/arm/mach-omap2/devices.c

$ vi arch/arm/mach-omap2/board-flash.c

  • 문제점 분석 및 해결
아래와 같이 빌드된 된 source만 찾아 grep으로 이를 검색

$ find . -name '*.o' | sed -e 's/o$/c/g' | xargs grep -rs omap_mux_init

  http://ahyuo79.blogspot.com/search?q=xargs

상위문제 Linux Kernel 사용이 되는 필요없는 Config를 제거하여 문제해결

현재 나의 Board가 EVM이 아니기 때문에 Kernel config를 점검해가면서 수정해서
필요 없는 부분을 제거하고 변경하고 TEST 하자.

3.2 NAND 변경시 관련설정

Device Drivers -> Memory Technology Devices

  http://processors.wiki.ti.com/index.php/Flash_configuration_in_the_Kernel#Enabling_NAND_Support
  http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/p/177166/641847#641847

7/31/2016

ARM을 사용하는 대표적인 CPU

ARM을 사용하는 대표적인 SOC 

  • EXYNOS Series
ODRIOD 와 삼성에서 사용되는 핸드폰 및 기타 에서 주로 사용되며, 나도 이 SOC는 직접 사용해본 것은 ODROID로 구입하여  나의 장난감으로만 사용했다.  
오랜전에 삼성 TI BSP 기술지원할때, 잠시 보기만 했으며, 그때 당시에는 너무 신기할 따름이였다. 


  • OMAP 과 Davinci Series (DMx)
국내 TI 3rd party 및 외국 TI 3rd party를 비롯하여 TI 관련회사에서 근무하면서 많이 가장 많이 접해본  SoC 혹은 AP이며, 역사 또한 너무나 잘안다.
TI 3rd party 회사부터 시작하여 TI가 처음 Linux Driver 제공하지 않았을 때부터 개발했기에, 관련사항을 많이 접해봤으며, 익숙하게 잘 알고 있다.
OMAP도 모바일 사업을 오래전으로 접었다.
  https://ko.wikipedia.org/wiki/OMAP


  • Snapdragon
나의 경우는 접해보지 못한 CPU이며, 모바일에서 가장 많이 사용하기에 간략하게 소개하며, 아래의 링크를 참조하자.
LG는 핸드폰 개발에서 어쩔수 없이 사용하며, 삼성은 2개 AP 기반으로 가져가고 있다.
  https://ko.wikipedia.org/wiki/%EC%8A%A4%EB%83%85%EB%93%9C%EB%9E%98%EA%B3%A4


  • Tegra
최근 EVM (Jetson TK-1) 을 가지고 논 SoC or AP이며 NVIDIA에서 제공하는 이름은 Tegra이다.
참고로, NVIDIA는 Tegra로 모바일 AP 사업을 진행했지만, TI보다 일찍 사업접었다. 
이때 인수한 회사가 영국의 아이세라 Baseband Chip회사이며, 인수 후 국내에서 모바일사업을 잠시 진행했는데, 잘되지 않았다.

TI를 비롯하여 많은 Chip 제조사가 GPU로 사용 
이매지네이션 테크놀로지의 PowerVR Series.

8/11/2015

Device Tree 기본설명 및 문법, 부팅방법 (AM437x,AM335x)

1. Device Tree 의 기본구성

Device Tree에서 사용되어지는 기본 용어들을 알아두자.
  • DTB : Deivce Tree Blob (DTC에 의해  DTS를 Compile하면 생성되는 파일) 
  • DTC:  Device Tree Compiler 
  • DTS :  Device Tree Syntax  
  • DTSI : Device Tree Syntax Include 

개발자는  DTS와 DTSI를 이용하여 Driver 설정 (HW 설정)구성 한 후 이를 DTC로 Compile 후 이를  DTB 형태로 사용하면 된다 

DTB를 적용하기 위해서는 Kernel에서도 .config에서도 적용이 되게 설정을 해야한다. 

최근에 사이트를 방문하니, Spec이 만들어져 있어 아래 부분을 링크

  http://www.devicetree.org/specifications/


1.1 DTS(Device Tree Source) 기본문법 

Device Tree는 현재 문법이 조금씩 다른것 같으며, 표준화가 진행이 되는 것 같으며,
이를 아래의 사이트에서 Version에 맞게 사용해야 할 것 같다.
하지만 각 Chip Vendor마다 조금씩 다르므로 각각의 Datasheet를 보고 파악을하는 것이 나을 것 같다.
다만 기본문법만  아래의 링크들을 보고 알아두자

  • Device Tree Spec 
 현재 이곳에서 인터넷에서 기재되고, 이곳에서 Device Tree를 관리한다.
  https://www.devicetree.org

  • Ubuntu 에서 ARM Device 를 위하여 Device Tree를 사용 할 경우 
  https://wiki.ubuntu.com/Kernel/Dev/ARMDeviceTrees?action=show&redirect=KernelTeam%2FARMDeviceTrees

  • Device Tree 사용법 ( Spec 및 관련문서 중요)
  https://www.kernel.org/doc/Documentation/devicetree/usage-model.txt
  http://www.devicetree.org/Device_Tree_Usage
  http://www.devicetree.org/specifications/

  • 현재 Device Tree의 적용되는 예
  https://en.wikipedia.org/wiki/Device_tree
  http://omappedia.org/wiki/Device_Tree     (TI)

  • Device Tree 사용법 소개
  http://elinux.org/Device_Tree
  http://elinux.org/Linux_Drivers_Device_Tree_Guide


1.2 DTS/DTSI(Device Tree Source)  위치확인  

이제 본인의 Kernel로 가서 아래와 같이 DTS의 위치를 확인하고, ARM64 or ARM32를 본인 CPU로 확인 후, 이제 본격적으로 자신의 DTS를 찾아보자.
빌드를 하면 본인의 dtb가 생성되므로 이 기준으로 찾아도 좋다

$ find . -name dts  // DTS 관련부분 전부 검색  
./arch/xtensa/boot/dts
./arch/arc/boot/dts
./arch/arm/boot/dts
./arch/arm64/boot/dts
./arch/nios2/boot/dts
./arch/powerpc/boot/dts
./arch/c6x/boot/dts
./arch/metag/boot/dts
./arch/mips/boot/dts
./arch/openrisc/boot/dts
./arch/cris/boot/dts
./arch/h8300/boot/dts
./arch/microblaze/boot/dts

  • DTS 와 DTSI 
Kernel의 arch/x/boot/dts에  DTS와 DTSI파일들이 존재하며, 이 파일로 설정이 가능하다.
DTS는 C언어 처럼 include가 가능하여, DTSI를 사용한다.

    arch/arm/boot/dts/
    arch/powerpc/boot/dts/


1.3 DTC(Device Tree Compiler) 위치확인 

DTC는 kernel에서 빌드되며 아래와 같이 Version이 존재하고, 관련 Source도 Kernel 내부에 존재한다.
  1. DTC의 빌드      : Kernel Config의  CONFIG_DTC=y 추가 
  2. DTC 의 Source :  ./script/dtc 


$ find . -name dtc   // Complier 확인 
./scripts/dtc        // dtc parser and lexer 및 기타소스 확인   
./scripts/dtc/dtc    // dtc bin 


$ cd ./scripts/dtc 
$ ./dtc -v
Version: DTC 1.4.1-g9d3649bd   // DTC Version 확인 


2. Device Tree를 이용한 Kernel Boot

우선 기존의 Kernel Image Boot 와 과 Device Tree를 이용한 Kernel Image을 비교하고, Device Tree를 이용할 경우 DTB 전달방법을 알아보자.


2.1 Kernel Image 비교

Bootloadr에서 DTB(Device Tree Blob)파일을 load 한 후 이를 Kernel로 넘겨주고, 이는 기존의 Kernel의 board-*.c를 대체하고 기존에 사용하던 
platform_device_registraition 방식을 제거를 하고 이 DTB를 사용하여 동적으로 변경한다.


  • uImage의  Old style 과 New Style 비교 

 
http://www.elinux.org/images/a/ad/Arm-soc-checklist.pdf


  • 3가지 모델로 제안하여 DTB도 두가지방식 
  1. OLD Style: 기존방식 MACHINE IDMACHINE_START/END 사용 
  2. 1stNew Style: DTB와 uImage 분리되며, U-BOOT에서 uImage 와 DTB 주소 전달
  3. 2ndNew Style: uImage 와 DTB File을 포함  (Uboot에서 DTB를 전달필요없음)



  • Kernel Image는 uImage or zImage로도 가능
  1. vmlinux : linux kernel의 ELF format으로 실행가능한 kernel이며 기본적인 kernel 
  2. image  : vmlinux 기반에서 objcopy에서 -O binary -R .comment -S 
  3. zImage : vmlinux기반에서 linkscript 기반으로 piggy 및 head 와 gzip 등을 포함한 Kernel Image 
  4. uImage : zImage 기반으로 작성되며 uboot용으로 변경 


$ cd board-support/linux*  //kernel source 이동
$ cd arch/arm/boot
$ ls -a
.Image.cmd  .gitignore  .zImage.cmd  Image  Makefile  bootp  compressed  dts  install.sh  zImage

$ cat .Image.cmd   // Image 만들어지는 방법 
cmd_arch/arm/boot/Image := /home/jhlee/am437x/works/linux-devkit/sysroots/i686-arago-linux/usr/bin/arm-linux-gnueabihf-objcopy -O binary -R .comment -S  vmlinux arch/arm/boot/Image

$ cat .zImage.cmd  // zImage 만들어지는 방법 
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

$ cd compressed
$ ls 
Makefile        big-endian.S  decompress.o  fdt_ro.o   head-sa1100.S    head.o       libfdt.h           misc.o          piggy.lz4.S     sdhi-shmobile.c  vmlinux.lds
ashldi3.S       bswapsdi2.S   fdt.c         fdt_rw.c   head-sharpsl.S   hyp-stub.S   libfdt_env.h       mmcif-sh7372.c  piggy.lzma.S    sdhi-shmobile.h  vmlinux.lds.in
ashldi3.o       bswapsdi2.o   fdt.h         fdt_rw.o   head-shmobile.S  hyp-stub.o   libfdt_internal.h  piggy.gzip      piggy.lzo.S     string.c
atags_to_fdt.c  debug.S       fdt.o         fdt_wip.c  head-xscale.S    lib1funcs.S  ll_char_wr.S       piggy.gzip.S    piggy.xzkern.S  string.o
atags_to_fdt.o  decompress.c  fdt_ro.c      fdt_wip.o  head.S           lib1funcs.o  misc.c             piggy.gzip.o    sdhi-sh7372.c   vmlinux


  • Kernel Image 구조 
  https://en.wikipedia.org/wiki/Vmlinux
  https://wiki.kldp.org/KoreanDoc/html/EmbeddedKernel-KLDP/kernel-image-file-structure.html


  • AM437x EVM Kernel Config 설정 

$ vi .config  //AM437x Kernel config  
....
CONFIG_DTC=y
CONFIG_OF=y

#
# Device Tree and Open Firmware support
#
CONFIG_PROC_DEVICETREE=y
# CONFIG_OF_SELFTEST is not set
CONFIG_OF_FLATTREE=y
CONFIG_OF_EARLY_FLATTREE=y
.....

#
# Boot options
#
CONFIG_USE_OF=y
CONFIG_ATAGS=y
# CONFIG_DEPRECATED_PARAM_STRUCT is not set
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
CONFIG_CMDLINE_FROM_BOOTLOADER=y
# CONFIG_CMDLINE_EXTEND is not set
# CONFIG_CMDLINE_FORCE is not set
CONFIG_KEXEC=y
CONFIG_ATAGS_PROC=y
# CONFIG_CRASH_DUMP is not set
CONFIG_AUTO_ZRELADDR=y


Kernel의 설정에 따라 전달방식은 두가지 설정
(CONFIG_ARM_APPENDED_DTB 와 ATAG)


  • 아래의 ARM 파트와 DT 전달방식을 확인
  아래의사이트에 너무자세하게 나와있다.
  http://lxr.free-electrons.com/source/Documentation/devicetree/booting-without-of.txt

  • DTC 생성 
    CONFIG_DTC=y 에 의해 ./script/dtc/dtc가 생성이 된다.

  • DTB Data를 전달하는 두가지 방식 
  1. uImage와 DTB를 합쳐서 설정하는 방식  
  2. DTB 와 uImage를 분리하며, uboot에서 이를 전달하는 방식 (3.1/2/3 설명 )  

2.2 Kernel설정 (1st New Style)

DTB와 Kernel이 분리된 경우 사용하며, 문서에도 보면 이부분을 선호하며, UBOOT에서 동적으로 맘대로 DTB만 변경만 하면 되기 때문에 편할 것으로 보인다.
2nd New Style 부분은 uImage와 DTB를 합치는 것이며 별도의 Kernel 설정이 필요하며 이부분은 생략

  • ATAGS 사용 및 소개 
UBOOT에서 Kernel에게 Taglist 를 전달해주는 개념이며, 이 Taglist에 받아 Kernel이 이를 사용한다.
Device Tree가 나오기전의 개념이며, 이것 단독으로 Device Tree를 사용할 수 없지만,이를 Device Tree에 적용하여 사용이 가능하다.


  • Kernel Config 설정
  1. CONFIG_ATAGS      //ATAGS 사용하여 TAG LIST로 받음 
  2. CONFIG_ARM_ATAG_DTB_COMPAT // TAG LIST에서 DTB를 받아 호환 
  3. CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER // TAG LIST DTB 포함 
  4. CONFIG_ARM_APPENDED_DTB // DTB가 Kernel Image에 포함
  5. CONFIG_ATAGS_PROC // ATGAS PROC 정보 


2.3 UBOOT의 Kernel DTB 전달과정 (1st New Style)


 A. UBOOT에서 KERNEL 의 ATAGS의 TAGLIST 전달방식

아래와 같이 ATAGS 기능 사용할 경우 전달 방식이 변경이 된다.r2에 Taglist를 전달해준다.
ATAGS 방식은 기존부터 존재하던 방식으로 ATAGS에 다양한 정보를 넣어 전달가능.
http://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf
       
B. 상위 ATAGS의 TAGLIST 미사용하고 DTB 주소설정

DTB를 전달할 경우, 아래와 같이 R2에 DTB의 주소를 넣어서 전달

http://events.linuxfoundation.org/sites/events/files/slides/petazzoni-device-tree-dummies.pdf


3. UBOOT의 Kernel DTB 전달방식 (1st New Style)

  • UBOOT 의 Kernel 의 DTB 전달 방식  (ATAG 사용)
bootm 은 uImage를 사용할이며, bootz는 zImage 사용할때이다.
앞에 kernel의 이미지를 address 주고  "-" 함께  dtb file address 주소를 준다.

$ bootm ${loadaddr} - ${fdtaddr} 
$ bootz ${loadaddr} - ${fdtaddr}


  • ATAGS 미사용과 Device Tree Mapping된 경우 전달형태

 CPU register contents
       r0 = 0
       r1 = Linux SOC family DT machine number  (Machine ID)
            (as defined in the ARM Linux machine database). 
            Unlike legacy ATAG booting, there is one unique ID is per SOC family not per machine.
       r2 = Physical address of FDT blob in system RAM

   
Kernel 소스 :
  arch/arm/kernel/atags_parse.c
  arch/arm/boot/compressed/atags_to_fdt.c

관련링크
  http://devicetree.org/Boot_Environment    ( Mapping 반드시 참조 )

Machine ID 와 ATAG 관련설명
  http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html (ATAG)
  http://devicetree.org/BootingLinuxOnArm  ( Booting 과정 설정)
  http://stackoverflow.com/questions/21014920/arm-linux-atags-vs-device-tree  (ATAGS , DT차이)
  https://www.kernel.org/doc/Documentation/arm/Booting (BOOTing 과정 설명)


4. Device Tree 사용한 Kernel 분석 

  • AM437x/AM335x일 경우,
Linux Kernel Image는 DTB파일은 받아 이 설정값 기준으로 각각의 Device Driver를 설정을 하게된다.
다만 주의해야할 것은 Kernel Config에서 관련설정을 해야한다.

이제 EVM Board에 관련설정은 board-generic.c  DTB로 변경하여 설정하게 되므로, 동작방식을 아래의 Kernel 소스에서 부터 확인해볼 필요가 있다.

  • Kernel config 확인
$ vi .config //AM437x 일 경우
...
#
# OMAP Feature Selections
#
CONFIG_OMAP_RESET_CLOCKS=y
CONFIG_OMAP_MUX=y
CONFIG_OMAP_MUX_DEBUG=y
CONFIG_OMAP_MUX_WARNINGS=y
CONFIG_OMAP_32K_TIMER=y
CONFIG_OMAP_DM_TIMER=y
CONFIG_OMAP_PM_NOOP=y
CONFIG_MACH_OMAP_GENERIC=y
CONFIG_ARCH_OMAP=y
# CONFIG_ARCH_OMAP3 is not set
# CONFIG_ARCH_OMAP4 is not set
# CONFIG_SOC_OMAP5 is not set
# CONFIG_SOC_AM33XX is not set
CONFIG_SOC_AM43XX=y
# CONFIG_SOC_DRA7XX is not set
CONFIG_ARCH_OMAP2PLUS=y
....

$ vi .config   //AM335x 일 경우 
...
#
# TI OMAP/AM/DM/DRA Family
#
# CONFIG_ARCH_OMAP3 is not set
# CONFIG_ARCH_OMAP4 is not set
# CONFIG_SOC_OMAP5 is not set
CONFIG_SOC_AM33XX=y
# CONFIG_SOC_AM43XX is not set
# CONFIG_SOC_DRA7XX is not set
CONFIG_ARCH_OMAP2PLUS=y
...


  • DT_MACHINE_START 확인
기존에 사용하던 MACHINE_START 대신 Device Tree는 DT_MACHINE_START를 사용하므로 관련부분 확인

$ grep -r DT_MACHINE_START ./arch/arm/mach-omap2/ // 본인 보드의 Board_init을 찾는다. DT_MACHINE_START
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(OMAP242X_DT, "Generic OMAP2420 (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(OMAP243X_DT, "Generic OMAP2430 (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(OMAP3_N900_DT, "Nokia RX-51 board")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(OMAP3_DT, "Generic OMAP3 (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(OMAP36XX_DT, "Generic OMAP36xx (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(OMAP3_GP_DT, "Generic OMAP3-GP (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(AM3517_DT, "Generic AM3517 (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(TI814X_DT, "Generic ti814x (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(TI816X_DT, "Generic ti816x (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(OMAP5_DT, "Generic OMAP5 (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(DRA74X_DT, "Generic DRA74X (Flattened Device Tree)")
./arch/arm/mach-omap2/board-generic.c:DT_MACHINE_START(DRA72X_DT, "Generic DRA72X (Flattened Device Tree)")


$ vi ./arch/arm/mach-omap2/board-generic.c
.....
#ifdef CONFIG_SOC_AM43XX
static const char *const am43_boards_compat[] __initconst = {
    "ti,am4372",
    "ti,am43",
    NULL,
};

DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
    .l2c_aux_val    = OMAP_L2C_AUX_CTRL,
    .l2c_aux_mask   = 0xcf9fffff,
    .l2c_write_sec  = omap4_l2c310_write_sec,
    .map_io     = am33xx_map_io,                  // vi ./arch/arm/mach-omap2/io.c
    .init_early = am43xx_init_early,              // vi ./arch/arm/mach-omap2/io.c
    .init_late  = am43xx_init_late,               // vi ./arch/arm/mach-omap2/io.c
    .init_irq   = omap_gic_of_init,               // vi ./arch/arm/mach-omap2/omap4-common.c
    .init_machine   = omap_generic_init,          // vi ./arch/arm/mach-omap1/board-generic.c
    .init_time  = omap3_gptimer_timer_init,       // vi ./arch/arm/mach-omap2/timer.c 
    .dt_compat  = am43_boards_compat,             // 위에 정의  
    .restart    = omap44xx_restart,               // vi ./arch/arm/mach-omap2/omap4-restart.c
MACHINE_END
#endif
.......
$ vi ./arch/arm/mach-omap2/board-generic.c   // 본인 보드의 설정을 확인하자 machine_desc 내용, 이 부분은 동적으로 설정이 되기때문에 찾아봐도 존재하지 않는다. 
....
#ifdef CONFIG_SOC_AM33XX
static const char *const am33xx_boards_compat[] __initconst = {
    "ti,am33xx",
    NULL,
};

DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
    .reserve    = omap_reserve,
    .map_io     = am33xx_map_io,           // vi ./arch/arm/mach-omap2/io.c 
    .init_early = am33xx_init_early,       // vi ./arch/arm/mach-omap2/io.c 
    .init_machine   = omap_generic_init,   // vi ./arch/arm/mach-omap1/board-generic.c
    .init_late  = am33xx_init_late,        // vi ./arch/arm/mach-omap2/io.c 
    .init_time  = omap3_gptimer_timer_init, // vi ./arch/arm/mach-omap2/timer.c
    .dt_compat  = am33xx_boards_compat,     // 위에 정의 
    .restart    = am33xx_restart,           // vi ./arch/arm/mach-omap2/am33xx-restart.c
MACHINE_END
#endif
.....


  • Kernel 의 Linker Script 분석


$ vi arch/arm/kernel/vmlinux.lds   //kernel의 linkscript (AM43xx)
.......

 .init.arch.info : {              //MACHINE_START or DT_MACHIN_START
  __arch_info_begin = .;
  *(.arch.info.init)
  __arch_info_end = .;           //MACHINED_END
 }
 .init.tagtable : {              //ATAGS
  __tagtable_begin = .;     
  *(.taglist.init)
  __tagtable_end = .;
 }
 .init.pv_table : {              // phy to virtual , 이것은 이곳의 범위에 상관이 없어 넘어감
  __pv_table_begin = .;
  *(.pv_table)
  __pv_table_end = .;
 }
 .init.data : {
  *(.init.data) *(.meminit.data) *(.init.rodata) *(.meminit.rodata) . = ALIGN(8); __clk_of_table = .; *(__clk_of_table) *(__clk_of_table_end) . = ALIGN(8); __reservedmem_of_table = .; *(__reservedmem_of_table) *(__reservedmem_of_table_end) . = ALIGN(8); __clksrc_of_table = .; *(__clksrc_of_table) *(__clksrc_of_table_end) . = ALIGN(32); __dtb_start = .; *(.dtb.init.rodata) __dtb_end = .; . = ALIGN(8); __irqchip_begin = .; *(__irqchip_of_table) *(__irqchip_of_end)
  . = ALIGN(16); __setup_start = .; *(.init.setup) __setup_end = .;
  __initcall_start = .; *(.initcallearly.init) __initcall0_start = .; *(.initcall0.init) *(.initcall0s.init) __initcall1_start = .; *(.initcall1.init) *(.initcall1s.init) __initcall2_start = .; *(.initcall2.init) *(.initcall2s.init) __initcall3_start = .; *(.initcall3.init) *(.initcall3s.init) __initcall4_start = .; *(.initcall4.init) *(.initcall4s.init) __initcall5_start = .; *(.initcall5.init) *(.initcall5s.init) __initcallrootfs_start = .; *(.initcallrootfs.init) *(.initcallrootfss.init) __initcall6_start = .; *(.initcall6.init) *(.initcall6s.init) __initcall7_start = .; *(.initcall7.init) *(.initcall7s.init) __initcall_end = .;
  __con_initcall_start = .; *(.con_initcall.init) __con_initcall_end = .;
  __security_initcall_start = .; *(.security_initcall.init) __security_initcall_end = .;
  . = ALIGN(4); __initramfs_start = .; *(.init.ramfs) . = ALIGN(8); *(.init.ramfs.info)
 }
 .exit.data : {
  *(.exit.data) *(.memexit.data) *(.memexit.rodata)
 }
 __init_end = .;
....

$ vi arch/arm/kernel/vmlinux.lds   //kernel의 linkscript (AM33xx)
.......

 .init.arch.info : {              //MACHINE_START or DT_MACHIN_START
  __arch_info_begin = .;
  *(.arch.info.init)
  __arch_info_end = .;           //MACHINED_END
 }
 .init.tagtable : {              //ATAGS
  __tagtable_begin = .;     
  *(.taglist.init)
  __tagtable_end = .;
 }
 .init.pv_table : {              // phy to virtual , 이것은 이곳의 범위에 상관이 없어 넘어감
  __pv_table_begin = .;
  *(.pv_table)
  __pv_table_end = .;
 }
....


$ vi System.map   // AM43xx

c0813594 T __arch_info_begin
c0813594 t __mach_desc_GENERIC_DT.20839
c0813594 T __proc_info_end
c08135ec t __mach_desc_AM43_DT
c0813644 T __arch_info_end
c0813644 T __tagtable_begin
c0813644 t __tagtable_parse_tag_cmdline
c081364c t __tagtable_parse_tag_revision
c0813654 t __tagtable_parse_tag_serialnr
c081365c t __tagtable_parse_tag_ramdisk
c0813664 t __tagtable_parse_tag_videotext
c081366c t __tagtable_parse_tag_mem32
c0813674 t __tagtable_parse_tag_core
c081367c t __tagtable_parse_tag_initrd2
c0813684 t __tagtable_parse_tag_initrd
c081368c T __pv_table_begin
c081368c T __tagtable_end
c0813a70 T __pv_table_end
......

$ vi System.map   // 각 함수 확인 (AM33xx)
c09924e4 T __arch_info_begin
c09924e4 t __mach_desc_GENERIC_DT.24345
c09924e4 T __proc_info_end
c099254c t __mach_desc_AM33XX_DT
c09925b4 T __arch_info_end
c09925b4 T __tagtable_begin              // tagslist 에 들어가는 정보들  
c09925b4 t __tagtable_parse_tag_cmdline     // cmdline
c09925bc t __tagtable_parse_tag_revision    // revision 
c09925c4 t __tagtable_parse_tag_serialnr
c09925cc t __tagtable_parse_tag_videotext
c09925d4 t __tagtable_parse_tag_mem32
c09925dc t __tagtable_parse_tag_core
c09925e4 t __tagtable_parse_tag_initrd2
c09925ec t __tagtable_parse_tag_initrd
c09925f4 T __pv_table_begin
c09925f4 T __tagtable_end
c09927bc T __pv_table_end
....


  • MACHINE_START/END 와 DT_MACHINE_START
위에서 설명했듯이 위 두기능는 동일하며, machine_desc를 Device Tree를 사용하냐 Old Style이냐 따라 보면되겠다.

$ vi arch/arm/include/asm/mach/arch.h  

struct machine_desc {
    unsigned int        nr;     /* architecture number  */
    const char      *name;      /* architecture name    */
    unsigned long       atag_offset;    /* tagged list (relative) */
    const char *const   *dt_compat; /* array of device tree
                         * 'compatible' strings */

    unsigned int        nr_irqs;    /* number of IRQs */

#ifdef CONFIG_ZONE_DMA
    phys_addr_t     dma_zone_size;  /* size of DMA-able area */
#endif

    unsigned int        video_start;    /* start of video RAM   */
    unsigned int        video_end;  /* end of video RAM */

    unsigned char       reserve_lp0 :1; /* never has lp0    */
    unsigned char       reserve_lp1 :1; /* never has lp1    */
    unsigned char       reserve_lp2 :1; /* never has lp2    */
    enum reboot_mode    reboot_mode;    /* default restart mode */
    unsigned        l2c_aux_val;    /* L2 cache aux value   */
    unsigned        l2c_aux_mask;   /* L2 cache aux mask    */
    void            (*l2c_write_sec)(unsigned long, unsigned);
    const struct smp_operations *smp;   /* SMP operations   */
    bool            (*smp_init)(void);
    void            (*fixup)(struct tag *, char **);
    void            (*dt_fixup)(void);
    long long       (*pv_fixup)(void);
    void            (*reserve)(void);/* reserve mem blocks  */
    void            (*map_io)(void);/* IO mapping function  */
    void            (*init_early)(void);
    void            (*init_irq)(void);
    void            (*init_time)(void);
    void            (*init_machine)(void);
    void            (*init_late)(void);
#ifdef CONFIG_MULTI_IRQ_HANDLER
    void            (*handle_irq)(struct pt_regs *);
#endif
    void            (*restart)(enum reboot_mode, const char *);
};






#define MACHINE_START(_type,_name)          \
static const struct machine_desc __mach_desc_##_type    \
 __used                         \
 __attribute__((__section__(".arch.info.init"))) = {    \
    .nr     = MACH_TYPE_##_type,        \
    .name       = _name,

#define MACHINE_END             \
};

#define DT_MACHINE_START(_name, _namestr)       \
static const struct machine_desc __mach_desc_##_name    \
 __used                         \
 __attribute__((__section__(".arch.info.init"))) = {    \
    .nr     = ~0,               \
    .name       = _namestr,

#endif

  • Kernel config
아래와 같이 ATAGS와 관련있는 파일을 확인

$ vi .config 
....
CONFIG_ATAGS=y                 # arch/arm/kernel/atags_parse.c
...
CONFIG_ARM_APPENDED_DTB=y
CONFIG_ARM_ATAG_DTB_COMPAT=y   # arch/arm/boot/compressed/atags_to_fdt.c
CONFIG_ATAGS_PROC=y            # arch/arm/kernel/atags_proc.c
CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
....


각 옵션에 대해 간단히 알아보자.
  1. CONFIG_ATAGS=y
  2. CONFIG_ARM_ATAG_DTB_COMPAT=y
  3. CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y

상위에서 ATAG는 DTB를 받기위한 한 통로이며, 물론 다르게 구성하여 확장도 가능하겠지만 현재는 그렇게 동작되지는 않는다.

ATAGS의 주소는 U-BOOT에서 FDT(Flattened Device Tree)라는 주소로 이를 받고, uImage와 DTB는 결합이 될 것이다.

  https://www.denx.de/wiki/DULG/UBootCmdFDT



  • Kernel에서 Machine ID 확인 
아래와 같이 arch/arm/tools/mach-types에서 확인가능

$ vi arch/arm/tools/mach-types
#
# machine_is_xxx        CONFIG_xxxx             MACH_TYPE_xxx           number
#
....
omap_generic            MACH_OMAP_GENERIC       OMAP_GENERIC            452
...
$ vi .config
....
CONFIG_MACH_OMAP_GENERIC=y   # 상위와 동일 
CONFIG_ARCH_OMAP=y
...


4.1 U-Boot 와 Kernel의 DTS 위치 및 호환성 ( DTB 공유)

Device Tree도 문법은 지속적으로 변경되겠지만, 최근 TI의 Sitara것을 보면 아래와 같이 AM335x의 경우 DTS File이 Kernel과 U-BOOT가 같이 존재하며 내용도 동일하다.
만약 UBOOT의 내용과 Kernel의 내용이 맞지 않는다면, 둘중 하나를 선택해서 사용해야할 것 같다

UBOOT or KERNEL의 DTS는 반드시 DTC가 존재해야 하며, Uboot도 DTB를 공유되어 사용되어진다.

보통 1st Boot Loader가 존재하며, 2nd Boot Loader (UBoot)를 사용하므로 DTB 역시 UBoot 와 Kernel 에서도 동일하게 사용하기 위해서 공유가 되어져야 할 것이다.

  • Devcie Tree의 Booting 방법 (참조)
처음에는 알지 못했는데, Kernel 뿐만 아니라 Uboot에도 DTB를 적용하여 이를 공유해 사용하면 될 것 같다.
  https://ahyuo79.blogspot.com/2015/08/am437x-kernel-device-tree.html

Uboot의 FDT Command
  https://www.denx.de/wiki/view/DULG/UBootCmdFDT

  • U-BOOT에서 Device Tree 위치 
$ cd board-support
$ cd u-boot*  // Uboot Source 로 이동 

$ ls arch/arm/dts // Uboot 용 Device Tree Syntax (Kernel과 동일)
-rw-r--r--  1 jhlee jhlee  9346 12월 15 09:05 am335x-bone-common.dtsi
-rw-rw-r--  1 jhlee jhlee 30487  3월 14 14:30 am335x-bone.dtb
-rw-r--r--  1 jhlee jhlee   618 12월 15 09:05 am335x-bone.dts
-rw-rw-r--  1 jhlee jhlee 31186  3월 14 14:30 am335x-boneblack.dtb
-rw-r--r--  1 jhlee jhlee  3377 12월 15 09:05 am335x-boneblack.dts
-rw-rw-r--  1 jhlee jhlee 30818  3월 14 14:30 am335x-bonegreen.dtb
-rw-r--r--  1 jhlee jhlee  1184 12월 15 09:05 am335x-bonegreen.dts
-rw-rw-r--  1 jhlee jhlee 36854  3월 14 14:30 am335x-evm.dtb
-rw-r--r--  1 jhlee jhlee 19058 12월 15 09:05 am335x-evm.dts
-rw-rw-r--  1 jhlee jhlee 35799  3월 14 14:30 am335x-evmsk.dtb
-rw-r--r--  1 jhlee jhlee 20720 12월 15 09:05 am335x-evmsk.dts
-rw-rw-r--  1 jhlee jhlee 31726  3월 14 14:30 am335x-icev2.dtb
-rw-r--r--  1 jhlee jhlee 10299 12월 15 09:05 am335x-icev2.dts
-rw-r--r--  1 jhlee jhlee 13955 12월 15 09:05 am33xx-clocks.dtsi
-rw-r--r--  1 jhlee jhlee 20273 12월 15 09:05 am33xx.dtsi
-rw-r--r--  1 jhlee jhlee 24483 12월 15 09:05 am4372.dtsi
-rw-r--r--  1 jhlee jhlee 22179 12월 15 09:05 am437x-gp-evm.dts
-rw-r--r--  1 jhlee jhlee 10493 12월 15 09:05 am437x-idk-evm.dts
-rw-r--r--  1 jhlee jhlee 17847 12월 15 09:05 am437x-sk-evm.dts
-rw-r--r--  1 jhlee jhlee 21643 12월 15 09:05 am43x-epos-evm.dts
-rw-r--r--  1 jhlee jhlee 16774 12월 15 09:05 am43xx-clocks.dtsi
-rw-r--r--  1 jhlee jhlee  6797 12월 15 09:05 am571x-idk.dts
-rw-r--r--  1 jhlee jhlee  7153 12월 15 09:05 am572x-idk.dts
-rw-r--r--  1 jhlee jhlee 20598 12월 15 09:05 am57xx-beagle-x15.dts
-rw-r--r--  1 jhlee jhlee  8073 12월 15 09:05 am57xx-idk-common.dtsi       
....


  • Kernel에서의 Device Tree 위치 
$ cd board-support
$ cd linux*  // Linux Kernel 로 이동 

$ ls arch/arm/boot/dts/
-rw-r--r--  1 jhlee jhlee  9346 12월 15 09:05 am335x-bone-common.dtsi
-rw-rw-r--  1 jhlee jhlee 30487  3월 14 14:30 am335x-bone.dtb
-rw-r--r--  1 jhlee jhlee   618 12월 15 09:05 am335x-bone.dts
-rw-rw-r--  1 jhlee jhlee 31186  3월 14 14:30 am335x-boneblack.dtb
-rw-r--r--  1 jhlee jhlee  3377 12월 15 09:05 am335x-boneblack.dts
-rw-rw-r--  1 jhlee jhlee 30818  3월 14 14:30 am335x-bonegreen.dtb
-rw-r--r--  1 jhlee jhlee  1184 12월 15 09:05 am335x-bonegreen.dts
-rw-rw-r--  1 jhlee jhlee 36854  3월 14 14:30 am335x-evm.dtb
-rw-r--r--  1 jhlee jhlee 19058 12월 15 09:05 am335x-evm.dts
-rw-rw-r--  1 jhlee jhlee 35799  3월 14 14:30 am335x-evmsk.dtb
-rw-r--r--  1 jhlee jhlee 20720 12월 15 09:05 am335x-evmsk.dts
-rw-rw-r--  1 jhlee jhlee 31726  3월 14 14:30 am335x-icev2.dtb
-rw-r--r--  1 jhlee jhlee 10299 12월 15 09:05 am335x-icev2.dts
-rw-r--r--  1 jhlee jhlee 13955 12월 15 09:05 am33xx-clocks.dtsi
-rw-r--r--  1 jhlee jhlee 20273 12월 15 09:05 am33xx.dtsi
-rw-r--r--  1 jhlee jhlee 24483 12월 15 09:05 am4372.dtsi
-rw-r--r--  1 jhlee jhlee 22179 12월 15 09:05 am437x-gp-evm.dts
-rw-r--r--  1 jhlee jhlee 10493 12월 15 09:05 am437x-idk-evm.dts
-rw-r--r--  1 jhlee jhlee 17847 12월 15 09:05 am437x-sk-evm.dts
-rw-r--r--  1 jhlee jhlee 21643 12월 15 09:05 am43x-epos-evm.dts
-rw-r--r--  1 jhlee jhlee 16774 12월 15 09:05 am43xx-clocks.dtsi
-rw-r--r--  1 jhlee jhlee  6797 12월 15 09:05 am571x-idk.dts
-rw-r--r--  1 jhlee jhlee  7153 12월 15 09:05 am572x-idk.dts
-rw-r--r--  1 jhlee jhlee 20598 12월 15 09:05 am57xx-beagle-x15.dts
-rw-r--r--  1 jhlee jhlee  8073 12월 15 09:05 am57xx-idk-common.dtsi       
....

7/10/2015

TI - OMAP-L137,8 (TEST)

1. TI의 OMAP Series 의 역사 

TI의 OMAP의 역사를 간단히 보면 OMAP 1~5까지 나와있다고 한다. 
하지만, 내가 직접 사용해본 OMAP Series는 OMAP2/3/4 와 OMAP-Lx 정도 인것 같다.
OMAP5도 분명을 사용을 했을텐데, 솔직히 OMAP5는 기억이 잘 안난다.^^ 
이유는 TI가 AP사업을 국내에서 철수하기 직전까지 내가 OMAP을 직접 지원하고, 개발하며 다루었기때문에 사용을 안할 수가 없다. 

TI에서 기존의 Davinci Series 보다 좀 더 성능이 좋은 SoC를 만든것이 OMAP이며, TI의 가장 큰 장점인 DSP를 포함하고 있다는 것이다.   
Camera와 Display 및 GPU(Imagination Technologies) 및 Power Management(PMIC,DVFS) 기능을 향상시킨 모델이 OMAP이며,
흔히 AP(Application Processor)라고 한다.

물론 Davinci Series도 DSP를 지원하지만, (저가 모델을 제외) 가장 큰 차이는 GPU의 지원과 각 상위 Peripheral device 세부기능의 성능 향상이 아닐까 생각이 든다.
Display에서 원활한 GUI 환경지원과 Camera 부분을 보면 Davinci Series와 많은 차이를 보여준다.
Camera의 ISP 인 경우 OMAP 내부에 별도의 Core까지 추가하여 연산을 하며, GPU의 지원에다 DSP와 함께 IVA-HD연동되는 복잡성을 보면
Davinci하고는 확연히 다르며 다양한 기능을 HW에서 제공을 해준다.

최근 Davinci Series인 DM8168의 구조를 보면 OMAP의 Booting 및 Kernel 초기화 소스 구조가 OMAP과 유사하게 변경이 되어가는 것 같다. 
  http://processors.wiki.ti.com/index.php/Boot_Sequence

국내에서 OMAP3/4는 모바일폰에 적용이 되었으며, OMAP2의 경우는 내비게이션에서도 많이 이용이 된걸로 기억하고 있다.
왜냐하면, 국내에서 거의 인지니언트 것을 가져다 사용을 했기 때문에 대부분 다 기억한다. 
  https://ko.wikipedia.org/wiki/OMAP
  https://en.wikipedia.org/wiki/OMAP

개인적으로는 너무 아쉬운 AP이며, Exynos가 개인생각으로는 많이 참고하고 구현하지 않았을까 생각한다. 
Exynos를 구조를 보면, OMAP 이 많이 떠오른다. (PowerVR도 동일함)  

위키에서 너무 잘 설명이 되어있으며, 매번 위키에서 새로운것을 배운다.


1.1. OMAP-L137 과 OMAP-L138 비교 

OMAP-Lx은 사실 기존의 OMAP하고 많이 다르며, 기존의 Davinci Series와 거의 유사하다고 봐야 할 것이다.
최근에 테스트 할 일이 있어, 다시 보게되었지만, TI의 이 옛날 EVM이 다시 내게 돌아와서 간단히 비교하고 정리하고자 한다.

이 부분은 일이 아니기에, TEST이므로, 추후 만약 다시 진행 한다면, 그때 다시 정리하고자 한다.



http://www.ti.com/product/OMAP-L138/datasheet


http://www.ti.com/product/OMAP-L137/datasheet


갑자기 OMAP-L137을 알아야 할 일이 있어, OMAP-L137를 보다가, EVM을 L138을 구해
두개를 같이 보게 되었다. SOC의 구조는 거의 흡사하고 주변장치의 갯수나 여부가 조금씩 다른 것 같다.


2. TI SDK


TI도 마찬가지지만, 초창기에는 SoC SDK 비롯한 개념이 거의 없었다.    
내가 TI 3rd Party에 다닐때 만 해도, 이런 SDK(개발환경, Kernel Porting) 부분은 TI 3rd Party들이 만들어서 제공을 해주는 것이지, 
TI가 제공 하는 일이 아니였다.  
물론 TI만 이렇게 변경된 것이 아니라, 다른 칩제조사들도 다 변했다.  
(이 이야기는 몬타비스타 리눅스까지 들어가야하니, 여기서 끝) 
TI가 Davinci를 출시하면서 부터 조금씩 Linux 와 Build 환경 및 개발환경을 점차 확대 지원하기 시작을 하였다.  
 
사실 그전에는 , 임베디드 리눅스를 오래하신분들은 다 아시겠지만, 본인들이 크로스 컴파일러 부터, Linux File System 만들고, 
Linux Kernel 포팅하여 올린 후, 멀티미디어를 하려면, 매번 다른 Frame Buffer기반으로 다 만들어서 동작 시켜야 했다. 

간단한 예를 들면, IXP425 기반에 HPI or PCI 기반으로 TI-DSP를 붙혀서 멀티미디어 동작하게 만들고, 
DSP에서 Codec 역할을 맡기고, IXP425 즉 인텔의 Xcale에는 OSD(Frame Buffer) 와 Video Buffer를 만들어서 이를 돌리고 했다. 
그리고, 이런 솔루션을 만들어서 기업에 팔고 그랬다.   
이렇게 만들어줘도, 이걸 양산을 하는 회사가 있고, 못하는 회사가 많았다. 
이유는 Linux기반으로 양산하는게 초창기에 너무 어려웠기 때문이다. 


2.1 OMAP-L138

TI Linux SDK 
  http://www.ti.com/tool/linuxsdk-omapl138


A. LINUXSDKOMAPL138

문서를 읽어보면, Ubuntu 10.04 LTS 32-bit  에서작업을 했다고 한다고,
현재 내 12.04 버전에서 그리고, 64-bit에서 할 방법이 없는지에 대해서 알아봤는데,
이미 AM437x에서 sudo apt-get install ia32-libs 도 다 설치를 했음에도 불구하고 제대로
동작을 하지 않는다.

처음부분 shell에 대한 에러부분을 해결을 해도 그 다음에, 배포판을 체크에서 넘어가지 않아  설치하지 되지 않는다.

일단, 그래서 OS 다시 설치 하기 귀찮아서, 다음번으로 넘기기로 한다.
  • dvsdk_omapl138-evm_04_03_00_06_setuplinux

B. LINUXSDKOMAPL138-LCDK

이 버전도 역시 Ubuntu 10.04 LTS 권장을 하지만,이 버전이 Kernel version도 3.x되고 최근 버전이고 해서 설치를 해보고, setup.sh를 했지만, 역시 OS를 변경을 해야함.
setup.sh 안에 package-install 존재함
  • ti-sdk-omapl138-lcdk-01.00.00.bz2

* 결론 아직 위 두 SDK는 설치 못해봄, OS 환경을 변경을 해줘야함.


2.2 OMAP-L138 EVM-INFO 


  • OMAP-L138 EVM 제조사 
http://www.logicpd.com/_archived_drupal_site/products/development-kits/zoom-omap-l138-experimenter-kit#tabs-som-2



  • BOOTMODE 
UART BOOT MODE 지원하고, Dvflasher 동일하다 (sfh로 이름이 변경)
http://processors.wiki.ti.com/index.php/Serial_Boot_and_Flash_Loading_Utility_for_OMAP-L138

 http://processors.wiki.ti.com/index.php/Programming_mDDR/DDR2_EMIF_on_OMAP-L1x/C674x



2.2 OMAP-L137


  http://www.ti.com/tool/linuxsdk-omapl137


A. LINUXSDKOMAPL137

일단, MontaVista Linux Pro 5.0을 사용을 하며, Version GA 를 다운을 받아 설치하고 있다.
  • REL_LSP_02_20_00_07.tar.gz

PSP_02_20_00_07/lsp_psp_02_20_00_07_release_notes or
PSP_02_20_00_07/docs 안에 OMAP L-137 User Guide 있으니 쉽게 설치 가능하다.

구조를 보면 아래와 같고 설치를 해보면, Tool Chain과 File system이 없다.
이 부분은 LSP Download 의 Releated Links 가 있는데 이부분에
OMAP-L137 Beta SDK에서 얻을 수 있다길래, 갔는데 Link만 있고 아무것도 없다.


혹시나,해서 LSP2.20 Beta Relese 다시 설치 시도,역시 없다.

  
  ├──PSP_02_20_00_07  
  │      ├──bin      
  │      │    ├──readme.txt
  │      │    ├──.....                // Pre-built Images & CCS Images 
  │      │    └── kernel_modules
  │      │            
  │      ├──docs                       // How To Use it 
  │      ├──board_utilities            // UBL and UBOOT , Flash Writer Source   
  │      │     ├──armubl  
  │      │     ├──dspubl  
  │      │     ├──flash_writers  
  │      │     ├──tools  
  │      │     └── u-boot-1.3.3.tar.gz
  │      ├── examples  
  │      ├── lsp_psp_02_20_00_07_release_notes.html  
  │      ├── psp_software_manifest.html
  │      └── psp_license_agreement.html
  │ 
  └── mvl_5_0_0_demo_lsp_setuplinux_02_20_00_07.bin  // Linux Kernel Source 


  http://processors.wiki.ti.com/index.php/Installing_the_Software_for_OMAP-L137
  http://processors.wiki.ti.com/index.php/Building_The_OMAP-L1_SDK


1/03/2014

Audio-ALSA OMAP Framework

1. OMAP 기본 ALSA 구성 

다음은 OMAP의 기본 ALSA  기본 Framewor이며, 기존 Audio Driver와 다른것이 있다면,HDMI와 확장형 Controler가 많다. 
사실 직접 일했을 때 Source를 분석을 했어야 했는데, 지금 간단히 정리한다.



아래 사이트에 가면 OMAP과 Codec의 설명이 잘 나오며, 기존 Davinchi Series와 차이점이라면, PMIC 사용 및 McPDM지원, HDMI 지원 등이다.
전에는 HDMI 때문에 SiliconImage사의 Chip도 사용을 하고 했는데, OMAP은 편해진것 같다.
OMAP에 대한 Audio관한  HW 정보 및 구성은 아래에서 확인하자.


  • OMAP Audio Framework 및 기본구성정보
http://omappedia.org/wiki/Audio_Drive_Arch


  • ALSA SOC 과 ALSA 부분 Link 
http://omappedia.org/wiki/Audio_Developers_Info


  • Pulse Audio 관련 (아직 사용못해봄)
  https://wiki.archlinux.org/index.php/PulseAudio
  http://omappedia.org/wiki/Ubuntu_PA
  https://www.freedesktop.org/wiki/Software/PulseAudio/

  • OMAP 관련 Audio 전체 설명 (상위 부분 Link)
  http://omappedia.org/wiki/Audio_Drivers_Domain_Wiki


2. OMAP Android Info


  • OMAP Ref
  http://www.ti.com/pdfs/wtbu/OMAP4430_4460_4470_PUBLIC_TRM_Addendum_ABE_HAL_vH.pdf
  http://omappedia.org/wiki/4AI.1.5_OMAP4_ICS_Blaze_AIC_AIC3262_SW_Release3c


  • Android HAL
  http://source.android.com/devices/audio_implement.html


3. OMAP 관련 LINK

  • OMAP 관련부분 Link
  http://omappedia.org/wiki/Linux_OMAP_Kernel_Main

  • OMAP Gstreamer
  http://omappedia.org/wiki/Gstreamer_Project_Main