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

2/27/2020

Yocto 의 Recipe 기본작성방법

1. Yocto 의 Recipe 실행 및 설정 

Yocto에서 recipe가 존재하면, 아래와 같이 bitbake로 실행가능하며, 별도의 task가 존재한다면, -c 옵션을 이용하여 task도 실행가능하다.
그러므로 Yocto에서 원하는 Source를 수정하고 싶다면 반드시 Recipe 수정방법을 이해해야한다.


Yocto 기본문법 과 정리 (필독)
  https://ahyuo79.blogspot.com/2020/01/raspberry-pi3-linux-yocto.html

Yocto Layer 구성방법 과 기본 Recipe 구성  
  https://ahyuo79.blogspot.com/2020/02/yocto-layer-configuration.html

Yocto Partition (WIC) 관리 
  https://ahyuo79.blogspot.com/2020/02/yocto-partition.html


Yocto Uboot/Kernel 수정방법 

Yocto Kernel  Patch (bbappend) 실제예제 



  • bitbake로 각 recipe 를 task 기반으로 실행 예 
//Linux Kernel 설정 이름은 변경됨 
$ bitbake linux-imx  -c menuconfig    // 설정변경
$ bitbake linux-imx  -c diffconfig    //*.cfg 생성 
$ bitbake linux-imx  -c compile -f    // -f force로 강제로 실행 , 일반적으로 빌드되면 재빌드를 안함 
$ bitbake linux-imx  -c deploy

//Uboot 설정, 이름은 변경됨
$ bitbake u-boot-imx 
$ bitbake u-boot-imx -c menuconfig   //설정변경 
$ bitbake u-boot-imx -c diffconfig   // *.cfg
$ bitbake u-boot-imx -c compile -f
$ bitbake u-boot-imx -c deploy 

//busybox 관련설정 
$ bitbake busybox -c menuconfig
$ bitbake busybox -c diffconfig 

-c 는 recipe에서 task 이므로 이부분은 각각의 recipe 확인필요
-f 는 force 로 강제로 실행


  • 많이 사용되어지는 task
  1. config: fetch 된 상태, 즉 소스가 있는 상태에서 configuration 진행 
  2. compile : config 후 compile 진행 
  3. clean / cleanall:  compile 부분 clean
  4. install : rootfs로 install 
  5. deploy: package 배포 

  https://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#ref-tasks

  • bitbake로 최종 Image 생성

//최종이미지 생성 
$ bitbake core-image-base     // core-image-minimal 기반에서 좀 더 원할하게 사용가능한 기본구성 

$ bitbake core-image-minimal  // Booting에 필요한 최소한의 Image 구성

// 이외 기타 , 각 Image 구성은 제조사 혹은 Yocto Version마다 다를 수 있으므로 실제 bbclass 와 같이 확인 
$ bitbake core-image-sato 
$ bitbake core-image-x11 

  https://wiki.yoctoproject.org/wiki/Minimal_Image


  • bitbake 적용중인 변수 값 확인
//bitbake를 이용하여 현재 사용중인 변수확인  
$ bitbake -e | grep ^CONF_VERSION  
CONF_VERSION="1"

$ bitbake -e | grep ^IMAGE  //IMAGE 에 연관된 변수 전체확인  
....

$ bitbake -e | grep ^KERNEL //KERNEL 에 연관된 변수 전체확인  
....

$ bitbake -e | grep ^IMAGE_INSTALL=  -A10//IMAGE_INSTALL  검색후 그다음 10줄 까지 확인   
....

$ bitbake -e | grep ^IMAGE_INSTALL=  -B10//IMAGE_INSTALL  검색후 그이전 10줄 까지 확인   
....

$ bitbake -e | grep ^IMAGE_INSTALL=  -A10 -B10 //IMAGE_INSTALL  검색후 그이전과 이후 총 20줄 모두 확인   
....


Yocto에서 사용되어지는 변수
  https://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#ref-variables-glossary


1.1 Recipe 의 이름설정

Package NamePackage Version을 기록하고, *.bb 와 *.bbappend 작성하며, *.bbappend 주로 확장하는 개념으로 주로 Patch할 때 사용한다.
Yocto에서는 PN의 이름이 동일한 경우 PV가 높은 것을 자동 적용하여 실행한다.
(동일한 recipe가 여러개 존재하여도 PV가 높은것을 자동선택)

${PN}_${PV}.bb
bbexample_0.0.1.bb 
bbexample_0.0.1.bbappend


1.2 Recipe 의 내부기본구성 

  • Recipe의 서술부분
SUMMARY = "SUMMARY  Bitbake Recipe Example"  # 보통 SUMMARY or DESCRIPTION으로 설명 
DESCRIPTION = "DESCIRPTION  Bitbake Recipe Example"
SECTION = "example"              # 생략해도 무방하지만 필요에따라 사용 


  • Receip 에서 LICENSE 사용방법 및 위치파악 
- LICENSE 미사용할 경우
# LICENSE 사용안할 경우 LIC_FILES_CHKSUM  필요없음 
LICENSE = "CLOSED" 

- LICENSE가 Source 안에 있을 경우
# LICENSE 사용할 경우 아래의 File이 Source에 포함되어있음  
LICENSE = "GPLv2"
# COPYING File 과 COPYING의 md5sum 값 (Download 위치의 Source의 Root), 즉 Source에 포함
LIC_FILES_CHKSUM = "file://COPYING;md5=d7810f...." 

- LICENSE가 COMMON_LICENSE_DIR 에 있을 경우
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=3434..."

- bitbake를 이용하여 LICENCE DIR 확인
$ bitbake -e | grep ^COMMON_LICENSE_DIR   //COMMON_LICENSE_DIR 위치파악 

file://의 위치는 ${S}를 기본으로 있는 File
md5는 md5sum의 값

  • 사용할 File들 Remote or Local로 구성 
# 1. remote protocol 로 tar.gz를 download 후 md5sum/sha256sum으로 확인
SRC_URI = "https://github.com/Lora-net/packet_forwarder/archive/v${PV}.tar.gz"  # 확장자 tar.gz로 unpack 자동진행 
SRC_URI[md5sum] = "a1f942e0cc7b02d604b11c8cb5f2a029"
SRC_URI[sha256sum] = "e68fadf6f1d2e5e7b601e504d5efb48b0a8f374c2c29c0476ab2fe9db68d33ae"

# 2. git 의 branch, tag 정보로 download
SRC_URI = "git://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git;protocol=git;branch=name"
SRC_URI = "git://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git;protocol=git;tag=v${PV}"

# 3. git 의 Commit number로 Download
SRC_URI = "git://github.com/DynamicDevices/bbexample.git"
SRCREV = "5c58a861ca31710f6433487b8b0d590a43afd0ad"

#4. Local files에 source에 보관 ${S}에서 찾아서 사용하며 아래 파일은 *.bb 같이존재
SRC_URI = "file://xxxxxxx.tar.gz
SRC_URI = "file://xxxxxxx.patch  
SRC_URI = "file://xxxxxxx.sh 

download의 error를 방지하기위해서 상위와 같이 md5sum 과 sha256sum checksum을 사용

  • 상위 File들을 Build Directory Source 위치 설정 
Build Directory에서 작업을 하는 위치이며, S의 위치는 WORKDIR기준으로 정의

# 1. Git Download 했을 경우 Build Directory의 S의 구성
S = "${WORKDIR}/git"

# 2. tar.gz로 Download 했을 경우, 압축을 풀어 packagename-${PV}
S = "${WORKDIR}/packagename-${PV}"

# 3. file을 직접 사용할경우 local or remote
S = "${WORKDIR}"

상위에서도 에러가 발생한다면, build space에서 상위 WORKDIR를 찾아 직접확인을 해보자.
Debug 방법은 bbplain을 사용해서 환경변수정보를 알아보자.

  https://www.yoctoproject.org/docs/2.7/ref-manual/ref-manual.html#var-TMPDIR

이외 Task 를 비롯하여 Class구성은 실제구성에서 알아보자.

1.3  Recipe 확장구성

  • *.bbappend의 구성 
보통 Patch용으로 사용하거나, 확장하기위해서 사용되어진다.
아래를 설정하지 않아도 기본으로 *.bb파일 기준으로 files에서 찾음

