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

    2/26/2020

    Yocto 의 WIC Partition 설정

    1.  Yocto 의 Image Partition 수정 

    Yocto에서 Image 의 Partition은 일반적으로 WIC기반으로 WKS FILE로 관리되어지고 있다.

    1.1 WIC/WKS 사용파악 

    아래와 같이 WKS FILE을 찾아 파일을 알고 검색하여 각각의 Partition의 구성을 알고 관련부분을 변경하자.

    $ bitbake -e | grep ^IMAGE_FSTYPES=    // 현재 사용중인 IMAGE 구성방법확인   
    IMAGE_FSTYPES="wic.bmap wic.bz2 tar.bz2"
    // wic.bmap (bmap은 XML로 bmaptool을 이용하여 write가능 or dd도 가능) 
    // wic.bz2 로 wic로 구성되고 압축됨 
    

    • WKS_FILE 검색
    $ bitbake -e | grep ^WKS_FILE=    // 현재 사용중인 WKS FILE 검색 
    WKS_FILE="imx-uboot-bootpart.wks.in"
    

    1.2 WIC 의 Partition 수정방법 

    WKS file은 종류로 나누어지며, *.wks 와 *.wks.in 으로 나누어진다.
    *.wks는 일반적인 kickstart files로 wic list images 를 하면 각 wks의 short-description 정보를 확인가능.
    *.wks.in는 내부에서 사용되어지는 FILE로 아래와 같이 kickstart files로 보여지지 않는다.

    • WKS FILE 수정방법의 예 
    $ find . -name imx-uboot-bootpart.wks.in  // WKS_FILE= 정보
    $ cat ./meta-freescale/wic/imx-uboot-bootpart.wks.in         // 상위 wks script로 반드시 아래의 Manual을 읽어야함 
    # short-description: Create SD card image with a boot partition
    # long-description:
    # Create an image that can be written onto a SD card using dd for use
    # with i.MX SoC family
    # It uses u-boot
    #
    # The disk layout used is:
    #  - --------- -------------- --------------
    # | | u-boot  |     boot     |    rootfs   |
    #  - --------- -------------- --------------
    # ^ ^         ^              ^
    # | |         |              |
    # 0 1kiB    4MiB          16MiB + rootfs + IMAGE_EXTRA_SPACE (default 10MiB)
    #
    
    ##
    ## rawcopy로 이용하며, uboot가 저장이 되어지며, --no-table 때문에 아래의 partition에서는 잡히지는 않는다. 
    ## 
    part u-boot --source rawcopy --sourceparams="file=${UBOOT_BINARY}" --ondisk mmcblk --no-table --align 1
    
    ##
    ## 상위 Layout의 boot에 해당하며, FAT로 구성되고, Kernel 과 DTB 와 TEE 정보 (mmcblkxp1)
    ##
    ## --size 16         : data를 넣고 여부으로 16M byte 넣어 매번 가변적 
    ## --fixed-size 16   : 고정 크기에 data들을 넣음 (고정크기)  ** Upgrade를 위해 추후 변경 
    ##
    part /boot --source bootimg-partition --ondisk mmcblk --fstype=vfat --label boot --active --align 4096 --size 16
    #part /boot --source bootimg-partition --ondisk mmcblk --fstype=vfat --label boot --active --align 4096 --fixed-size 16
    
    ##
    ## 상위 Layout의 rootfs에 해당하며 Main Filesystem 이다. 
    ## Linux Main Filesystem 으로 보면 별도로 size를 정의하지 않지만 아래의 비율로 계산하여 여부발생 ((mmcblkxp2)
    ## du command 사용 
    ## IMAGE_OVERHEAD_FACTOR="1.3"
    ## IMAGE_ROOTFS_EXTRA_SPACE="0"
    ## IMAGE_ROOTFS_SIZE="65536"
    ## --size            : 언급이 없으므로, 관련 data를 넣은 후에 상위 설정된 여부의 계산으로 설정하여 변경 (가변적)
    ## --fixed-size 16   : 고정 크기에 data들을 넣음 (고정크기) ** Upgrade를 위해 고정적으로 변경 
    ## 
    part / --source rootfs --ondisk mmcblk --fstype=ext4 --label root --align 4096
    #part / --source rootfs --ondisk mmcblk --fstype=ext4 --label root --align 4096 --fixed-size 256
    
    ##
    ## 상위 Layout에는 존재하지 않으며, 별도로 설정을 변경하고 직접 수정하여 변경 
    ## VOLATILE_LOG_DIR= no 설정 후 아래와 같이 추가 (mmcblkxp3)
    ## /var/log를 사용 (256Mbyte)
    part /var/log  --ondisk mmcblk --fstype=ext4 --label root --align 4096 --size 256
    
    ##
    ## bootloader 에서 partition table 정보 (MSDOS 이외 설정도가능)
    ##
    bootloader --ptable msdos


    WKS FILE 의 part 관련
      https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#ref-kickstart

    WIC 명령어
      https://www.yoctoproject.org/docs/2.4.2/dev-manual/dev-manual.html#creating-partitioned-images-using-wic
      https://www.yoctoproject.org/docs/2.0/dev-manual/dev-manual.html#creating-partitioned-images

    1.3 WIC Python Code 분석 

    WKS FILE을 정확하게 설정하고 이해하려면 어쩔수 없이 현재 본인의 WIC 명령어에서 제공되어지는 기능들을 알아보자

    • WIC Python Code 분석
    ./poky/scripts
      https://github.com/alexandrebelloni/wic/tree/master/scripts
      https://github.com/openembedded/openembedded-core/tree/master/scripts

    ./poky/scripts/lib/wic/image/help.py
      https://github.com/alexandrebelloni/wic/blob/master/scripts/lib/image/help.py
      https://github.com/openembedded/openembedded-core/blob/master/scripts/lib/wic/help.py

    ./poky/scripts/wic
      https://github.com/openembedded/openembedded-core/blob/master/scripts/wic

    • WKS Kickstart File 옵션관련내용
      https://github.com/openembedded/openembedded-core/blob/master/scripts/lib/wic/ksparser.py

    • WKS의 File의 part 의 --source 부분
      ./poky/scripts/lib/wic/plugins/source/
      https://github.com/openembedded/openembedded-core/tree/master/scripts/lib/wic/plugins/source


    //--sourceparams=${UBOOT_BINARY}
    $ bitbake -e | grep ^UBOOT_BINARY
    UBOOT_BINARY="u-boot.imx"
    

      WKS의 FILE part 의 --source 의 bootimage-partition 분석
      https://github.com/openembedded/openembedded-core/blob/master/scripts/lib/wic/plugins/source/bootimg-partition.py

    // --source 의 bootimg-partition 부분분석 (상위 python 소스참조) 
    //DEPLOY_DIR_IMAGE 위치에서 IMAGE_BOOT_FILES들을 가져와서 넣음 
    
    $ bitbake -e | grep ^DEPLOY_DIR_IMAGE
    DEPLOY_DIR_IMAGE="/home/jhlee/yocto/build-fb/tmp/deploy/images/imx6sxsabresd"
    
    //IMAGE_BOOT_FILES 들이 FAT에 저장됨 
    $ bitbake -e | grep ^IMAGE_BOOT_FILES
    IMAGE_BOOT_FILES="     zImage     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     tee.bin uTee-6sxsdb      "
    

      WKS의 FILE part 의 --source 의 rootfs 분석
      https://github.com/openembedded/openembedded-core/blob/master/scripts/lib/wic/plugins/source/rootfs.py

    // --source 의 rootfs 부분분석 (상위 python 소스참조) 
    $ bitbake -e | grep ^IMAGE_ROOTFS
    IMAGE_ROOTFS="/home/jhlee/yocto/build-fb/tmp/work/cortexa9hf-neon-poky-linux-gnueabi/defaultpkgname/1.0-r0/rootfs"
    IMAGE_ROOTFS_EXTRA_SPACE="0"
    IMAGE_ROOTFS_SIZE="65536
    


    1.4 Linux Partition 관련내용 

    VOLATILE_LOG_DIR은 일반적으로 no 로 설정이 되어있으며, 이를 tmpdir로 설정되어 ramdisk로 보통 관리하지만,
    기록을 하기 원한다면 아래와 같이 확인 한 후 User Configuration에서 설정을 변경 후 상위 WKS File에 적용하면 된다.

    • User Configuration 에서 VOLATILE_LOG_DIR=no 설정
    User Configuration 에 환경변수 설정 상위참조

    $ bitbake -e | grep ^VOLATILE_LOG_DIR  // default yes
    VOLATILE_LOG_DIR="yes"
    

    • /etc/fstab 수정
    yocto 의 sources에서 fstab 관련부분 검색 후 수정

    $ find . -name fstab
    ./poky/meta/recipes-core/base-files/base-files/fstab
    
    $ vi ./poky/meta/recipes-core/base-files/base-files/fstab  // 추가 /var/log filesystem 설정 
    ....
    /dev/mmcblk3p3       /var/log             auto       defaults              1  1
    ...
    


      https://stackoverflow.com/questions/49912475/adding-a-partition-in-yocto-generated-image
      https://www.digi.com/resources/documentation/digidocs/90001546/concept/yocto/c_emmc_layout_yocto.htm
      https://developer.ridgerun.com/wiki/index.php?title=IMX8/iMX8MEVK/Yocto/Installing_an_Image


    2. WIC Command 사용 

    • wic list images 로 kickstart files 확인 
    // bitbake가 동작할 경우 같이 동작
    $ wic list images //*wks 들의 (short-description 정보)
      imx-uboot                                     Create SD card image with a boot partition
      mkhybridiso                                   Create a hybrid ISO image
      sdimage-bootpart                              Create SD card image with a boot partition
      directdisk                                    Create a 'pcbios' direct disk image
      qemux86-directdisk                            Create a qemu machine 'pcbios' direct disk image
      directdisk-gpt                                Create a 'pcbios' direct disk image
      systemd-bootdisk                              Create an EFI disk image with systemd-boot
      directdisk-multi-rootfs                       Create multi rootfs image using rootfs plugin
      directdisk-bootloader-config                  Create a 'pcbios' direct disk image with custom bootloader config
      mkefidisk                                     Create an EFI disk image
    


    • wic list images ( kickstart list 추가 )
    $ find . -name *wks*  // wks kickstart file 검색 
    ...
    sources/meta-freescale/wic/imx-uboot.wks // imx-uboot ,BSP 전용 WKS FILE 
    poky/scripts/lib/wic/canned-wks/*.wks  // 아래 일반적인 kickstart file로 아래의나열된것들 
    ....
    ....                                   // wks.in 파일은 생략 
    
    $ cp sources/meta-freescale/wic/imx-uboot.wks sources/meta-freescale/wic/upgrade.wks  // wks kickstart file 추가 
    
    $ vi sources/meta-freescale/wic/upgrade.wks //short-description 수정
    
    $ wic list images         //*wks 들의 (short-description 정보 재확인)
      upgrade                                      Create SD card image with a boot partition (Jeonghun) //추가확인
      imx-uboot                                     Create SD card image with a boot partition
      mkhybridiso                                   Create a hybrid ISO image
      sdimage-bootpart                              Create SD card image with a boot partition
      directdisk                                    Create a 'pcbios' direct disk image
      qemux86-directdisk                            Create a qemu machine 'pcbios' direct disk image
      directdisk-gpt                                Create a 'pcbios' direct disk image
      systemd-bootdisk                              Create an EFI disk image with systemd-boot
      directdisk-multi-rootfs                       Create multi rootfs image using rootfs plugin
      directdisk-bootloader-config                  Create a 'pcbios' direct disk image with custom bootloader config
      mkefidisk                                     Create an EFI disk image
    


    • 각 kickstart 세부정보파악 
    $ wic list imx-uboot help  // 상위 imx-uboot 정보 (long-description 정보)
    
    Create an image that can be written onto a SD card using dd for use
    with i.MX SoC family
    It uses u-boot
    
    The disk layout used is:
     - --------- --------------
    | | u-boot  |    rootfs    |
     - --------- --------------
    ^ ^         ^              ^
    | |         |              |
    0 1kiB    4MiB + rootfs + IMAGE_EXTRA_SPACE (default 10MiB)
    


    • Cooked Mode 기반으로 Image 생성
    존재하는 kickstart file 기반으로 Image 생성

    $ wic create upgrade -e core-image-base 
    Summary: There was 1 WARNING message shown.
    INFO: Creating image(s)...
    
    INFO: The new image(s) can be found here:
      ./upgrade-202005191127-mmcblk.direct  // 생성되는 FILE fdisk -l 로 확인 
    
    The following build artifacts were used to create the image(s):
      ROOTFS_DIR:                   /home/jhlee/yocto/build-fb/tmp/work/imx6sxsabresd-poky-linux-gnueabi/core-image-base/1.0-r0/rootfs
      BOOTIMG_DIR:                  /home/jhlee/yocto/build-fb/tmp/work/imx6sxsabresd-poky-linux-gnueabi/core-image-base/1.0-r0/recipe-sysroot/usr/share
      KERNEL_DIR:                   /home/jhlee/yocto/build-fb/tmp/deploy/images/imx6sxsabresd
      NATIVE_SYSROOT:               /home/jhlee/yocto/build-fb/tmp/work/cortexa9hf-neon-poky-linux-gnueabi/wic-tools/1.0-r0/recipe-sysroot-native
    
    INFO: The image(s) were created using OE kickstart file:
      /home/jhlee/yocto/imx-yocto-bsp/sources/meta-freescale/wic/upgrade.wks
    
    $ wic create imx-uboot -e core-image-base
    $ wic create mkefidisk -e core-image-minimal
    
    $ ls
    bitbake-cookerdaemon.log cache  conf  sstate-cache  tmp  upgrade-202005191127-mmcblk.direct
    
    $ wic ls upgrade-202005191127-mmcblk.direct // not working 
    $ cp upgrade-202005191127-mmcblk.direct upgrade-202005191127-mmcblk.direct.wic
    
    $ wic ls upgrade-202005191127-mmcblk.direct.wic // 확장자만 변경하면 동작 
    Num     Start        End          Size      Fstype
     1       4194304    193363967    189169664  ext4
    
    $ fdisk -l upgrade-202005191127-mmcblk.direct  
    Disk upgrade-202005191127-mmcblk.direct: 184.4 MiB, 193363968 bytes, 377664 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x2944b746
    
    Device                              Boot Start    End Sectors   Size Id Type
    upgrade-202005191127-mmcblk.direct1       8192 377663  369472 180.4M 83 Linux
    

    • wic는 두가지 방법으로 생성
    //Cooked Mode (kickstart File 기반)
    $ wic create wks_file -e IMAGE_NAME
    // Raw Mode 
    $ wic create wks_file options ( -e IMAGE_NAME , .. 모든부분을 다 설정해야함)
    

    일반적으로 최종 Image가 다 합쳐져서 나오므로, 특정 Image들을 별도로 분리할 생각이 있다면
    별도의 WKS FILE을 만들어서 Kickstart FILE로 등록한 후 생성하자 (Coocked Mode)
    처음부터 Raw Mode는 비추천하며, 차라리 Cooked Mode에서 Raw Mode 처럼 사용하는 방법을 사용하자

    • bitbake로 생성된 Image 분석 (wks.in기반)
    $ cp tmp/deploy/images/imx6sxsabresd/core-image-base-imx6sxsabresd.wic.bz2 .
    
    $ bzip2 -d ./core-image-base-imx6sxsabresd.wic.bz2
    
    $ wic ls core-image-base-imx6sxsabresd.wic
    Num     Start        End          Size      Fstype
     1       4194304     27491327     23297024  fat16
     2      29360128    259118079    229757952  ext4
     3     260046848    528482303    268435456  ext4
    
    $ wic ls core-image-base-imx6sxsabresd.wic:2  // Num 2 Partition 
    
    $ wic rm core-image-base-imx6sxsabresd.wic:2/mnt  // Num 2 Partition 
    


    2.1 WIC Image 의 정보분석 

    wic ls 를 이용하여 확인해도 되지만, wic는 yocto가 설정이 되었을 경우에만 사용가능하므로, 가능하면 fdisk를 이용하여 확인하자.

    • fdisk 를 이용하여 wic image 기본정보확인
    $ fdisk -l core-image-base-imx6sxsabresd.wic
    Disk core-image-base-imx6sxsabresd.wic: 504 MiB, 528482304 bytes, 1032192 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disklabel type: dos
    Disk identifier: 0x304dec68
    
    Device                             Boot  Start     End Sectors   Size Id Type
    core-image-base-imx6sxsabresd.wic1 *      8192   53859   45668  22.3M  c W95 FAT32 (LBA)
    core-image-base-imx6sxsabresd.wic2  57344  503031  445688 217.6M 83 Linux
    core-image-base-imx6sxsabresd.wic3      507904 1032191  524288   256M 83 Linux
    
    $ fdisk -l core-image-base-imx6sxsabresd.wic
    Disk core-image-base-imx6sxsabresd.wic: 504 MB, 528482304 bytes, 1032192 sectors
    64 cylinders, 255 heads, 63 sectors/track
    Units: sectors of 1 * 512 = 512 bytes
    
    Device                           Boot StartCHS    EndCHS        StartLBA     EndLBA    Sectors  Size Id Type
    core-image-base-imx6sxsabresd.wic1 *  64,0,1      420,3,4           8192      53859      45668 22.2M  c Win95 FAT32 (LBA)
    Partition 1 has different physical/logical start (non-Linux?):
         phys=(64,0,1) logical=(0,130,3)
    Partition 1 has different physical/logical end:
         phys=(420,3,4) logical=(3,89,58)
    core-image-base-imx6sxsabresd.wic2    448,0,1     1023,3,32        57344     503031     445688  217M 83 Linux
    Partition 2 has different physical/logical start (non-Linux?):
         phys=(448,0,1) logical=(3,145,15)
    Partition 2 has different physical/logical end:
         phys=(1023,3,32) logical=(31,79,40)
    core-image-base-imx6sxsabresd.wic3    1023,3,32   1023,3,32       507904    1032191     524288  256M 83 Linux
    Partition 3 has different physical/logical start (non-Linux?):
         phys=(1023,3,32) logical=(31,156,62)
    Partition 3 has different physical/logical end:
         phys=(1023,3,32) logical=(64,63,63)
    



    • Sector 정보기반으로 byte로 변환
    1. Start Sector ( 57344 * 512 = 29360128 )
    2. End Sector ( 503031 * 512 = 257551872 )
    3. Sectors or End Sector - Start Sector +1  (503031-57344+1 = 445688 * 512 = 228192256 )


    2.2  WIC Image mount 방법

    • wic image loop mount-1
    $ losetup -v -f -o 29360128 --sizelimit 228192256 core-image-base-imx6sxsabresd.wic
    or 
    $ losetup -f -o 29360128 core-image-base-imx6sxsabresd.wic  // busybox는 상위옵션 미지원 
    
    $ losetup -a   // show loop device status 
    /dev/loop0: 29360128 core-image-base-imx6sxsabresd.wic
    
    $ blkid /dev/loop0
    /dev/loop0: LABEL="root" UUID="051f84f1-7fe9-4adc-abcb-6b50651f66ed" TYPE="ext4"
    
    $ mount -o ro /dev/loop0 /mnt  // loop mount 
    $ ls /mnt
    bin         etc         lost+found  proc        sys         var
    boot        home        media       run         tmp
    dev         lib         mnt         sbin        usr
    
    $ losetup -d  /dev/loop0 // detach 
    

      https://www.computerhope.com/unix/losetup.htm
      https://dustymabe.com/2012/12/15/mounting-a-partition-within-a-disk-image/

    • wic image loop mount-2
    $ mount  -o ro,offset=$((512*57344)) core-image-base-imx6sxsabresd.wic /mnt
    $ umount /mnt 
    


    2.3 WIC Image Write 방법 과 분할 

    • mmcblk 정보확인
    $ fdisk -l /dev/mmcblk3
    Disk /dev/mmcblk3: 30 GB, 31826378752 bytes, 62160896 sectors
    971264 cylinders, 4 heads, 16 sectors/track
    Units: sectors of 1 * 512 = 512 bytes
    
    Device       Boot StartCHS    EndCHS        StartLBA     EndLBA    Sectors  Size Id Type
    /dev/mmcblk3p1 *  64,0,1      420,3,4           8192      53859      45668 22.2M  c Win95 FAT32 (LBA)
    /dev/mmcblk3p2  448,0,1     1023,3,32        57344     503031     445688  217M 83 Linux
    /dev/mmcblk3p3    1023,3,32   1023,3,32       507904    1032191     524288  256M 83 Linux
    

    Start Sector 와 Sector 갯수 정보로 dd를 이용하여 write 진행

    • wic image mmblk3p2 write 방법
    //skip : input  offset n bs 
    //seek : output offset n bs 
    //Sectors 445688 =  EndLBA-StartLBA+1 $((503031-57344+1))
    
    $ dd if=core-image-base-imx6sxsabresd.wic of=/dev/mmcblk3 bs=512 skip=57344 seek=57344 count=$((503031-57344+1)) conv=sync,noerror 
    $ dd if=core-image-base-imx6sxsabresd.wic of=/dev/mmcblk3 bs=512 skip=57344 seek=57344 count=445688 conv=sync,noerror 
    or 
    $ dd if=core-image-base-imx6sxsabresd.wic of=/dev/mmcblk3p2 bs=512 skip=57344 count=$((503031-57344+1)) && sync 
    $ dd if=core-image-base-imx6sxsabresd.wic of=/dev/mmcblk3p2 bs=512 skip=57344 count=445688 && sync 
    


      https://software.intel.com/en-us/node/721474
      https://developer.ridgerun.com/wiki/index.php?title=IMX8/iMX8MEVK/Yocto/Installing_an_Image

    • wic image 분할 저장 
    //bs   : 1 block bytes 
    //skip : input  offset n bs 
    //seek : output offset n bs 
    $ dd if=core-image-base-imx6sxsabresd.wic of=partition1_img   bs=512   skip=8192    count=45668  conv=sync,noerror 
    $ dd if=core-image-base-imx6sxsabresd.wic of=partition2_img   bs=512   skip=57344   count=445688 conv=sync,noerror 
    

    Image 와 함께 md5sum 혹은 다른 hashsum을 이용하여 이를 같이 보관하는 것이 좋다.

    dd option 설명
      https://www.gnu.org/software/coreutils/manual/html_node/dd-invocation.html

    2/25/2020

    Yocto 의 Layer Configuration 및 Machine/Distro Layer

    1.  Yocto의 Layer 구성 

    먼저 Yocto 에서 사용되어지는 Recipe 관련문법을 아래링크에서 기본으로 알고 구성하도록하자.

    Yocto 기본문법 과 이해 
      https://ahyuo79.blogspot.com/2020/01/raspberry-pi3-linux-yocto.html


    • Yocto Reference Manual 
    반드시 Yocto 각 버전별로 확인을 해야하며, Manaul 기반으로 이해하도록 하는 것을 권장한다. 

    Zeus(3.0)
    Warrior(2.7)
    Fido(1.8)


    1.1 Layer Configuration 구성 및 설정방법

    일반 Layer는 BBPATH 와 BBFILES을 설정을 해주고 각각의 BBFILES 관련정보를 설정해주는 역할로, 
    BBFILES, 즉 Recipe들을 기본동작을 가능하게 만들어준다.

    더불어 BB 관련된 설정을 넣어 각각의 동작을 조금씩 다르게 할 수 있으며, 
    별도의 설정을 하여 공통 변수를 공유하게 할 수 있다. 

    Reference Manual 참조(Layer 만들기)
      https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#creating-your-own-layer

    Layer를 쉽게 생성방법 


    • 직접 자신의 Layer 생성/설정/Recipe생성/구성  
    나의 경우는 Tool을 이용하기 보다는 아래와 같이 직접 손으로 구성하여 만드는 것을 선호한다.
    Tool로 하면 매번 필요없는 것들이 많아서 지우는게 많아 나는 직접 구성하는 것을 선호  
    $ cd sources  // Yocto Source로 이동  
    
    $ mkdir meta-test-jhlee   // Layer 이름 정함 (Layer 설정시 이름동일) 
    
    $ cd meta-test-jhlee    // 새로 생성한 Layer 이동 
    
    $ mkdir conf
    
    $ vi conf/local.conf    // Layer 설정 (아래 참조) 
    
    $ mkdir -p recipes-core/images                 // Recipe Directory  관리 
    
    $ vi recipes-core/images/core-image-jhlee.bb   // Recipe Directory  Image Recipe 생성 (아래 참조)
    
    $ mkdir -p recipes-test/jhlee-test1            // jhlee-test1 recipe용  
    $ mkdir -p recipes-test/jhlee-test2            // jhlee-test2 recipe용  
    $ mkdir -p recipes-test/jhlee-test3            // jhlee-test3 recipe용  
    
    $ vi LICENSE    // Layer LICENSE   
    $ vi README     // Layer README   
    $ vi README.md  // Layer 관리시 Github README   
    

    나중에는 Tool 이 더 좋아져서 Tool 기반으로 해야 할 걸로 생각되어지며, 이 부분은 추후 Yocto가 버전이 높아지면, 참고만 하도록 하자 

    • 상위 구성한 Layer 전체구성확인  
    상위에서 구성한 나의 Layer 의 전체구성을 확인하자 
    $ tree -t -L 2 --charset unicode
    .
    |-- recipes-core
    |   `-- images
    |-- recipes-test
    |   |-- jhlee-test1
    |   |-- jhlee-test2
    |   `-- jhlee-test3
    |-- LICENSE
    |-- README
    |-- README.md
    `-- conf
        `-- local.conf
    


    • Layer 설정 (conf/layer.con)
    일반 Layer의 기본목적은 다음과 같다.  
    1. Recipe 즉 BBFILE 관련설정 
    2. 해당 RECIPE들을 처리할 때 공통적으로 적용될 설정
    아래의 각 변수들은 Yocto Manual 반드시 참조하도록 
    $ vi conf/layer.conf
    ## BBPATH 에 LAYERDIR (meta-test-jhlee) 위치를 삽입 
    ## BB FILE들의 위치 (*.bb,*bbclass,**bbappend)
    # We have a conf and classes directory, add to BBPATH
    ## $ bitbake -e | grep ^BBPATH  로 확인가능 
    BBPATH .= ":${LAYERDIR}"
    
    ## BB FILE들을 찾는 법 (Recipe List)
    # We have recipes-* directories, add to BBFILES
    BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
     ${LAYERDIR}/recipes-*/*/*.bbappend"
    
    ## Layer List로 이것이 추가되면서 아래와 같이 이 이름기준으로 OVERRIDE됨 
    BBFILE_COLLECTIONS += "meta-test-jhlee"
    ### conf/layer.conf 에서 사용하며 반드시 suffix로 layer name 사용 
    BBFILE_PATTERN_meta-test-jhlee = "^${LAYERDIR}/"
    ### 아래명령어로 우선순위 확인가능  bitbake-layers show-layers
    BBFILE_PRIORITY_meta-test-jhlee = "9"
    # no problem in warrior version 
    # Jeonghun 
    ## 아래에서 Yocto의 Version 호환성
    LAYERSERIES_COMPAT_meta-test-jhlee = "warrior"
    

    Layer 기본구조
    아래의 Manual에서 기본구조를 파악하도록하자 

    • Image Recipe 설정 (자신만의 image) 
    나만의 image Recipe를 만들어서 나만의 Image 구성도 가능하며, 아래와 같이 해보도록 하자
    $ vi recipes-core/images/core-image-jhlee.bb
    ## IMAGE 관련 서술 
    SUMMARY = "Jeonghun Image TEST "
    
    ## core-image-base 기반으로 만들며, 다른것으로 변경하면됨 
    include recipes-core/images/core-image-base.bb
    
    ## 현재 내가 만든 Recipe들을 Image에 추가
    IMAGE_INSTALL += "binutils"
    
    IMAGE_INSTALL += "jhlee-test1 jhlee-test2 jhlee-test3"
    
    ## 상위 구성한 Layer를 추가한 후 각각의 Recipe들을 만들면 bitbake에서도 동작
    ## e.g bitbake core-image-jhlee 
    ## 
    export IMAGE_BASENAME = "core-image-jhlee"
    


    • 이후 작업 
    1. TEST 할 Recipe 구현 및 소스추가  
    2. User Configuration의 bblayers.conf에 상위 Layer 등록 
    3. source를 이용하여 기본설정 (build space 생성)
    4. bitbake로 테스트

    Recipe 관련 기본문법 및 OVERRIDES 설명

    Recipe 작성방법

    User Config에 상위 생성된 Layer 등록 (bblayers.conf)
      https://ahyuo79.blogspot.com/2020/02/yocto-user-configuration.html


    1.2 Machine Layer 분석 및 확인

    일반 Layer 구성방법과 거의 동일하며,  처음 conf/layer.conf 구성후  
    MACHINE 값에 따라 별도로 Machine Layer 가 설정된다
    물론 변수가 BSP 마다 조금씩 다르겠지만, 구성부터 살펴보자.

    아래는 NXP(Freescale)의 구성이며, 간단하게 분석해보자 
    $ cd sources      // Yocto Sources 이동
    
    $ tree -t -L 2 --charset unicode meta-fsl-bsp-release/imx/meta-bsp/conf/  
    meta-fsl-bsp-release/imx/meta-bsp/conf/   // i.MX BSP Layer 분석 
    |-- layer.conf        // 일반 Layer Recipe들 관리목적  
    `-- machine           // Machine Layer Folder 
        |-- imx6dlsabreauto.conf
        |-- imx6dlsabresd.conf
        |-- imx6qpdlsolox.conf
        |-- imx6qpsabreauto.conf
        |-- imx6qpsabresd.conf
        |-- imx6qsabreauto.conf
        |-- imx6qsabresd.conf
        |-- imx6slevk.conf
        |-- imx6sllevk.conf
        |-- imx6solosabreauto.conf
        |-- imx6solosabresd.conf
        |-- imx6sxsabreauto.conf
        |-- imx6sxsabresd.conf   // User Config의 local.conf의 MACHINE 정보 
        |-- imx6ul7d.conf
        |-- imx6ul9x9evk.conf
        |-- imx6ulevk.conf
        |-- imx6ull14x14evk.conf
        |-- imx6ull9x9evk.conf
        |-- imx6ulz14x14evk.conf
        |-- imx7d12x12lpddr3arm2.conf
        |-- imx7dsabresd.conf
        |-- imx7ulpevk.conf
        |-- imx8_all.conf
        |-- imx8dxlphantommek.conf
        |-- imx8mmddr3lval.conf
        |-- imx8mmddr4evk.conf
        |-- imx8mmddr4val.conf
        |-- imx8mmevk.conf
        |-- imx8mmlpddr4evk.conf
        |-- imx8mnevk.conf
        |-- imx8mqevk.conf
        |-- imx8qmddr4arm2.conf
        |-- imx8qmlpddr4arm2.conf
        |-- imx8qmmek.conf
        |-- imx8qxplpddr4arm2.conf
        |-- imx8qxpmek.conf
        `-- include               // Machine Layer 공통사항 Include  
    
    $ ls meta-fsl-bsp-release/imx/meta-bsp/  // 상위 layer.conf에 때문에 Recipe 동작 
    classes  recipes-bsp           recipes-core      recipes-graphics  recipes-multimedia  recipes-support  wic
    conf     recipes-connectivity  recipes-devtools  recipes-kernel    recipes-security    recipes-utils
    
    

    User Conf의 MACHINE 설정 과 Machine Layer 선택
      https://ahyuo79.blogspot.com/2020/02/yocto-user-configuration.html 

    • BSP Layer 의 conf/layer.conf 설정 
    상위에서 구현된 일반 Layer와 거의 유사하며, 다만 특정 값들을 설정 
    1. BBMASK를 이용하여 Recipe들을 제외
    2. HOSTTOOLS 관련설정을 별도로 진행 및 DISTRO 관련설정 
    $ vi meta-fsl-bsp-release/imx/meta-bsp/conf/layer.conf   // Recipe 관리목적 
    # We have a conf and classes directory, add to BBPATH
    BBPATH .= ":${LAYERDIR}"
    
    # We have a packages directory, add to BBFILES
    BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
                ${LAYERDIR}/recipes-*/*/*.bbappend"
    
    BBFILE_COLLECTIONS += "fsl-bsp-release"
    BBFILE_PATTERN_fsl-bsp-release := "^${LAYERDIR}"
    BBFILE_PRIORITY_fsl-bsp-release = "8"
    LAYERSERIES_COMPAT_fsl-bsp-release = "warrior"
    
    HOSTTOOLS_NONFATAL_append = " bc sha384sum xxd"
    
    # Enable optee for all builds using this layer, assuming the machine supports it.
    # To remove optee from the build, add the following line to local.conf:
    # DISTRO_FEATURES_remove = "optee"
    # DEPRECATED: The ability to remove optee from the build is deprecated and
    # will be removed in some future release.
    DISTRO_FEATURES_append = " optee"
    
    DISTRO_FEATURES_FILTER_NATIVESDK += "wayland"
    
    BBMASK += "meta-freescale/recipes-graphics/wayland/weston-init.bbappend"
    



    • BSP Layer의 include Machine Layer 
    Machine이 여러개이므로, 공통사항들의 설정을 공유하며, 내부적으로 또 공통사항을 Include함
    $ vi meta-fsl-bsp-release/imx/meta-bsp/conf/machine/include/imx6sabresd-common.inc
    # Provides the i.MX6 SABRE SD common settings
    
    ## meta-fsl-bsp-release/imx/meta-bsp/conf/machine/include/imx-base.inc 존재
    ## meta-fsl-bsp-release/imx/meta-bsp/conf/machine/include/tune-cortexa9.inc 없음 (현재 필요없음)
    #
    ## 아래의 require 파일들을 보면 WIC/WKS 를 비롯하여 UBOOT/KERNEL/IMAGE 설정 다양한 정보를 확인가능
    ## SOC_DEFAULT_WKS_FILE / WKS_FILE_DEPENDS / WKS_FILE / KERNEL_IMAGETYPE 
    require conf/machine/include/imx-base.inc
    require conf/machine/include/tune-cortexa9.inc
    
    SERIAL_CONSOLES = "115200;ttymxc0"
    
    MACHINE_FIRMWARE_append_mx6 = " linux-firmware-ath6k"
    
    MACHINE_FEATURES += " pci wifi bluetooth bcm4339 bcm43455"
    



    • BSP Layer의 Machine Layer 
    MACHINE에 의해 설정이 되며, 다시 MACHINE의 OVERRIDES 기능을 제공하여 변수선택
    $ vi meta-fsl-bsp-release/imx/meta-bsp/conf/machine/imx6sxsabresd.conf
    
    ## OVERRIDES 기능설정 mx6 과 mx6sx로 설정되며 이는 아래의 include에 영향을 미침 
    ## 아래와 같이 mx6x or mx6으로 변수설정 (conf/machine/include/imx-base.inc)
    #
    ## UBOOT_ENTRYPOINT_mx6  = "0x10008000"
    ## UBOOT_ENTRYPOINT_mx6sx = "0x80008000" 
    #
    ## MACHINEOVERRIDES_EXTENDER_mx6sx  = "imxfbdev:imxpxp:imxgpu:imxgpu2d:imxgpu3d" 
    ## MACHINE_SOCARCH_SUFFIX_mx6sx = "-mx6sx" 
    ## MACHINE_EXTRA_RRECOMMENDS_append_mx6sx = " ${@bb.utils.contains('DISTRO_FEATURES', 'alsa', 'imx-alsa-plugins', '', d)}"
    ## MACHINE_GSTREAMER_1_0_PLUGIN_mx6sx = "imx-gst1.0-plugin" 
    MACHINEOVERRIDES =. "mx6:mx6sx:"
    
    ## 상위 include/imx6sabresd-common.inc 참고 
    require conf/machine/include/imx6sabresd-common.inc
    
    ## KERNEL DEVICE TREE 설정 (UBOOT의 DEVICE TREE는 해당안됨) 
    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"
    
    MACHINE_FEATURES_append = " optee"
    
    ## 보통아래와 같이 사용 uboot-config.bbclass
    ##     UBOOT_CONFIG ??= 
    ##     UBOOT_CONFIG[foo] = "config,images"
    #
    ## UBOOT_CONFIG = emmc 이면 아래의 Kernel Config 설정 
    UBOOT_CONFIG ??= "${@bb.utils.contains('COMBINED_FEATURES', 'optee', 'sd-optee', 'sd', d)}"
    UBOOT_CONFIG[sd] = "mx6sxsabresd_config,sdcard"
    UBOOT_CONFIG[emmc] = "mx6sxsabresd_emmc_config,sdcard"
    UBOOT_CONFIG[qspi2] = "mx6sxsabresd_qspi2_config"
    UBOOT_CONFIG[m4fastup] = "mx6sxsabresd_m4fastup_config"
    UBOOT_CONFIG[mfgtool] = "mx6sxsabresd_config"
    UBOOT_CONFIG[sd-optee] = "mx6sxsabresd_optee_config,sdcard"
    
    OPTEE_BIN_EXT = "6sxsdb"
    

    KERNEL_DEVICE_TREE

    UBOOT
      https://www.yoctoproject.org/docs/latest/ref-manual/ref-manual.html#ref-classes-uboot-config



    1.3 Distro Layer 분석 및 확인

    일반 Layer 구성방법은 비슷하여 conf/layer.conf 구성후  DISTRO 값에 따라 별도로 Distro Layer 가 설정된다
    DISTRO 값이 빈 값이면, poky/meta/conf/distro/defaultsetup.conf 사용한다함  

    동일하게 Distro Layer의 구성확인
    $ cd sources      // Yocto Sources 이동
    
    $ tree -t -L 2 --charset unicode ./meta-fsl-bsp-release/imx/meta-sdk/conf/
    ./meta-fsl-bsp-release/imx/meta-sdk/conf/
    |-- layer.conf
    `-- distro
        |-- fsl-imx-fb.conf   // DISTRO 값에 의해 설정  
        |-- fsl-imx-wayland.conf
        |-- fsl-imx-x11.conf
        |-- fsl-imx-xwayland.conf
        |-- imx-wayland-ivi.conf
        `-- include
    
    $ tree -t -L 2 --charset unicode ./meta-fsl-bsp-release/imx/meta-sdk/conf/distro
    ./meta-fsl-bsp-release/imx/meta-sdk/conf/distro
    |-- fsl-imx-fb.conf      
    |-- fsl-imx-wayland.conf
    |-- fsl-imx-x11.conf
    |-- fsl-imx-xwayland.conf
    |-- imx-wayland-ivi.conf
    `-- include
        |-- fsl-imx-base.inc    // DISTRO Layer 확장  
        `-- fsl-imx-preferred-env.inc
    

    User Conf의 DISTRO 설정 과 Distro Layer 선택
      https://ahyuo79.blogspot.com/2020/02/yocto-user-configuration.html 
      


    $ vi ./meta-fsl-bsp-release/imx/meta-sdk/conf/layer.conf  // 일반 Layer (Recipe 관리, 상위설명참조)
    # We have a conf and classes directory, add to BBPATH
    BBPATH .= ":${LAYERDIR}"
    
    # We have a packages directory, add to BBFILES
    BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \
                ${LAYERDIR}/recipes-*/*/*.bbappend"
    
    BBFILE_COLLECTIONS += "fsl-sdk-release"
    BBFILE_PATTERN_fsl-sdk-release := "^${LAYERDIR}"
    BBFILE_PRIORITY_fsl-sdk-release = "8"
    LAYERSERIES_COMPAT_fsl-sdk-release = "warrior"
    
    # Add warrior to LAYERSERIERS_COMPAT for genivi layers until warrior branch
    # is created in upstream
    LAYERSERIES_COMPAT_ivi_append = " warrior"
    LAYERSERIES_COMPAT_ivitest_append = " warrior"
    LAYERSERIES_COMPAT_ivibsp_append = " warrior"
    
    BBFILES_DYNAMIC += " \
        browser-layer:${LAYERDIR}/dynamic-layers/browser-layer/*/*/*.bb \
        browser-layer:${LAYERDIR}/dynamic-layers/browser-layer/*/*/*.bbappend \
        \
        openembedded-layer:${LAYERDIR}/dynamic-layers/openembedded-layer/*/*/*.bb \
        openembedded-layer:${LAYERDIR}/dynamic-layers/openembedded-layer/*/*/*.bbappend \
        \
        qt5-layer:${LAYERDIR}/dynamic-layers/qt5-layer/*/*/*.bb \
        qt5-layer:${LAYERDIR}/dynamic-layers/qt5-layer/*/*/*.bbappend \
        \
        ivi:${LAYERDIR}/dynamic-layers/ivi/*/*/*.bb \
        ivi:${LAYERDIR}/dynamic-layers/ivi/*/*/*.bbappend \
        \
        ivitest:${LAYERDIR}/dynamic-layers/ivitest/*/*/*.bb \
        ivitest:${LAYERDIR}/dynamic-layers/ivitest/*/*/*.bbappend \
    "
    BBMASK += "meta-freescale/dynamic-layers/qt5-layer/recipes-qt/qt5/qtbase_%.bbappend"
    BBMASK += "meta-freescale-distro/recipes-fsl/packagegroups/packagegroup-fsl-tools-gpu-external.bb"
    BBMASK += "meta-ivi/meta-ivi/recipes-graphics/wayland/weston_%.bbappend"
    


    • Distro Layer 
    User Config의 DISTRO에 의해서 설정되었으며, DISTRO_FEATURES LIST 중 기능을 삭제
    $ vi ./meta-fsl-bsp-release/imx/meta-sdk/conf/distro/fsl-imx-fb.conf
    # i.MX DISTRO for the FrameBuffer graphical backend.
    
    include conf/distro/include/fsl-imx-base.inc
    include conf/distro/include/fsl-imx-preferred-env.inc
    
    DISTRO = "fsl-imx-fb"
    
    # Remove conflicting backends.
    DISTRO_FEATURES_remove = "x11 wayland directfb "
    

    DISTRO_FEATURES 에서 사용되는 LIST
      https://www.yoctoproject.org/docs/current/ref-manual/ref-manual.html#ref-features-distro

    • Distro Layer (Include)  
    상위에서 include 된 공통사항
    $ vi ./meta-fsl-bsp-release/imx/meta-sdk/conf/distro/include/fsl-imx-base.inc
    DISTRO = "fsl-imx"
    DISTRO_NAME = "NXP i.MX Release Distro"
    DISTRO_VERSION = "4.19-warrior"
    
    DISTRO_CODENAME = "warrior"
    SDK_VENDOR = "-pokysdk"
    SDK_VERSION := "${DISTRO_VERSION}"
    #SDK_VERSION := "${@'${DISTRO_VERSION}'.replace('snapshot-${DATE}','snapshot')}"
    
    MAINTAINER = "NXP "
    
    TARGET_VENDOR = "-poky"
    
    LOCALCONF_VERSION = "1"
    
    IMX_DEFAULT_DISTRO_FEATURES = "opengl ptest multiarch"
    # Enable vulkan distro feature only for mx8
    IMX_DEFAULT_DISTRO_FEATURES_append_mx8 = " vulkan"
    # Enable jailhouse distro feature only for mx8m
    IMX_DEFAULT_DISTRO_FEATURES_append_mx8m = " jailhouse"
    IMX_DEFAULT_EXTRA_RDEPENDS = "packagegroup-core-boot"
    IMX_DEFAULT_EXTRA_RRECOMMENDS = "kernel-module-af-packet"
    
    BBMASK += "poky/meta/recipes-graphics/vulkan/vulkan_1.1.73.0.bb"
    
    DISTRO_FEATURES ?= "${DISTRO_FEATURES_DEFAULT} ${DISTRO_FEATURES_LIBC} ${IMX_DEFAULT_DISTRO_FEATURES}"
    
    SDK_NAME = "${DISTRO}-${TCLIBC}-${SDK_ARCH}-${IMAGE_BASENAME}-${TUNE_PKGARCH}"
    SDKPATH = "/opt/${DISTRO}/${SDK_VERSION}"
    
    DISTRO_EXTRA_RDEPENDS += " ${IMX_DEFAULT_EXTRA_RDEPENDS}"
    DISTRO_EXTRA_RRECOMMENDS += " ${IMX_DEFAULT_EXTRA_RRECOMMENDS}"
    
    TCLIBCAPPEND = ""
    .....중략....
    
    $ vi ./meta-fsl-bsp-release/imx/meta-sdk/conf/distro/include/fsl-imx-preferred-env.inc
    
    # Set the preffered provider for opencl-headers
    PREFERRED_PROVIDER_opencl-headers_imx = "imx-gpu-viv"
    
    PREFERRED_VERSION_gstreamer1.0-plugins-base = "1.16.0.imx"
    PREFERRED_VERSION_gstreamer1.0-plugins-bad  = "1.16.0.imx"
    PREFERRED_VERSION_gstreamer1.0-plugins-good = "1.16.0.imx"
    PREFERRED_VERSION_gstreamer1.0              = "1.16.0.imx"
    
    # Use systemd as default init manager
    VIRTUAL-RUNTIME_init_manager = "systemd"
    PREFERRED_PROVIDER_udev = "systemd"
    "./meta-fsl-bsp-release/imx/meta-sdk/conf/distro/include/fsl-imx-preferred-env.inc" 58L, 2420C                                                1,1           Top
    # Use i.MX Kernel, U-Boot and Gstreamer 1.0 providers
    PREFERRED_PROVIDER_virtual/bootloader_imx = "u-boot-imx"
    #PREFERRED_PROVIDER_virtual/bootloader_mx6 = "u-boot-imx"
    #PREFERRED_PROVIDER_virtual/bootloader_mx6ul = "u-boot-imx"
    #PREFERRED_PROVIDER_virtual/bootloader_mx6sll = "u-boot-imx"
    #PREFERRED_PROVIDER_virtual/bootloader_mx7d = "u-boot-imx"
    #PREFERRED_PROVIDER_virtual/bootloader_mx7ulp = "u-boot-imx"
    
    PREFERRED_PROVIDER_virtual/kernel_imx = "linux-imx"
    #PREFERRED_PROVIDER_virtual/kernel_mx6 = "linux-imx"
    #PREFERRED_PROVIDER_virtual/kernel_mx6ul = "linux-imx"
    #PREFERRED_PROVIDER_virtual/kernel_mx6sll = "linux-imx"
    #PREFERRED_PROVIDER_virtual/kernel_mx7d = "linux-imx"
    #PREFERRED_PROVIDER_virtual/kernel_mx7ulp = "linux-imx"
    #PREFERRED_PROVIDER_virtual/kernel_imx7ulp_zebu = "linux-imx"
    
    PREFERRED_VERSION_linux-libc-headers_imx ?= "4.19"
    
    # Extra audio support
    # Add support for ALL i.MX6/7/8 SoC families
    MACHINE_EXTRA_RRECOMMENDS_append_imx = " ${@bb.utils.contains('DISTRO_FEATURES', 'alsa', 'imx-alsa-plugins', '', d)}"
    
    # Default toolchains used in testing i.MX BSPs
    DEFAULTTUNE_mx6   = "cortexa9hf-neon"
    DEFAULTTUNE_mx6ul = "cortexa7hf-neon"
    DEFAULTTUNE_mx6sll = "cortexa9hf-neon"
    DEFAULTTUNE_mx7d   = "cortexa7hf-neon"
    DEFAULTTUNE_mx7ulp = "cortexa7hf-neon"
    DEFAULTTUNE_mx8 = "aarch64"
    
    # Enable the kenrel loadable module as default
    USE_GPU_VIV_MODULE = "1"
    
    IMX_GPU_VERSION            ?= "6.4.0.p1.0"
    IMX_GPU_VERSION_SUFFIX      = "aarch32"
    IMX_GPU_VERSION_SUFFIX_mx8  = "aarch64"
    
    PREFERRED_VERSION_imx-gpu-viv               = "${IMX_GPU_VERSION}-${IMX_GPU_VERSION_SUFFIX}"
    PREFERRED_VERSION_kernel-module-imx-gpu-viv = "${IMX_GPU_VERSION}"
    PREFERRED_VERSION_imx-gpu-g2d               = "${IMX_GPU_VERSION}"
    
    # Set the preffered provider for opencl-headers
    PREFERRED_PROVIDER_opencl-headers_imx = "imx-gpu-viv"
    
    PREFERRED_VERSION_gstreamer1.0-plugins-base = "1.16.0.imx"
    PREFERRED_VERSION_gstreamer1.0-plugins-bad  = "1.16.0.imx"
    PREFERRED_VERSION_gstreamer1.0-plugins-good = "1.16.0.imx"
    PREFERRED_VERSION_gstreamer1.0              = "1.16.0.imx"
    
    # Use systemd as default init manager
    VIRTUAL-RUNTIME_init_manager = "systemd"
    PREFERRED_PROVIDER_udev = "systemd"
    PREFERRED_PROVIDER_udev-utils = "systemd"
    DISTRO_FEATURES_BACKFILL_CONSIDERED = "sysvinit"
    IMX_DEFAULT_DISTRO_FEATURES += " systemd"
    
    SOC_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT_mx6 = "1"
    SOC_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT_mx7ulp = "1"
    
    

    3.1.1. Creating Your Own Layer
      https://www.yoctoproject.org/docs/current/dev-manual/dev-manual.html#creating-your-own-distribution


    2. Yocto의 Layer 추가 방법 


    • Yocto에서 제공해주는 Layer 검색 (중요)
    Openembedded Site에서 제공해주고 있는 Layer들로 이곳에서 검색 후 이 git으로 download를 하면 쉽게 추가가능