Yocto에서 recipe가 존재하면, 아래와 같이 bitbake로 실행가능하며, 별도의 task가 존재한다면, -c 옵션을 이용하여 task도 실행가능하다.
그러므로 Yocto에서 원하는 Source를 수정하고 싶다면 반드시 Recipe 수정방법을 이해해야한다.
Yocto 기본 사용
https://ahyuo79.blogspot.com/2015/10/yocto.html
https://ahyuo79.blogspot.com/2015/10/imx6.html
https://ahyuo79.blogspot.com/2015/10/yocto.html
https://ahyuo79.blogspot.com/2015/10/imx6.html
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
Raspberry Pi기반 Yocto 구성
https://ahyuo79.blogspot.com/2018/02/raspberry-pi-systems-with-yoctohtml.html
https://ahyuo79.blogspot.com/2018/02/raspberry-pi-systems-with-yoctohtml.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
- config: fetch 된 상태, 즉 소스가 있는 상태에서 configuration 진행
- compile : config 후 compile 진행
- clean / cleanall: compile 부분 clean
- install : rootfs로 install
- 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 Name 과 Package 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 사용안할 경우 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로 구성
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 위치 설정
# 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의 구성
아래를 설정하지 않아도 기본으로 *.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 안에서 이를 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 개념
물론 암묵적으로 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 뒤에 추가가능
- do_configure(): Configure를 설정을 해줌
- do_compile() : 존재하지 않는다면, oe_runmake가 Makefile 찾아 자동 Build
- 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 적용
## 환경변수는 본인이 설정 do_configure_prepend() { export PATH="" } ## 환경변수는 본인이 설정 do_compile_prepend() { export PATH="" }
- Recipe 의 Task do_complie 없애고, Makefile 직접구성
$ 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 개념 및 설정
아래와 같이 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 방법
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 예제
$ 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 작성예제
## 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 의 차이
하지만 RDEPENDS의 경우는 이 Program이 Runtime으로 동작할때 필요한 Library가 필요할 경우 많이 사용한다.
이때 CFLAGS or LDFLAGS or CXXFLAGS를 같이 사용하여 관련 library를 추가하고 세부설정도 가능하다.
(주의: 스페이스로 반드시 이전 FLAGS정보와 분리)
일반적으로 상위 FLAGS들을 설정하면, 세부 플래그는 동일하게 설정되지만, 크로스 컴파일 환경이다보니, 세부적으로 조절해야 할 경우가 발생한다.
- TARGET_xxx : Target Device
- BUILD_xxx : Build Host i.e -native
- BUILDSDK_xxx: Build Host i.e. nativesdk-
- 상위 Recipe 작성 중 다양한 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 확인 및 설정확인
$ 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)
DTS 수정방법 두가지
- 최종 설정되는 dts 파일을 직접 수정 (맨 아래의 녹색 DTS파일)
- 새로 파일 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)
CONFIG_xxx =y 역시 중복설정가능하며 최종설정되는 값으로 진행되므로 cfg로 이전 설정을 변경이 가능하다.
수정방법
- 기본적으로 본인의 defconfig 직접수정하여 변경
- 추가로 *.cfg 파일을 생성
- Uboot의 Config 관련부분 Python 분석 (*.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)
$ 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)
$ 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 적용
- bitbake package -c diffconfig 이용하여 cfg 와 patch를 넣어 적용
- cfg 동작 안된다면, 소스를 분석하여 task에 넣어 강제설정
- 이것도 안되면 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 적용
- bitbake kernel_name -c diffconfig 이용하여 cfg 와 patch를 넣어 적용
- cfg 동작 안되다면 do_preconfigure_append or 다른 task로 강제설정
- 이것도 안되면 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 이 가능하다.
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
2.5 다양한 class와 task 이용한 Recipe 작성법
항상 본인이 사용하는 Yocto의 Version을 확인 한 후 해당 Manual 참조
bbclass 의 이해와 사용법 (inherit allarch , systemd, ... )
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
https://stackoverflow.com/questions/50906048/bitbake-recipes-simple-file-copy
https://github.com/DynamicDevices/bbexample/releases
https://github.com/DynamicDevices/bbexample/commit/5c58a861ca31710f6433487b8b0d590a43afd0ad
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
$ 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 구성
$ 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://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://stackoverflow.com/questions/50906048/bitbake-recipes-simple-file-copy
- Yocto의 다양한 Class 정보
- Yocto 의 다양한 Task
- Yocto 의 Kernel 관련된 Task
- BBexmple 의 예제
https://github.com/DynamicDevices/bbexample/releases
https://github.com/DynamicDevices/bbexample/commit/5c58a861ca31710f6433487b8b0d590a43afd0ad