e.g 1
$ cd meta-xxx/.../   // 수정을 원하는 recipe 이동 
$ cat xxx_1.0.1.bb  //recipe 파일 확인 
$ mkdir files
$ vi  xxx_1.0.1.bbappend //patch file 구성 및 cfg 파일 구성 
FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
## update
SRC_URI += "file://001_mypatch.patch"
SRC_URI += "file://002_mypatch.patch"

e.g 2
$ cd meta-xxx/.../     // 수정을 원하는 recipe 이동 
$ cat xxx_1.0.1.bb  //recipe 파일 확인 
$ mkdir v1.0.1
$ vi  xxx_1.0.1.bbappend //patch file 구성 및 cfg 파일 구성 
#*.bb 파일의 PV기준으로 v{PV} directory에서 찾음 
FILESEXTRAPATHS_prepend := "${THISDIR}/v${PV}:"
## update
SRC_URI += "file://001_mypatch.patch"
SRC_URI += "file://002_mypatch.patch"


2. Recipe의 이해와 예제 

Recipe 안에는 Class 와 Task를 이용하여 많은 기능들을 구현이 가능하다.

  • Recipe 의 Class 개념 
Recipe에서는 동일한 기능들을 library 처럼 불러사용이 가능한데, 이를 class라고 하며 구성은 package_name.bbclass file 구성으로 되어있다.
Recipe 안에서 이를 inherit package_name 을 호출을 하면 이 class 기능을 사용가능하다.

inherit systemd  

Yocto Class들의 구성
  https://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#ref-classes
Codename(Warrior)의 Classes
  https://www.yoctoproject.org/docs/2.7/ref-manual/ref-manual.html#ref-classes
Codename (Fido) 의 Classes
  https://www.yoctoproject.org/docs/1.8/ref-manual/ref-manual.html#ref-classes



  • Recipe의 Task 개념
Recipe에서 기본동작은 Task 기반으로 호출이 되어 동작되어지며, 이는 함수와 비슷하다
물론 암묵적으로 Task를 선언하지 않아도 자동으로 규칙에 맞게 실행이 되어진다.
순서를 비롯하여 각각의 기능이 다르므로 각 기능에 맞는 Task를 사용해서 본인이 원하는 기능을 추가해서 넣는다.

## 이 Package가 빌드시 반드시 필요하며 종속적임(중요)
DEPENDS += "libusb1 udev" 

## 일반적으로 CFLAGS or LDFLAGS 상위 libusb 추가 (반드시 스페이스 추가) 
## 가끔세부적인 CFLAGS or LDFLAGS를 위해 세부적인 필요할때  
## TARGET_xxxx    (Target Device)  
## BUILD_xxx      (Build Host , i.e  -native)  
## BUILDSDK_xxx   (Build Host 의 SDK i.e. nativesdk-) 
CFLAGS_append = " -lusb-1.0 "

## CXXFLAGS 정보추가 가능 
## LDFLAGS  정보추가 가능 

## do_compile task 
## Makefile이 존재한다면 do_compile을 생략
## Makefile 이 있을 경우 CFLAGS/LDFLAGS 와 환경변수로 Control이 가능 (상위 DEPENDS 설정) 
## Makefile이 없을 경우 아래와 같이 직접찾아 빌드 
do_compile() {
        ${CC}  -o test main.c ${CFLAGS} ${LDFLAGS} 
}

## do_install task
## 가장 많이 사용할 task로 install이 되는 위치를 정하고 package가 된후 
## 최종으로 자동으로 rootfs에 들어가진다. 
## install 명령어 이외에도 삭제하고싶다면 rm으로 삭제 
do_install() {
        ## install 장소정의 
        install -d ${D}${bindir}
        install -d ${D}${sysconfdir}/systemd/network
        install -d ${D}${systemd_system_unitdir}

        ## 실제 파일 Install 
        install -D -m 0744 ${S}/*.sh ${D}${bindir}
        install -D -m 0744 ${S}/test ${D}${bindir}
} 

Task 역시 prepend or append 로 task 뒤에 추가가능
  1. do_configure(): Configure를 설정을 해줌
  2. do_compile() : 존재하지 않는다면, oe_runmake가 Makefile 찾아 자동 Build 
  3. do_install(): RootFS로 이를 Install 

Yocto 다양한 Task의 구성
상위에 언급한 Task 이외에 다양한 Task가 많이 존재하므로 반드시 확인하자
  https://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#ref-tasks
Codename(Warrior)의 Tasks
  https://www.yoctoproject.org/docs/2.7/ref-manual/ref-manual.html#ref-tasks
Codename (Fido) 의 Tasks
  https://www.yoctoproject.org/docs/1.8/ref-manual/ref-manual.html#ref-tasks


  • Recipe의 각 Task 마다 prepend 와 append 적용
Makefile이 제대로 구현이 되어있다면, do_compile의 필요가 없지만, do_compile_prepend를 이용하여 환경변수 구성을 할 수가 있다.

## 환경변수는 본인이 설정 
do_configure_prepend() {
 export PATH=""
}

## 환경변수는 본인이 설정 
do_compile_prepend() {
 export PATH=""
}

  • Recipe 의 Task do_complie 없애고, Makefile 직접구성 
Simple하게 구성을 해지만 가능하다면 CFLAGS / LDFLAGS를 적용가능하도록 구성하자

$ vi Makefile  
APP_TEST1   := test1 
APP_TEST2   := test2
APP_TEST3   := test3
APP_TEST4   := test4


APP_NAME := $(APP_TEST1) $(APP_TEST2) $(APP_TEST3) $(APP_TEST4) 

ARCH ?=
CROSS_COMPILE ?=

OBJDIR = obj
INCLUDES = $(wildcard inc/*.h)

LIBS_USB := -lusb-1.0 
LIBS_SSL := -lssl -lcrypto
LIBS_PTH := -lpthread 

FILES_LIB := mylib.c mysimplelib.c 

OPT_USB   := $(FILES_LIB) $(CFLAGS) $(LIBS_USB)
OPT_SSL   := $(CFLAGS) $(LIBS_SSL)
OPT_PTH   := $(CFLAGS) $(LIBS_PTH)
OPT_BOTH  := $(FILES_LIB) $(CFLAGS) $(LIBS_USB) $(LIBS_SSL)

all: $(APP_NAME)

clean:
 rm -f $(OBJDIR)/*.o
 rm -f $(APP_NAME)

$(APP_TEST1): $(INCLUDES) 
 @echo "TEST0: ${INCLUDES} CC:${CC} CFLAGS:${CFLAGS} " > log    
 $(CC) -o $(APP_TEST1) test1.c $(OPT_USB)

$(APP_TEST2): $(INCLUDES)   
 $(CC) -o $(APP_TEST2) test2.c $(OPT_SSL)

$(APP_TEST3): $(INCLUDES)   
 $(CC) -o $(APP_TEST3) test3.c $(OPT_PTH)

$(APP_TEST4): $(INCLUDES)   
 $(CC) -o $(APP_TEST4) test4.c $(OPT_BOTH)



  • Recipe의 Package 개념 및 설정
Yocto는 Recipe를 Package 단위로 구성하기 때문에 당연히 현재의 Package를 알아야 하며,
아래와 같이 Package에 관련부분을 설정해야줘야한다.

Package 관련설정
  https://ahyuo79.blogspot.com/search/label/Yocto-UserConf

e.g 1
## Package 심플하게 구성하게 이름만 선언하고, 이를 IMAGE_INSTALL에 추가 
## 
PACKAGES = "${PN}"
##
## FILE은 Package 내부의 File List로 Package가 이 위치구성되고 최종 RootFS에 적용된다.
## 
FILES_${PN} = "${bindir}/* "

##
## 매번 QA Issue에러 발생하면 관련부분을 생략하자 
##
INSANE_SKIP_${PN} = "ldflags"
INSANE_SKIP_${PN} += "installed-vs-shipped"


e.g 2
##
## PACKAGE 구성시 DEBUG를 어떻게 구성할 것인지 (필요없다면 생략)
## 
PACKAGE_DEBUG_SPLIT_STYLE = "debug-without-src"

##
## Package 의 리스트 구성 으로 간단하게 하고자 하면  
## 
PACKAGES = "${PN}-dbg ${PN} ${PN}-doc"

## QA Issue에서 아래에러를 때문에  추가 
# Avoid QA Issue: No GNU_HASH in the elf binary
INSANE_SKIP_${PN} = "ldflags"

##
## 상위에서 PACKAGE들의 저장위치 
FILES_${PN}-dbg = " \
 ${bindir}/.debug \
"
FILES_${PN} = " \
 ${bindir}/* \
 ${docdir}/* \
"
FILES_${PN}-doc = " \
 ${docdir} \
"



  • Recipe의 관련정보 Debug 방법
Recipe를 작성하다보면 Recipe의 내부변수의 정보를 비롯하여 print를 해서 보고 싶을 경우가 많을 것이며, 이를 bbplain이라는 것을 이용하여 확인하자

do_compile() {
        bbplain "--------    COMPILE DEBUG ${CFLAGS} "  
        ${CC}  -o test main.c ${CFLAGS} ${LDFLAGS} 
}

do_install() {
        bbplain "--------    INSTALL DEBUG ${bindir} " 
        install -d ${D}${bindir}
        install -d ${D}${sysconfdir}/systemd/network
        install -d ${D}${systemd_system_unitdir}
} 

bbplain/bbwarn/bbnote 등을 이용한 debug방법 (각 변수정보확인)
  https://git.yoctoproject.org/cgit.cgi/poky/plain/meta/classes/logging.bbclass


2.1 Image recipe 예제

class image(*.bbclass)를 사용하여 구성을 하여도 되겠지만, 가장쉽게 구성하는 방법은 기존의 Image bb 파일 기반으로 재구성하는 방법이다.

  • IMAGE recipe 예제
bitbake 이용하여 빌드할 경우, 보통 core-image-base 기반으로 나만의 Image를 만들 경우 아래와 같이 구성

$ cd sources/meta-xxxx  // 관련 Layer
$ mkdir recipes-core
$ cd recipes-core
$ vi core-image-mine.bb  
SUMMARY = "My raspberry's Image "

## bitbake core-image-base 기반으로 작성됨
## 이 방법말고 inherit core-image를 이용하여 즉 bbclass를 직접이용하여 사용하는 방법으로도 가능 
include recipes-core/images/core-image-base.bb  

## 상위 기반으로 필요한 Package를 추가하여 설치 
IMAGE_INSTALL += "openssh"  
## 항상 추가된 Package의 bb 파일 검색해서 필요한 Package 추가 한 후 
## 종속관계를 알기위해서 bb 파일에서 반드시 아래 두 항목확인
## DEPENDS : Build를 위해 필요 Package
## RDEPENDS : Runtime시 필요한 Package  
IMAGE_INSTALL += "tcpdump"

## 나만의 Image name 선언 
export IMAGE_BASENAME = "core-image-mine"  

##오직 TEST를 위해 do_rootfs 후에 진행되는 Task 기능추가 추가 
my_postprocess_function() {
   echo "hello" > ${IMAGE_ROOTFS}/hello.txt
}
ROOTFS_POSTPROCESS_COMMAND += "my_postprocess_function; " 

class image를 좀 더 알고 싶다면  core-image-base.bb 파일 이외 inherit core-image를 사용하므로 core-image.bbclass를 세부분석

2.2  Simple Build Recipe 작성 

  • local 기반의 simple recipe 작성예제 
Simple 하게 이미 Source가 존재한다고 가정하고 아래와 같이 구성
    ## recipe의 설명 및 라이센스 설정
    SUMMARY = "TEST"
    SECTION = "TEST"
    LICENSE = "CLOSED"
    
    ## Build할 Source 의 위치 아래는 Local로 설정
    SRC_URI = "file://demo.c"
    S = "${WORKDIR}"
    
    ## Build시 CFLAGS 의 설정 
    CFLAGS_append = "-lusb-1.0 "
    
    ## Build 실 필요한 Package 이름 
    DEPENDS += "libusb1" 
    
    ## Compile task 
    do_compile() {       
     ${CC} demo.c ${LDFLAGS} ${CFLAGS} -o demo
    }
    
    ## 컴파일전에 환경설정 
    do_compile_prepend() {
        export LIBUSB_PATH="${STAGING_LIBDIR}/libusb1"    
    }
    
    ## 설치진행 
    do_install() {
        install -d ${D}${bindir}
        install ${B}/demo ${D}${bindir}
    }
    
    INSANE_SKIP_${PN} += "installed-vs-shipped"
    
    ## Package 이름 
    PACKAGES = "${PN}"
    
    ## install에서 설치되어지는 곳 각 설정 
    FILES_${PN} = "${bindir}/* "
    


    • DEPENDS 와 RDEPENDS 의 차이 
    DEPENDS의 경우 이 recipe를 Build 하기전에 반드시 필요한 Package 구성이며 일반적으로Library 경우가 많다.
    하지만 RDEPENDS의 경우는 이 Program이 Runtime으로 동작할때 필요한 Library가 필요할 경우 많이 사용한다.
    이때 CFLAGS or LDFLAGS or CXXFLAGS를 같이 사용하여 관련 library를 추가하고 세부설정도 가능하다.
    (주의: 스페이스로 반드시 이전 FLAGS정보와 분리)

    일반적으로 상위 FLAGS들을 설정하면, 세부 플래그는 동일하게 설정되지만, 크로스 컴파일 환경이다보니, 세부적으로 조절해야 할 경우가 발생한다.
    1. TARGET_xxx  :  Target Device
    2. BUILD_xxx :  Build Host  i.e    -native 
    3. BUILDSDK_xxx: Build Host  i.e. nativesdk-


    • 상위 Recipe 작성 중 다양한 QA Issue 해결
    Recipe 작성 후 bitbake 실행시 QA Issue라면서 에러가 발생을 할 경우가 있는데, 필요없다면, 생략가능하므로 아래와 같이 설정하여 해결

    $ bitbake core-base-image
    ......
    ERROR: .... do_package_qa: QA Issue: .....
    ......
    installed and not shipped files. [installed-vs-shipped]
    
    //상위와 같은 에러 발생
    
    ./tmp/sstate-control
    ......
    manifest-cortexa9hf-neon-tcpdump.package             //각 Package의 확인 
    manifest-cortexa9hf-neon-tcpdump.package_qa
    manifest-cortexa9hf-neon-tcpdump.package_write_rpm
    manifest-cortexa9hf-neon-tcpdump.populate_lic
    manifest-cortexa9hf-neon-tcpdump.populate_sysroot
    .......
    

    • 보통 QA Issue가 발생하면 Recipe(*bb)에 추가항목

    # Avoid QA Issue: No GNU_HASH in the elf binary
    INSANE_SKIP_${PN} = "ldflags"
    
    # Avoid QA Issue: installed-vs-shipped
    INSANE_SKIP_${PN} += "installed-vs-shipped"
    


    2.3 Kernel/Uboot/Busybox Recipe 수정방법 


    • Uboot/Kernel Device Tree Blob 확인 및 설정확인
    Device Tree Blob은 확인은 아래에서 쉽게가능하지만, 이중 한개만을 사용한다.

    $ bitbake -e | grep ^KERNEL_DEVICETREE=    // KERNEL Device Tree 전체확인가능 (이중 하나만 사용하며, Uboot Script에서 확인가능) 
    KERNEL_DEVICETREE="imx6sx-sdb.dtb imx6sx-sdb-emmc.dtb imx6sx-sdb-m4.dtb                      imx6sx-sdb-sai.dtb imx6sx-sdb-lcdif1.dtb imx6sx-sdb-ldo.dtb                      imx6sx-sdb-reva-ldo.dtb imx6sx-sdb-reva.dtb                      imx6sx-sdb-btwifi.dtb imx6sx-sdb-mqs.dtb"
    
    $ bitbake -e | grep ^KERNEL       // KERNEL 관련설정확인
    ...
    $ bitbake -e | grep ^UBOOT        // UBOOT 관련설정확인 (Kernel의 Device Tree 같이 사용안할수 있음)
    ...
    $ bitbake -e | grep ^UBOOT_CONFIG // i.MX일 경우,UBOOT_CONFIG에서 Device Tree 선택
    UBOOT_CONFIG="emmc"
    

    User Config 설정관련사항 (UBOOT_CONFIG)
      https://ahyuo79.blogspot.com/2020/02/yocto-user-configuration.html

    User Config 와 Machin Layer (UBOOT_CONFIG)
      https://ahyuo79.blogspot.com/2020/02/yocto-layer-configuration.html

    • Uboot/Kernel Device Tree Syntax 설정 (*dts,*dtsi)
    Device Tree는 *.dts 와 *.dtsi 파일 구성이 되어있으며, 보통 include 형식으로 참조하여 여러개의 dts 와 dtsi로 구성이 되어있다.

    DTS 수정방법 두가지
    1. 최종 설정되는 dts 파일을 직접 수정 (맨 아래의 녹색 DTS파일)
    2. 새로 파일 dts 생성 후 최종 dts를 include 생성 후 이것으로 DTS 설정 

    아래의 구성처럼 맨 아래의 최종 녹색 *.dts 기반으로 생성이 되므로, 본인이 원하는 dts가 있다면. 이를 한번 더 include하면 된다. 



    출처 
      https://developer.toradex.com/device-tree-customization#2-imx-6ull-based-modules

    ** 상위그림에서 마지막으로 참조되는 *.dts들은 마지막 Layer인 진한녹색 부분이며 이는 아래의 dts들을 포함하고 있다.

    *.dts 에서 본인의 원하는 device의 설정 및 설정값들은 중복설정 하여도 상관없다. 
    다만, *.dts의 내용이 중복될 경우 상위 그림 구성처럼 마지막으로 참조되는 *.dts 의 내부값으로 최종설정되기때문에 중복부분 확인필요


    기본최종 dts기반으로 새로구성할 경우

    기존에 존재하는 마지막 *.dts 파일를 찾은 후 새로 생성할 *.dts의 내부에 include로 최종 dts를 포함하여 새로생성한다
    변경할 사항들은 새로 생성한 dst에 중복설정한 후 이를 최종 dts로 만들어 빌드를 진행한다.
    (다만 너무 많이 수정한다면, 어쩔 수 없이 중복설정보다는 직접 수정을 하자)

    Uboot 와 Kernel의 dts의 구성은 같지만,  사용방법은 Chip Maker마다 다르므로  주의하자.

    TI 인경우, 한개의 dtb를 Uboot 와 Kernel이 같이 서로 공유하여 사용
    i.MX일 경우는, Uboot와 dtb를 합쳐서 Uboot Image 생성한 후, Kernel용은 dtb를 별도사용하므로, Uboot 소스와 Kernel 소스에서 각각 수정해서 반영

    Uboot 와 Kernel Device Tree 관련내용
      https://ahyuo79.blogspot.com/2015/08/kernel-boot-kernel-device-tree.html

    • Kernel/Uboot/Busybox  Config  수정 (*.cfg)
    Kernel/Uboot/Busybox는 각각의 기본 Config 존재하며, board 기반으로 설정이 되어진다.
    CONFIG_xxx =y 역시 중복설정가능하며 최종설정되는 값으로  진행되므로 cfg로 이전 설정을 변경이 가능하다.

    수정방법
    1. 기본적으로 본인의 defconfig  직접수정하여 변경
    2. 추가로 *.cfg 파일을 생성


    • Uboot의 Config 관련부분 Python 분석 (*.cfg)
    Uboot에서 Config 부분(*.cfg)를 어떻게 처리하는지를 보기위해서 소스분석
    $ find . -name u-boot-imx_*bb*   // 현재 Uboot 검색 
    ./meta-fsl-bsp-release/imx/meta-bsp/recipes-bsp/u-boot/u-boot-imx_2019.04.bb         // Yocto는 항상 PV가 높은 것을 자동선택 
    ./meta-fsl-bsp-release/imx/meta-bsp/recipes-bsp/u-boot/u-boot-imx_2019.04.bbappend
    ./meta-freescale/recipes-bsp/u-boot/u-boot-imx_2018.03.bb
    
    $ vi ./meta-fsl-bsp-release/imx/meta-bsp/recipes-bsp/u-boot/u-boot-imx_2019.04.bb // 현재 Uboot Recipe 분석 
    .....
    require u-boot-common.inc
    require u-boot.inc
    inherit pythonnative
    ....
    inherit fsl-u-boot-localversion
    

    상위와 같이 u-boot.inc를 포함되어있으며, 이부분을 분석해야 이해가 되며, 최종 do_configure()에서 이 부분을 처리함 
    $ find . -name u-boot.inc   //source에서 검색
    ./sources/meta-fsl-bsp-release/imx/meta-bsp/recipes-bsp/u-boot/u-boot.inc 
    ./sources/poky/meta/recipes-bsp/u-boot/u-boot.inc
    $ cd meta-xxx/...   // U-boot recipe 이동 
    $ cat u-boot.inc  // *.cfg 처리파일 (Uboot Config)
    .......
    # returns all the elements from the src uri that are .cfg files
    def find_cfgs(d):
        sources=src_patches(d, True)
        sources_list=[]
        for s in sources:
            if s.endswith('.cfg'):
                sources_list.append(s)
    
        return sources_list
    
    do_configure () {
        if [ -z "${UBOOT_CONFIG}" ]; then
            if [ -n "${UBOOT_MACHINE}" ]; then
                oe_runmake -C ${S} O=${B} ${UBOOT_MACHINE}
            else
                oe_runmake -C ${S} O=${B} oldconfig
            fi
            merge_config.sh -m .config ${@" ".join(find_cfgs(d))}
            cml1_do_configure
        fi
    }
    ......
    

    • Busybox 의 Config 관련부분 Python 분석 (*.cfg)
    동일하게 Busybox의 Config 관련부분(*.cfg) 부분 소스분석 
    $ find . -name busybox_*bb*   // 현재 busybox 검색 
    ./meta-fsl-bsp-release/imx/meta-bsp/recipes-core/busybox/busybox_%.bbappend  
    ./poky/meta/recipes-core/busybox/busybox_1.30.1.bb              // Yocto는 항상 PV가 높은것 자동선택 
    ./poky/meta-skeleton/recipes-core/busybox/busybox_%.bbappend
    ./poky/meta-poky/recipes-core/busybox/busybox_%.bbappend
    
    $ vi ./poky/meta/recipes-core/busybox/busybox_1.30.1.bb // 현재 busybox Recipe 분석 
    require busybox.inc
    ......
    

    Uboot와 동일하게 busybox.inc가 존재하며 이부분의 do_configure 부분에서 처리 
    $ find . -name busybox.inc   //source에서 검색
    ./sources/poky/meta/recipes-core/busybox/busybox.inc
    $ cd meta-xxx/...   // busybox recipe 이동 
    $ cat busybox.inc  // *.cfg 처리파일 (busybox Config)
    .......
    # returns all the elements from the src uri that are .cfg files
    def find_cfgs(d):
        sources=src_patches(d, True)
        sources_list=[]
        for s in sources:
            if s.endswith('.cfg'):
                sources_list.append(s)
    
        return sources_list
    
    do_configure () {
            do_prepare_config
            merge_config.sh -m .config ${@" ".join(find_cfgs(d))}
            cml1_do_configure
    }
    ......
    


    • Kernel 의 Config 관련부분 분석 (*.cfg)
    동일하게 Kernel 의 Config 처리방법(*.cfg) 소스분석 
    $ find . -name linux-imx_*bb //Kernel Recipe 검색 
    ./meta-fsl-bsp-release/imx/meta-bsp/recipes-kernel/linux/linux-imx_4.19.35.bb   //자동으로 Version 높은 것을 선택사용 
    ./meta-freescale/recipes-kernel/linux/linux-imx_4.9.123.bb
    
    $ vi ./sources/meta-fsl-bsp-release/imx/meta-bsp/recipes-kernel/linux/linux-imx_4.19.35.bb // Kernel Recipe 분석
    .....
    require recipes-kernel/linux/linux-imx.inc
    ...
    ## 아래와 같이 기존에 Yocto Manual 존재하는 Task를 미사용하고 새로추가된 Task 사용 
    do_preconfigure_prepend() {
        # meta-freescale/classes/fsl-kernel-localversion.bbclass requires
        # defconfig in ${WORKDIR}
        install -d ${B}
        cp ${S}/arch/${ARCH}/configs/${DEFCONFIG} ${WORKDIR}/defconfig
    }
    

    이상하게 Kernel도 구조는 동일하지만, 이상하게 제대로 동작이 되지 않아 세부분석 
    제대로 지원되지 않아 상위 처럼 내가 직접 do_preconfigure_prepend로 만들어서 지원

    $ find . -name linux-imx.inc
    ./sources/meta-freescale/recipes-kernel/linux/linux-imx.inc 
    
    $ vi ./sources/meta-freescale/recipes-kernel/linux/linux-imx.inc // bbclass 연결됨 
    ....
    inherit kernel fsl-kernel-localversion fsl-vivante-kernel-driver-handler
    ...
    
    $ find . -name kernel*bbclass  //bbclass 분석 
    ./poky/meta/classes/kernel.bbclass
    
    $ find . -name fsl-kernel-localversion*bbclass //bblcass 분석
    ./meta-freescale/classes/fsl-kernel-localversion.bbclass
    
    $ find . -name fsl-vivante-kernel-driver-handler*bbclass  //bblcass 분석
    ./meta-freescale/classes/fsl-vivante-kernel-driver-handler.bbclass
    
    ##
    ## 상위 소스분석 했지만, merge_config 부분 발견못함 
    ## 원래의 Kernel Recipe는 cfg가 제대로 지원이 되어야 하지만 미지원됨 (문제확인)
    
    $ grep -r merge_config.sh .  // cfg 지원되는 부분 검색 
    ./meta-freescale/recipes-kernel/linux/linux-qoriq_4.19.bb  
    ..
    ./poky/meta/classes/kernel-yocto.bbclass
    

    결론 Kernel Recipe는 문제가 존재하며 별도의 Task do_preconfigure 사용중 

    • Uboot/Busybox 의 bbappend file 생성 후 Patch 적용
    1. bitbake package -c diffconfig 이용하여 cfg 와 patch를 넣어 적용
    2. cfg 동작 안된다면, 소스를 분석하여 task에 넣어 강제설정
    3. 이것도 안되면 defconfig에 대한 patch를 생성하여 patch로 적용 


    $ cat u-boot-imx_xxxx.bb // u-boot recipe 확인 
    $ vi  u-boot-imx_xxxx.bbappend //u-boot 관련수정사항 추가 
    FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
    SRC_URI += "file://001_uboot_device_tree.patch"
    SRC_URI += "file://002_uboot_defconfig.patch"
    SRC_URI += "file://000_uboot.cfg"
    SRC_URI += "file://001_uboot.cfg"
    SRC_URI += "file://002_uboot.cfg"
    

    • Kernel 의 bbappend file 생성 후 Patch 적용
    1. bitbake kernel_name -c diffconfig 이용하여 cfg 와 patch를 넣어 적용
    2. cfg 동작 안되다면 do_preconfigure_append or 다른 task로 강제설정
    3. 이것도 안되면 defconfig에 대한 patch를 생성하여 patch로 적용 

    Kernel 추가 Config (*.cfg) 파일생성
    $ cd build    // Yocto build space 이동  
    $ bitbake linux-imx  -c menuconfig    // kernel config 변경 
    $ bitbake linux-imx  -c diffconfig    //변경된 config  *.cfg 생성 후 이를 Kernel Recipe에 추가 
    $ cat fragment.cfg
    $ cp fragment.cfg 001_kernel.cfg
    

    Kernel patch 파일생성 (path 중요)
    $ cd build    // Yocto build space에서 Kernel Source 위치파악하고, kernle 수정  
    
    $ mkdir -p  ~/patch/kernel    // Yocto 의 Patch를 위해 임시 directory생성  
    $ cp -a tmp/work-shared/imx6sxsabresd/kernel-source ~/patch/kernel/kernel_org   // Yocto에서 Download Kernel위치
    $ cp -a tmp/work/imx6sxsabresd-poky-linux-gnueabi/linux-imx/4.19.35-r0/kernel-source ~/patch/kernel/kernel_new // Yocto에서 Build 된 Kernel 위치(이부분 수정)
    
    // Kernel-source 위치 기준으로 Patch 생성 
    $ cd ~/patch/kernel     // Kernel Patch directory 이동 
    $ diff -urN  kernel-source_org  kernel-source_new  > kernel.patch   // Kernel 전체 Patch 생성 or 이위치에서 file patch 생성
    
    // 여러 File Patch 파일이므로 분할 or 상위위치에서 필요파일 Patch 생성
    $ cp kernel.patch 001_kernel_imx6sx-sdb.dtsi.patch  // 001_kernel_filename 구성후 나머지삭제
    $ cp kernel.patch 002_kernel_imx6sx-sdb-emmc.dts.patch //구성후 나머지 삭제
    
    //Kernel-source 위치중요 (현재 kernel_org,kernel_new로 생성되며, 날짜확인중요)  
    $ cat 001_kernel_imx6sx-sdb.dtsi.patch 
    diff -urN kernel-source_org/arch/arm/boot/dts/imx6sx-sdb.dtsi kernel-source_new/arch/arm/boot/dts/imx6sx-sdb.dtsi
    .....
    

    Patch 관련사항 (주의사항)

    Yocto에서는 Build Directory 내부에 Download 되는 위치와 Build 되는 위치거의 비슷한데, 간혹가다가 위치가 다른 경우가 있다. 
    예를 들면. 현재 Kernel의 경우 Build 방법이 달라서 인지 몰라도 위치가 다른데, work-shared의 용도는 다른 recipe와 공유목적이라고 한다.

    $ cd build     // Yocto Build directory
    
    tmp/work/imx6sxsabresd-poky-linux-gnueabi/u-boot-imx/1_2019.04-r0/git/                                  //Uboot  Download 위치 
    tmp/work/cortexa9hf-neon-mx6sx-poky-linux-gnueabi/linux-imx-headers/4.19.35-r0/git/                   //Kernel Download 위치 
    
    tmp/work/imx6sxsabresd-poky-linux-gnueabi/u-boot-imx/1_2019.04-r0/build/mx6sxsabresd_emmc_config/   //Uboot  Build 된 위치                   
    tmp/work-shared/imx6sxsabresd/kernel-source/                                                                //Kernel Build 된 위치 
    
    // 아래와 같이 Yocto는 거의 Download 위치와 Build 위치는 같은위치
    $ ls tmp/work/imx6sxsabresd-poky-linux-gnueabi/u-boot-imx/1_2019.04-r0/                 
    001_uboot_devicetree.patch    build/                        image/                        pkgdata/                      sysroot-destdir/
    002_uboot_defconfig.patch     deploy-rpms/                  license-destdir/              pseudo/                       temp/
    003_uboot_mmc.patch           deploy-u-boot-imx/            package/                      recipe-sysroot/               u-boot-imx.spec
    004_uboot_mx6sxsabresd.patch  git/                          packages-split/               recipe-sysroot-native/
    
    // 아래와 같이 예외적으로 다른사항도 있으니 주의 (Kernel build 위치가 다름) 
    // 현재 이유는 Compile시 neow으로 build해서 다른 것으로 생각 
    
    $ ls tmp/work/cortexa9hf-neon-mx6sx-poky-linux-gnueabi/linux-imx-headers/4.19.35-r0/   
    configure.sstate        git/                    license-destdir/        package/                pkgdata/                recipe-sysroot/         sysroot-destdir/
    deploy-rpms/            image/                  linux-imx-headers.spec  packages-split/         pseudo/                 recipe-sysroot-native/  temp/
    


    Kernel Recipe에 적용
    $ cd sources     // Yocto의 source 이동 
    $ cd meta-xxx/...  // Kernel recipe 이동 
    $ cat linux-imx_xxxxx.bb                  // Kernel recipe 확인 
    $ vi linux-imx_xxxxx.bbappend
    FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
    SRC_URI += "file://001_kernel_imx6sx-sdb.dtsi.patch"
    SRC_URI += "file://002_kernel_imx6sx-sdb-emmc.dts.patch"
    SRC_URI += "file://001_kernel.cfg"
    SRC_URI += "file://002_kernel.cfg"
    
    
    ## 문제사항 
    # 상위 *.cfg가 적용되지 않아 .config까지 적용하기위해서 아래와 같이 do_preconfigure를 이용하여 직접적용함 
    #
    ## 주의사항 (이것도 문제가 있음)
    # kernel menuconfig or config 전에 추가되기 때문에, 
    # Kernel diffconfig 를 하여도 동작안되므로, diffconfig를 원하면, 이부분을 막아야함 
    do_preconfigure_append() {
            cat ${WORKDIR}/001_kernel.cfg >> ${WORKDIR}/defconfig
            cat ${WORKDIR}/001_kernel.cfg >> ${WORKDIR}/build/.config
            cat ${WORKDIR}/002_kernel.cfg >> ${WORKDIR}/defconfig
            cat ${WORKDIR}/002_kernel.cfg >> ${WORKDIR}/build/.config
    }
    


    Kernel 관련된 Task
      https://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#kernel-related-tasks

    /sys/kernel/debug 사용할 경우 
      https://yoctoproject.org/docs/3.0.4/profile-manual/profile-manual.html#profile-manual-general-setup

    2.4 systemd class를 이용한 recipe 작성

    systemd class를 이용하여 systemd의 service를 쉽게 제어가능하며, 각각의 File들을 쉽게 install 이 가능하다.

    • system 관련 서비스 기능추가 
    $ cat systemd.bb 
    ## Systemd 관련부분 설정
    SUMMARY = "Systemd Setting "
    DESCRIPTION = "Systemd Setting"
    LICENSE = "CLOSED"
    
    ## systemd bbclass 이용 
    inherit systemd 
    
    ## FILE관련 PATH를 별도로 추가를 하지 않아도 이곳에서 files에서 아래 파일들을 찾음 
    ## FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
    
    SRC_URI =  "file://eth0.network"
    SRC_URI += "file://test-0.service"
    SRC_URI += "file://test-1.service"
    SRC_URI += "file://test-2.service"
    SRC_URI += "file://test.sh"
    SRC_URI += "file://Seoul"
    SRC_URI += "file://30-mmc.rules"
    
    ## S설정
    ## 상위 Local File로 구성되어있기에 별도의 Directoryr가 필요없음 
    
    S = "${WORKDIR}"
    
    ##
    ## 본인이 원하는 systemd service를 SYSTEMD_SERVICE_ 설정 아래 설치별도로 존재 
    ## 이곳을 설정을 하지 않고 udev와 systemd의 service 연결하여 실행하고자 한다면, 이곳이 선언하지 말자. 
    ## https://ahyuo79.blogspot.com/2020/02/sdcard-udev.html
    SYSTEMD_PACKAGES = "${PN}"
    SYSTEMD_SERVICE_${PN} = "test-0.service test-1.service test-2.service"
    
    do_install() {
    ## Debug를 위해 삽입 bbplain기능 
      bbplain "--------    Systemd Setting Install     -----------------"
    ## 설치될 부분을 정의 
     install -d ${D}${bindir}
     install -d ${D}${sysconfdir}/systemd/network
     install -d ${D}${systemd_system_unitdir}
    
    ## systemd의 상위 service에서 사용하는 shell script 
     install ${S}/*.sh ${D}${bindir}
    
    ## systemd의 service기능 설치 
     install -D -m 0644 ${S}/*.service    ${D}${systemd_system_unitdir}
    
    ## 기타 필요한 부분 복사설치 
     install -D -m 0644 ${S}/eth0.network ${D}${sysconfdir}/systemd/network/eth0.network 
     install -D -m 0644 ${S}/Seoul        ${D}${sysconfdir}/localtime
     install -D -m 0644 ${S}/30-mmc.rules ${D}${sysconfdir}/udev/rules.d/30-mmc.rules
    }
    
    
    #PACKAGES = "${PN} "
    ## 상위 Install에서 설치될 부분을 반드시 정의 
    FILES_${PN} += " \
     ${sysconfdir} \
     ${bindir} \
     ${systemd_system_unitdir} \
    "
    

    install 시 상위 sysconfdir/systemd_system_unitdir/  변수정보
      https://git.yoctoproject.org/cgit.cgi/poky/plain/meta/conf/bitbake.conf

    bbplain 을 이용한 debug방법 (각 변수정보확인)
      https://git.yoctoproject.org/cgit.cgi/poky/plain/meta/classes/logging.bbclass

    • systemd 의 service 관련 설정 및 Shell Script 
    이 부분은 별도로 systemd 관련 Manual을 참고

    $ cat files/test-0.service
    [Unit]
    Description=TEST Service
    After=network-online.target
    Wants=network-online.target
    
    
    [Service]
    Type=simple
    ExecStart=/usr/bin/test.sh
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target 


    • logger 와 간단한 Shell script 구성 
    service에서 사용하는 쉬운 shell script
    $ cat files/test.sh
    #!/bin/sh
    
    WAIT_100MS() { sleep 0.1}
    
    ## /var/log 에 tag는 test 설정 하고 우선순위및 설정  
    echo ">> Start TEST Service\n\n" | logger -t test -p local3.notice
    
    /bin/ls
    
    ## 상위 실행의 최종 return 값 체크 
    if [ $? -eq 0 ]
    then
      echo "Success: ls" | logger -t test -p local3.notice
    else
      echo "Failure: ls" >&2 | logger -t test  -p local3.notice
      exit 1
    fi
    
    ## 본인이 원하는 프로그램 실행 
    /bin/xxxxx
    
    ## 이프로그램 실패를 해서 exit 1이 되며 상위 Service의 Restart=on-failure 에 의해 재실행 
    echo -e ">> Failed TEST Service\n\n" | logger -t test -p local3.notice
    exit 1
    

    2.5 다양한 class와 task 이용한 Recipe 작성법

    항상 본인이 사용하는 Yocto의 Version을 확인 한 후 해당 Manual 참조
    bbclass 의 이해와 사용법 (inherit allarch , systemd, ... )

    • Yocto 의 class systemd (inherit systemd) 의 예제
      https://stackoverflow.com/questions/45614578/enable-systemd-services-using-yocto
      https://community.nxp.com/thread/472820
      https://www.yoctoproject.org/pipermail/yocto/2015-April/024469.html
      https://hub.mender.io/t/startup-script-for-raspberrypi3-using-yocto/201/2


    • Yocto 의 class allarch (inherit allarch) 의 예제
      https://git.yoctoproject.org/cgit.cgi/poky/plain/meta/classes/allarch.bbclass
      https://stackoverflow.com/questions/50906048/bitbake-recipes-simple-file-copy


    • Yocto의 다양한 Class 정보 
      https://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#ref-classes

    • Yocto 의 다양한 Task
      https://www.yoctoproject.org/docs/2.7/ref-manual/ref-manual.html#ref-tasks

    • Yocto 의 Kernel 관련된 Task 
      https://www.yoctoproject.org/docs/2.7/ref-manual/ref-manual.html#kernel-related-tasks


    • BBexmple 의 예제
      https://github.com/DynamicDevices/meta-example/blob/master/recipes-example/bbexample/bbexample_1.0.bb
      https://github.com/DynamicDevices/bbexample/releases
      https://github.com/DynamicDevices/bbexample/commit/5c58a861ca31710f6433487b8b0d590a43afd0ad

    10/13/2015

    IMX6 CAMERA MODULE 수정 및 Yocto 로 Patch 만들기

    1. IMX6 CAMERA INTERFACE

    현재 Freescale 의 I.MX6 의 Linux KERNEL은 device tree를 사용하고 있어, 수정 및 관리가 쉽다.
    I.MX6의 camera capture의 interfaces는 Module 형태로 제공을 하고 있어,
    만약, 해당부분을 추가한다면, module를 추가해서 넣고 테스트를 진행하면 된다.


    1.1 CAMERA 관련문서확인

    우선 Freescale에서 제공하는 문서와 Yocto File을 다운로드 하고 관련문서를 숙지하도록하자.

    Freescale의 Camera 관련문서 
      https://www.freescale.com/webapp/sps/download/license.jsp?colCode=L3.10.17_1.0.0_LINUX_DOCS&appType=file1&location=null&DOWNLOAD_ID=null


    • Download
    fsl-yocto-3.10.17_1.0.0.tar.gz ( Freescale site에서 download )


    • 상위 관련문서
    1. i.MX_6_SABRE-SD_Linux_Release_Notes.pdf
    2. i.MX_6_Linux_Reference_Manual.pdf
    3. i.MX_6_BSP_Porting_Guide.pdf

    각 문서의 주요사항들을 아래와 같이 정리하다. 

    A.  i.MX_6_SABRE-SD_Linux_Release_Notes.pdf

    상위 문서에서 아래부분을 각각 확인하자.
    Device Tree 부분은 나의 문서를 참조하고 기본개념을 파악하자. 

    TI Sitara Device Tree 관련내용(반드시 숙지) 

    Device Tree 부분 참조

    그리고 나서 커널내부에서 제공하는 문서를 보자
    • Device Tree  
           uImage-imx6sl-evk-csi.dtb

    상위문서의 아래부분들을 반드시 참고하고 확인하자
    • 4 BSP Supported Features i.MX 6 SABRE-SD
    1. Supported Features for i.MX 6 SABRE-SD
    2. IPU V3 driver Yes Provides the interfaces to access IPU V3 modules
    3. V4L2 Capture Yes Supports dual camera.
    4. CSI Camera Yes Supports OV5640 camera sensor.
    5. CSI Camera Yes Supports OV5640 camera sensor.

    B. i.MX_6_Linux_Reference_Manual.pdf

    기본적으로 Camera의 동작방식과 관련부분을 알고 있어야 아래 부분이 이해가 가능하다.

    추후 Camera 관련내용제공 

    각 부분 카메라 관련 모듈 테스트 방법 과 IPU와 동작방법알아두자.
    상위 문서의 아래부분을 참고
    • Ch 6   IPU (Image Processing Unit)
            6.3 Source Code Structure
            6.3.1 Menu Configuration Options  ***
            6.4 Unit Test 확인

    $ insmod ipu_prp_enc.ko
    $ insmod ipu_bg_overlay_sdc.ko
    $ insmod ipu_fg_overlay_sdc.ko
    $ insmod ipu_csi_enc.ko
    $ insmod ov5640_camera.ko
    $ insmod mxc_v4l2_capture.ko
    


    • Chapter 20  OmniVision Camera Driver
    • Chapter 21  MIPI CSI2 Driver


    C. i.MX_6_BSP_Porting_Guide.pdf

    iMX의 BSP를 수정하는 전반적인 방법에대해서 설명을 해주고 있으므로, 반드시 확인


    1.2 KERNEL 구조파악

    기본적으로 KERNEL에 Linux Module을 추가하려면, 아래와 같이 기본구조를 파악하자.

    A. KERNEL CONFIG 의 확인 

    i.MX6에서 사용하는 Main Kernel Config 이며, 모든 Kernel Config 구성이 동일하다. 
    아래와 같이 동일한 역할을 하는 파일이지만, 위치가 다 다를 수 있다

    $ ls kernelxxx/arch/arm/configs/xxxx_defconfig     //  본래 xxx_defconfig 위치는 이곳이며, make xxx_defconfig  (bitbake(yocto)에서도 사용)
    $ defconfig                              //  실제 적용되는 defconfig로 이 기반으로 .config 생성       
      imx_v7_defconfig                       //  imx_v7_defconfig defconfig 동일하며,  arch/xxx/configs/에 위치함 
    $ vi .config                             //  현재 설정된 kernel config 값으로 defconfig 기반으로 생성됨   
                                             //  defconfig 와 .config는 구조는 거의 비슷하지만, 생성되는 것은 Kernel에서 변경이됨 
    
    원래 Linux kernel의 경우 아래와 같이 동작하지만 Yocto에서도 상위와 같이 각각의 defconfig 를 이해하자 
    $ make xxx_defconfig    //arch/arm/configs/xxxx_defconfig 설정  후 .config 설정됨 
    $ make menuconfig       


    B. KCONFIG 파일

    Linux Kernel에서 직접 수정하도록 하자 

    //일반적인 Linux Kernel는 알다시피 아래와 같이 하지만, 현재 Yocto를 사용하므로 아래를 참조해가며 하자 
    
    $ make menuconfig // Linux 메뉴설정을 위해 아래의 파일들을 점검하자 (Driver추가시)
    
    // 상위 .config에 의해 실제 소스에 적용되는 #define 설정값 
    $ cat include/generated/autoconf.h 
    
    // make menuconfig  실행시 메뉴설정 파일 
    // 해당 driver에서 Kconfig파일과 makefile을 동시에 수정을 해주면된다.
    $ Kconfig     // Main 설정 
    $ makefile    // 관련부분 검토 (커널 Version 확인)
    
    // Linux Kernel Version 확인 
    $ vi include/linux/version.h  
    

    2. CAMERA MODULE 수정


    아래와 같이 build가 아니라 직접 source에 가서 수정하도록하자. 
    대신 수정하기전에, backup을 반드시 진행하고 수정을 하도록하자.


    2.1 Kernel Module 수정 및 config 수정 

    $ cd ~/IMX6/fsl-community-bsp/build/tmp/work/imx6qsabreauto-poky-linux-gnueabi/linux-fslc-mx6/3.14-1.0.x+gitAUTOINC+4bae14aef7-r0/build/source
    
    $ cp ./drivers/media/platform/mxc/capture/ov5642.c ./drivers/media/platform/mxc/capture/fpga.c
    
    $ vi ./drivers/media/platform/mxc/capture/Makefile
    fpga_camera-objs := fpga.o
    obj-$(CONFIG_MXC_CAMERA_FPGA) += fpga_camera.o
    
    $ vi ./drivers/media/platform/mxc/capture/Kconfig 
    config MXC_CAMERA_FPGA
            tristate "FPGA camera support"
            depends on !VIDEO_MXC_EMMA_CAMERA && I2C
            ---help---
              If you plan to use the ov5642 Camera with your MXC system, say Y here.
    
    $ cd ..      
    $ vi . config                    //build directory.
    CONFIG_MXC_CAMERA_OV5642=m
    CONFIG_MXC_CAMERA_FPGA=m
    $ cd .. 
    $ vi defconfig 
    CONFIG_MXC_CAMERA_OV5642=m
    CONFIG_MXC_CAMERA_FPGA=m
    

    상위와 같이 Kernel Config 와 관련 Driver 추가

    2.2 make menuconfig시 설정정보 

    Video For Linux는 Camera기능에서 Capture기능을 담당하는 부분으로 중요하다
      - Deivce Driver -> Multimedia Support -> V4L platform devices


    3. PATCH 만들어 적용 

    Linux Kernel Patch를 직접 만들어서 이를 Yocto의 적용해보도록하자.
    물론 bbappend를 사용할 것이다. 

    3.1  KERNEL Patch 생성 


    $ cd ~/IMX6/fsl-community-bsp/build/tmp/work/imx6qsabreauto-poky-linux-gnueabi/linux-fslc-mx6/3.14-1.0.x+gitAUTOINC+4bae14aef7-r0
    $ mkdir jhlee  // backup 용 source 보관
    $ cp -a  /home/jhlee/IMX6/fsl-community-bsp/build/tmp/work-shared/imx6qsabreauto/kernel-source/  org  // orginal source backup
    $ cp -a  /home/jhlee/IMX6/fsl-community-bsp/build/tmp/work-shared/imx6qsabreauto/kernel-source/  new // after modified kernel 
    $ diff -urN  org  new  > fpga.patch  

    상위와 같이 만들어진 patch를 확인한 후 필요한 부분만 사용


    3.2 recipes-kernel 찾기

    bitbake 사용시 중요한 것은 recipes 이므로 recipes-kernel 관련된 부분을 모두 찾아보자

    내 kernel를  recipes 이름을 정확히 알고 있다면 . bb file 파일로 찾자

    $ cd ~/IMX6/fsl-community-bsp/   // main으로 이동 
    $ find . -name recipes-kernel
    ./sources/meta-openembedded/meta-initramfs/recipes-kernel
    ./sources/meta-openembedded/meta-oe/recipes-kernel
    ./sources/meta-openembedded/meta-networking/recipes-kernel
    ./sources/meta-fsl-arm-extra/recipes-kernel
    ./sources/poky/meta-yocto-bsp/recipes-kernel
    ./sources/poky/meta/recipes-kernel
    ./sources/poky/meta-skeleton/recipes-kernel
    ./sources/poky/scripts/lib/bsp/substrate/target/arch/arm/recipes-kernel
    ./sources/poky/scripts/lib/bsp/substrate/target/arch/i386/recipes-kernel
    ./sources/poky/scripts/lib/bsp/substrate/target/arch/x86_64/recipes-kernel
    ./sources/poky/scripts/lib/bsp/substrate/target/arch/powerpc/recipes-kernel
    ./sources/poky/scripts/lib/bsp/substrate/target/arch/mips/recipes-kernel
    ./sources/poky/scripts/lib/bsp/substrate/target/arch/qemu/recipes-kernel
    ./sources/poky/scripts/lib/bsp/substrate/target/arch/mips64/recipes-kernel
    ./sources/poky/scripts/lib/bsp/substrate/target/arch/common/recipes-kernel
    ./sources/meta-fsl-arm/openembedded-layer/recipes-kernel
    ./sources/meta-fsl-arm/recipes-kernel 
    


    3.3 Kernel recipes 의 BB file 확인  

    bb file의 예를 들면, 다음과 같다. 
    linux-fslc-mx6_3.14-1.0.x.bb  
    상위 구조를 보면  '_' 기준으로 PN(Package Name)과 PV(Package Version)를 나누어진다.
    그러므로 아래와 같이 검색하면 쉽게 찾는다

    • 나의 기본 KERNEL BB FILE 확인 
    상위구조를 이해했으며, 아래와 같이 쉽게 찾도록하자 
    $ find ./ -name linux-fslc-mx6*bb* // manual을 보고 이미 kernel recipe 파악 or show-recipe로 추측하자 
    .....
    $ cd ~/IMX6/fsl-community-bsp/   // main으로 이동 
    $ vi ./sources/meta-fsl-arm/recipes-kernel/linux/linux-fslc-mx6_3.14-1.0.x.bb 
    # Copyright (C) 2015 O.S. Systems Software LTDA.
    # Released under the MIT license (see COPYING.MIT for the terms)
    
    SUMMARY = "FSL Community BSP i.MX6 Linux kernel with backported features and fixes"
    DESCRIPTION = "Linux kernel based on Freescale 3.14.28 GA release, used by FSL Community BSP in order to \
    provide support for i.MX6 based platforms and include official Linux kernel stable updates, backported \
    features and fixes coming from the vendors, kernel community or FSL Community itself."
    
    include linux-fslc.inc
    
    PV .= "+git${SRCPV}"
    
    SRCBRANCH = "3.14-1.0.x-mx6"
    SRCREV = "4bae14aef7b8f340f30598d2b076e9ed7b7cba56"
    
    COMPATIBLE_MACHINE = "(mx6)"
    

    상위 bb file 의 내부에 include가 있으므로, linux-fslc.inc 파일을 찾아 세부적으로 보자

    • Source 와 Build된 부분의 defconfig
    현재 Kernel config 와 동일한지 우선 확인하자.  
    source 의 defconfig 값과 build의 defconfig를 비교를 해보고, 
    만약 defconfig를 설정을 변경하고자 하면 source에서 이를 맞춰서 변경해주면된다.
    $ cd ~/IMX6/fsl-community-bsp/ 
    $ diff  ./sources/meta-fsl-arm/recipes-kernel/linux/linux-fslc-mx6/defconfig   ~/IMX6/fsl-community-bsp/build/tmp/work/imx6qsabreauto-poky-linux-gnueabi/linux-fslc-mx6/3.14-1.0.x+gitAUTOINC+4bae14aef7-r0/defconfig   // 동일 


    3.4  Patch를 Yocoto *.bbappend 추가 

    상위에서 만들어진, 나의 Linux Patch를 Kernel Recipe에 bbappend로 아래와 같이 추가하자.
    보통 bbappend 형식으로 많이 Patch관리를 한다. 

    $ cd ~/IMX6/fsl-community-bsp/   // main으로 이동 
    $ cd ./sources/meta-fsl-arm/recipes-kernel/linux/  
    $ cp ~/IMX6/fsl-community-bsp/build/tmp/work/imx6qsabreauto-poky-linux-gnueabi/linux-fslc-mx6/3.14-1.0.x+gitAUTOINC+4bae14aef7-r0/jhlee/fpga.patch . 
    $ mkdir files             //  아래의 bbappend에 따라 subdirectory 생성하지만, files은 기본으로 찾음
    $ mv fpga.patch files   // files에 copy 
    $ ls
    linux-fslc-mx6_3.14-1.0.x.bb        linux-imx                     linux-imx-rt-3.14.28     linux-ls1          linux-timesys-3.0.15
    fpga.patch      linux-fslc-mx6_3.14-1.0.x.bbappend  linux-imx-3.14.38             linux-imx-rt_3.14.28.bb  linux-ls1.inc      linux-timesys_3.0.15.bb
    linux-fslc      linux-fslc.inc                      linux-imx-mfgtool-3.14.28     linux-imx.inc            linux-ls1_3.12.bb
    linux-fslc-mx6  linux-fslc_4.1.bb                   linux-imx-mfgtool_3.14.38.bb  linux-imx_3.14.38.bb     linux-mfgtool.inc
    


    • bbappend를 적용하여 patch진행 
    기본으로 recipe(*.bb)파일 위치기준으로 사용되어지는 files는 FILEPATH에 의해 local file들을 찾을 수 있다.
    하지만, 아래와 같이 FILEPEXTRAATHS에 추가적으로 위치를 확장가능
    SRC_URI 을 "file://" 사용할 경우 Local File을 사용하는 것이며, 
    THISDIR의 위치는 bbappend 파일의 위치이며, 아래와 같이 patch파일을 본인이 원하는 sub directory에 추가

    주석처리 했지만, 다양하게 구성해서 해보자 
    $ vi linux-fslc-mx6_3.14-1.0.x.bbappend 
    FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
    #FILESEXTRAPATHS_prepend := "${THISDIR}/v${PV}:"
    #FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
    #FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}-${PV}:"
    SRC_URI += "file://fpga.patch"
    #PRINC := "${@int(PRINC) + 1}" 
    

    * prepend는 맨앞에 할당
    * append 는 맨뒤에 할당
    * SRC_URI += append 의미이며, file:// 은 local file 의미

    • Patch 문제발생시 확인사항 
    상위를 추가하면 quilt 라는 것이 patch를 실행을 하는데, quilt에서 에러가 발생하면 path 내부에러문제인지 자세히 살펴보자.


    3.4.1  상위 관련설정 세부사항 설명 


    • FILEPATH
    Local FILES들을 기본으로 찾는 PATH로 보통 *bb 파일의 위치로 설정 ({THISDIR}/files:)
      https://www.yoctoproject.org/docs/1.8/ref-manual/ref-manual.html#var-FILESPATH

    • FILESEXTRAPATHS
    Local FILE들을 찾는위치를 추가로 확장하는 PATH로 본인이 원하는대로 확장
      https://www.yoctoproject.org/docs/1.8/ref-manual/ref-manual.html#var-FILESEXTRAPATHS

    • SRC_URI
    prefix 와 suffix 값에 의해 동작이 결정된다고 생각하면된다. ";" 를 넣어  patchdir를 이용하여 patch dir로 변경가능
      https://www.yoctoproject.org/docs/1.8/ref-manual/ref-manual.html#var-SRC_URI
      http://www.embeddedlinux.org.cn/OEManual/src_uri_variable.html

    • Kernel 관련수정방법
    Kernel의 설정인 defconfig 부터 관련 driver 수정에 관련된 부분을 설명
      https://www.yoctoproject.org/docs/1.8/kernel-dev/kernel-dev.html
      https://www.yoctoproject.org/docs/1.8/kernel-dev/kernel-dev.html#changing-the-configuration
      https://www.yoctoproject.org/docs/1.8/kernel-dev/kernel-dev.html#creating-the-append-file


    • cfg 파일 만드는 방법
    재미있는 것은  아래와 같이 diffconfig를 이용하면 .config 와 차이점을 *.cfg에 저장을 해준다.

    $ bitbake linux-fslc-mx6 -c diffconfig