Now I’m working on making a custom Linux OS for an embedded system and I’m quite new to this area. So I decided to write this note for future me and for digesting my learnings.
Building environment
I prepared a new laptop for a host machine because I use Mac usually and Mac is not the best option for my case. It is more stable to work in a similar environment to embedded Linux.
- Host
- Thinkpad T14s Gen 1
- Linux Ubuntu 22.04.2 LTS - Target
- Raspberry Pi CM4
Set up host Ubuntu
I downloaded packages to build images first after I installed Linux.
sudo apt-get install autoconf automake bison bzip2 cmake flex g++ gawk gcc gettext git gperf help2man libncurses5-dev libstdc++6 libtool libtool-bin make patch python3-dev rsync texinfo unzip wget xz-utils chrpath diffstat
One note. I tried to do it with a Linux trial account first for some reason (eventually, it didn’t work because of the lack of storage though). Then I got Unable to locate package
error and I ran the below commands following the article.
sudo add-apt-repository universe multiverse
sudo apt update
Apart from packages, I installed Etcher to flash images to a SD card, which I’ll need later, following the documents
what I did is install deb
file and run the command.
sudo apt install ./balena-etcher_******_amd64.deb
Build existing BSP
I started my Yocto journey by building an existing BSP for my Raspberry Pi. I googled the open-source BSP for RPI and found one which is officially supported by OpenEmbedded. I attached lists for any other BSP officially supported as well.
This is my first build so I tried to follow the procedures which the Yocto project officially shows as much as possible.
Install Yocto
First of all, I need to install Yocto (poky). When you install Yocto, you should choose the latest LTS version. In my case, it’s kirkstone
. You can check the latest version with the link.
Then move to my working directory and clone the repository.
git clone -b kirkstone git://git.yoctoproject.org/poky.git
Install layers
the RPI BSP (meta-raspberrypi) depends on meta-oe
and openembedded-core
. So we need two more layers, meta-openembedded
and meta-raspberrypoi
.
git clone -b kirkstone git://git.openembedded.org/meta-openembedded
git clone -b kirkstone git://git.yoctoproject.org/meta-raspberrypi
So now there are three layers (repositories) in my working directory.
Set up BitBake environment
BitBake is a build-tool, that Yocto Project takes. To run the BitBake command, I need to run the command.
source poky/oe-init-build-env build-rpi
The command sets up environment variables for BitBake and moves you to the build-rpi
directory. When you run it the first time, it creates the directory and moves you to the directory. When you run it a second time or later, it just moves you to the directory.
Add layers to my image
After setting up BitBake, it’s time to add the layers to my image.
1. bitbake-layers add-layer ../meta-openembedded/meta-oe
2. bitbake-layers add-layer ../meta-openembedded/meta-python
3. bitbake-layers add-layer ../meta-openembedded/meta-networking
4. bitbake-layers add-layer ../meta-openembedded/meta-multimedia
5. bitbake-layers add-layer ../meta-raspberrypi
I added meta-python
, meta-networking
, and meta-multimedia
because I’ll use connman
command to connect my RPI with my local wifi. meta-networking
and meta-multimedia
depend on meta-python
. The order does matter because of the dependency. I have to add dependent layers first.
CAUTION: I followed the instruction in the book but we might not need the dependency layers anymore onkirkstone
because they seem to depend on meta-oe
directly. I’ll check later but I’m focusing to go through all procedures for this time. So I’ll go with them unless I don’t have any problems.
One note. when I ran the bitbake-layers add-layer
command, it threw the below error to me.
$ bitbake-layers add-layer ../meta-openembedded/meta-oe
NOTE: Starting bitbake server...
ERROR: The following required tools (as specified by HOSTTOOLS) appear to be unavailable in PATH, please install them in order to proceed:
lz4c
ERROR: The following required tools (as specified by HOSTTOOLS) appear to be unavailable in PATH, please install them in order to proceed:
lz4c
I googled it quickly and found an issue. I fixed the error following the conversation. Basically, I need to install two more packages.
sudo apt-get install zstd lz4
Then I checked the result using the command and it looks like that.
$ bitbake-layers show-layers
NOTE: Starting bitbake server...
layer path priority
==========================================================================
meta /home/linux/poky/meta 5
meta-poky /home/linux/poky/meta-poky 5
meta-yocto-bsp /home/linux/poky/meta-yocto-bsp 5
meta-oe /home/linux/meta-openembedded/meta-oe 5
meta-python /home/linux/meta-openembedded/meta-python 5
meta-networking /home/linux/meta-openembedded/meta-networking 5
meta-multimedia /home/linux/meta-openembedded/meta-multimedia 5
meta-raspberrypi /home/linux/meta-raspberrypi 9
Also I can check it to see the conf/bblayers.conf
like below.
$ cat conf/bblayers.conf
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
BBLAYERS ?= " \
/home/linux/poky/meta \
/home/linux/poky/meta-poky \
/home/linux/poky/meta-yocto-bsp \
/home/linux/meta-openembedded/meta-oe \
/home/linux/meta-openembedded/meta-python \
/home/linux/meta-openembedded/meta-networking \
/home/linux/meta-openembedded/meta-multimedia \
/home/linux/meta-raspberrypi \
"
Change machine
I need to change the target machine before building. When I saw the support device of the BSP, I didn’t find the RPI CM 4 device name. Then I found the commit saying I can use raspberrypi4-64
for RPI CM 4.
So I set it as my target machine in conf/local.conf
file.
MACHINE = "raspberrypi4-64"
Set up for ssh
Append ssh-server-openssh
to the list of EXTRA_IMAGE_FEATURES
in your conf/local.conf
file to activate ssh server, which I’ll use later.
EXTRA_IMAGE_FEATURES ?= "debug-tweaks ssh-server-openssh"
Build image
Now I can build my first image. it took a few hours.
bitbake rpi-test-image
Loading cache: 100% | | ETA: --:--:--
Loaded 0 entries from dependency cache.
Parsing recipes: 100% |###########################################################################################################################################| Time: 0:01:13
Parsing of 2536 .bb files complete (0 cached, 2536 parsed). 3954 targets, 142 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
Build Configuration:
BB_VERSION = "2.0.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "ubuntu-22.04"
TARGET_SYS = "aarch64-poky-linux"
MACHINE = "raspberrypi4-64"
DISTRO = "poky"
DISTRO_VERSION = "4.0.11"
TUNE_FEATURES = "aarch64 armv8a crc cortexa72"
TARGET_FPU = ""
meta
meta-poky
meta-yocto-bsp = "kirkstone:84dd3d0e6c90656f2a7105aabd303a62fa49eeba"
meta-oe
meta-python
meta-networking
meta-multimedia = "kirkstone:346753705e49a2486867dc150181a1c7f4d69377"
meta-raspberrypi = "kirkstone:43683cb14b6afc144619335b3a2353b70762ff3e"
NOTE: Fetching uninative binary shim http://downloads.yoctoproject.org/releases/uninative/4.0/x86_64-nativesdk-libc-4.0.tar.xz;sha256sum=fd75b2a1a67a10f6b7d65afb7d0f3e71a63b0038e428f34dfe420bb37716558a (will check PREMIRRORS first)
Initialising tasks: 100% |########################################################################################################################################| Time: 0:00:03
Sstate summary: Wanted 1941 Local 0 Mirrors 0 Missed 1941 Current 0 (0% match, 0% complete)
NOTE: Executing Tasks
NOTE: Tasks Summary: Attempted 4744 tasks of which 0 didn't need to be rerun and all succeeded.
Then I flashed the wic.bz2
image in tmp/deploy/images/raspberrypi64-4/
directory with Etcher and inserted the SD cord into my RPI. Afterwards, I booted it up.
Set up WiFi
First of all, I needed to connect the RPI to my local internet to do ssh. So I used an Ethernet cable. The RPI could connect to the internet but I couldn’t do ssh connection on my Linux machine. (I need to check later) But it works with Mac so I decided to go with Mac only for connecting wifi
After connecting with Mac, I could do ssh with root@raspberrypi4–64.local
. Then the following commands are steps to connect wifi using connman
.
root@raspberrypi4-64:~# connmanctl
connmanctl> enable wifi
Enabled wifi
connmanctl> agent on
Agent registered
connmanctl> scan wifi
Scan completed for wifi
connmanctl> services
*AR Wired ethernet_xxxx
[MY_NETWORK] wifi_xxxx
connmanctl> connect wifi_xxxx
Agent RequestInput wifi_xxxx
Passphrase = [ Type=psk, Requirement=mandatory, Alternates=[ WPS ] ]
WPS = [ Type=wpspin, Requirement=alternate ]
Passphrase? [MY_PASSWORD]
Connected wifi_xxxx
connmanctl> services
*AR Wired ethernet_xxxx
*AR BT-STCPSX wifi_xxxx
connmanctl> quit
Create my custom layer
I tried to install ruby in my image as my practice because I’m a Ruby on Rails developer. So I created the directory for my custom layer.
$ bitbake-layers create-layer ../meta-ruby
NOTE: Starting bitbake server...
Add your new layer with 'bitbake-layers add-layer ../meta-ruby'
$ cd ../meta-ruby/
$ ls
conf COPYING.MIT README recipes-example
$ cat recipes-example/example/example_0.1.bb
SUMMARY = "bitbake-layers recipe"
DESCRIPTION = "Recipe created by bitbake-layers"
LICENSE = "MIT"
python do_display_banner() {
bb.plain("***********************************************");
bb.plain("* *");
bb.plain("* Example recipe created by bitbake-layers *");
bb.plain("* *");
bb.plain("***********************************************");
}
addtask display_banner before do_build
I’ll move back to the directory later. While I work on developing my layer, I’ll use another directory, in my case build-mine
. So I run the following commands to start developing my ruby layer.
source poky/oe-init-build-env build-mind
devtool add https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.2.tar.gz
Actually, I run the following command first. But it raised the error. The devtool
command seems to compute PN
and PV
variables from the URL. (I need to check later). So I changed the tarball URL consisting of the recipe name and version then it succeeded
devtool add ruby https://github.com/ruby/ruby/archive/refs/tags/v3_2_2.tar.gz
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/devtool5zi87oy_/ruby_refs/tags/v3.2.2.bb'
One more note. When I tried to add a new layer, it raised ModuleNotFoundError
. It needs setuptools
so I installed it.
$ devtool add https://github.com/ruby/ruby/archive/refs/tags/v3_2_2.tar.gz
NOTE: Starting bitbake server...
NOTE: Starting bitbake server...
Traceback (most recent call last):
File "/home/ats/projects/yocto/raspberry_pi/poky/scripts/recipetool", line 111, in <module>
ret = main()
File "/home/ats/projects/yocto/raspberry_pi/poky/scripts/recipetool", line 75, in main
scriptutils.load_plugins(logger, plugins, pluginpath)
File "/home/ats/projects/yocto/raspberry_pi/poky/scripts/lib/scriptutils.py", line 98, in load_plugins
plugin = load_plugin(name)
File "/home/ats/projects/yocto/raspberry_pi/poky/scripts/lib/scriptutils.py", line 87, in load_plugin
spec.loader.exec_module(mod)
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/home/ats/projects/yocto/raspberry_pi/poky/scripts/lib/recipetool/create_buildsys_python.py", line 11, in <module>
import setuptools.command.build_py
ModuleNotFoundError: No module named 'setuptools'
ERROR: Command 'script -e -q -c "recipetool --color=always create --devtool -o /tmp/devtoolwxcvcv6v 'https://github.com/ruby/ruby/archive/refs/tags/v3_2_2.tar.gz' -x /home/ats/projects/yocto/raspberry_pi/build-mine/workspace/sources/devtoolsrcwueswe6h" /dev/null' failed
apt-get install python3-setuptools
Then I opened the ruby recipe with devtool edit-recipe ruby
and was thinking about what to do. Based on the document, I need to inherit autotools
because ruby tarball files include Autotool to install.
So I added inherit autotools
to recipes-ruby/ruby/ruby_3.2.2.bb
. Then Yocto takes care of executing ./configure
and make
when installing.
Build my layer
Then I ran devtool build ruby
and I encountered a lot of problems here. I’ll show you one by one here.
I got the error and it threw from ruby configure.ac. It looks I need ruby in my host machine as well and set the path.
| checking for ruby... false
| configure: error: executable host ruby is required for cross-compiling
| NOTE: The following config.log files may provide further information.
| NOTE: /home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/core2-64-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/config.log
| ERROR: configure failed
| WARNING: exit code 1 from a shell command.
ERROR: Task (/home/ats/projects/yocto/raspberry_pi/build-mine/workspace/recipes/ruby/ruby_3.2.2.bb:do_configure) failed with exit code '1'
NOTE: Tasks Summary: Attempted 635 tasks of which 81 didn't need to be rerun and 1 failed.
So what I did is below. To install ruby and to set the ruby path in ruby_3.2.2.bb
when ./configure
is run
apt-get install ruby
# Specify any options you want to pass to the configure script using EXTRA_OECONF:
EXTRA_OECONF = "--with-baseruby=/usr/bin/ruby"
Then the previous error had gone. But another came. I’m not sure what happened to me exactly but I guess something wrong with ruby still because the build stage is still in do_populate_sysroot. So I built the assumption that the ruby path is different when building.
Log data follows:
| DEBUG: Executing python function extend_recipe_sysroot
| NOTE: Direct dependencies are ['/home/ats/projects/yocto/raspberry_pi/poky/meta/recipes-core/glibc/glibc_2.35.bb:do_populate_sysroot', '/home/ats/projects/yocto/raspberry_pi/poky/meta/recipes-devtools/gcc/gcc-cross_11.3.bb:do_populate_sysroot', '/home/ats/projects/yocto/raspberry_pi/poky/meta/recipes-devtools/gcc/gcc-runtime_11.3.bb:do_populate_sysroot', '/home/ats/projects/yocto/raspberry_pi/poky/meta/recipes-devtools/libtool/libtool-cross_2.4.7.bb:do_populate_sysroot', '/home/ats/projects/yocto/raspberry_pi/poky/meta/recipes-devtools/libtool/libtool-native_2.4.7.bb:do_populate_sysroot', 'virtual:native:/home/ats/projects/yocto/raspberry_pi/poky/meta/recipes-devtools/autoconf/autoconf_2.71.bb:do_populate_sysroot', 'virtual:native:/home/ats/projects/yocto/raspberry_pi/poky/meta/recipes-devtools/automake/automake_1.16.5.bb:do_populate_sysroot', 'virtual:native:/home/ats/projects/yocto/raspberry_pi/poky/meta/recipes-devtools/pseudo/pseudo_git.bb:do_populate_sysroot']
| NOTE: Installed into sysroot: []
| NOTE: Skipping as already exists in sysroot: ['glibc', 'gcc-cross-aarch64', 'gcc-runtime', 'libtool-cross', 'libtool-native', 'autoconf-native', 'automake-native', 'pseudo-native', 'linux-libc-headers', 'flex-native', 'xz-native', 'mpfr-native', 'gnu-config-native', 'gmp-native', 'zstd-native', 'texinfo-dummy-native', 'libmpc-native', 'binutils-cross-aarch64', 'zlib-native', 'libgcc', 'm4-native', 'gettext-minimal-native']
| DEBUG: Python function extend_recipe_sysroot finished
| DEBUG: Executing python function autotools_aclocals
| DEBUG: SITE files ['endian-little', 'bit-64', 'arm-common', 'arm-64', 'common-linux', 'common-glibc', 'aarch64-linux', 'common']
| DEBUG: Python function autotools_aclocals finished
| DEBUG: Executing shell function do_install
| NOTE: make -j 8 DESTDIR=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/image install
| BASERUBY = /usr/bin/ruby --disable=gems
| CC = aarch64-poky-linux-gcc -mcpu=cortex-a57 -march=armv8-a+crc -fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/recipe-sysroot
| LD = aarch64-poky-linux-ld --sysroot=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/recipe-sysroot
| LDSHARED = aarch64-poky-linux-gcc -mcpu=cortex-a57 -march=armv8-a+crc -fstack-protector-strong -O2 -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/recipe-sysroot -shared
| CFLAGS = -O2 -pipe -g -feliminate-unused-debug-types -fmacro-prefix-map=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0=/usr/src/debug/ruby/3.2.2-r0 -fdebug-prefix-map=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0=/usr/src/debug/ruby/3.2.2-r0 -fdebug-prefix-map=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/recipe-sysroot= -fdebug-prefix-map=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/recipe-sysroot-native=
| XCFLAGS = -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-strong -mbranch-protection=pac-ret -fno-strict-overflow -fvisibility=hidden -fexcess-precision=standard -DRUBY_EXPORT -fPIE -I. -I.ext/include/aarch64-linux-gnu -I../../../../../../workspace/sources/ruby/include -I../../../../../../workspace/sources/ruby -I../../../../../../workspace/sources/ruby/enc/unicode/15.0.0
| CPPFLAGS =
| DLDFLAGS = -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -fmacro-prefix-map=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0=/usr/src/debug/ruby/3.2.2-r0 -fdebug-prefix-map=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0=/usr/src/debug/ruby/3.2.2-r0 -fdebug-prefix-map=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/recipe-sysroot= -fdebug-prefix-map=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/recipe-sysroot-native= -Wl,-z,relro,-z,now -Wl,--compress-debug-sections=zlib -fstack-protector-strong -pie
| SOLIBS = -lrt -lrt -ldl -lm -lpthread
| LANG =
| LC_ALL = en_US.UTF-8
| LC_CTYPE =
| MFLAGS = -j8 --jobserver-auth=4,5
| RUSTC = no
| YJIT_RUSTC_ARGS = --crate-name=yjit --crate-type=staticlib --edition=2021 -g -C opt-level=3 -C overflow-checks=on '--out-dir=/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/yjit/target/release/' ../../../../../../workspace/sources/ruby/yjit/src/lib.rs
| generating enc.mk
| aarch64-poky-linux-gcc (GCC) 11.3.0
| Copyright (C) 2021 Free Software Foundation, Inc.
| This is free software; see the source for copying conditions. There is NO
| warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| making srcs under enc
| making enc
| make[1]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| make[1]: Nothing to be done for 'enc'.
| make[1]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| make[1]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| make[1]: Nothing to be done for 'srcs'.
| make[1]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| generating transdb.h
| transdb.h unchanged
| generating makefiles ext/configure-ext.mk
| making trans
| ext/configure-ext.mk updated
| make[1]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| make[1]: Nothing to be done for '../../../../../../workspace/sources/ruby/enc/trans'.
| make[1]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| making encs
| make[1]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| make[1]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| make[1]: Nothing to be done for 'encs'.
| make[1]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| make[1]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| generating makefile exts.mk
| exts.mk updated
| make[1]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/-test-/bug-3571'
| linking shared-object -test-/bug_3571.so
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/-test-/bug-3571'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/-test-/st/foreach'
| linking shared-object -test-/st/foreach.so
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/bigdecimal'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/-test-/st/foreach'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/digest'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/bigdecimal'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/coverage'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/date'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/io/nonblock'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/coverage'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/io/console'
| linking shared-object io/nonblock.so
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/json'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/date'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/digest'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/io/console'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/io/wait'
| linking shared-object io/wait.so
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/monitor'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/nkf'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/monitor'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/pathname'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/json'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/nkf'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/objspace'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/pathname'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/pty'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/io/nonblock'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/rubyvm'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/pty'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/objspace'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/rubyvm'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/io/wait'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/syslog'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/.bundle/gems/debug-1.7.1/ext/debug'
| make[2]: /home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/image/usr/bin/ruby: No such file or directory
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/.bundle/gems/rbs-2.8.2/ext/rbs_extension'
| make[2]: /home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/image/usr/bin/ruby: No such file or directory
| make[2]: *** [Makefile:214: gemlib] Error 127
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/.bundle/gems/debug-1.7.1/ext/debug'
| make[1]: *** [exts.mk:300: .bundle/gems/debug-1.7.1/ext/debug/all] Error 2
| make[1]: *** Waiting for unfinished jobs....
| make[2]: *** [Makefile:214: gemlib] Error 127
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/.bundle/gems/rbs-2.8.2/ext/rbs_extension'
| make[1]: *** [exts.mk:302: .bundle/gems/rbs-2.8.2/ext/rbs_extension/all] Error 2
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/syslog'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/ripper'
| make[2]: Entering directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/socket'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/ripper'
| make[2]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2/ext/socket'
| make[1]: Leaving directory '/home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/ruby-3.2.2'
| make: *** [uncommon.mk:331: build-ext] Error 2
| ERROR: oe_runmake failed
| WARNING: exit code 1 from a shell command.
ERROR: Task (/home/ats/projects/yocto/raspberry_pi/build-mine/workspace/recipes/ruby/ruby_3.2.2.bb:do_install) failed with exit code '1'
NOTE: Tasks Summary: Attempted 637 tasks of which 634 didn't need to be rerun and 1 failed.
So I tried to build in native so that I didn’t have to care about path in different environments. So I set DEPENDS = "native"
in my recipe file and remove the ruby path which I set right before.
Then the error had gone. I was glad my assumption was kind of correct. And another came. The error was happening because Yocto didn’t find the right path to place ruby ri
and rod
file. I think I could set the path for them but basically, they are documentation files so I just removed them to solve the error.
Please set FILES such that these items are packaged. Alternatively if they are unneeded, avoid installing them or delete them within do_install.
ruby: 13547 installed and not shipped files. [installed-vs-shipped]
ERROR: ruby-3.2.2-r0 do_package: Fatal QA errors were found, failing task.
ERROR: Logfile of failure stored in: /home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/temp/log.do_package.3992874
ERROR: Task (/home/ats/projects/yocto/raspberry_pi/build-mine/workspace/recipes/ruby/ruby_3.2.2.bb:do_package) failed with exit code '1'
I set just an option for autotool.
EXTRA_OECONF = "--disable-install-doc"
Then the error had gone. But another came. I’m not sure what was happening to me again. I saw something wrong with pkgconfing in my detailed log. So I googled quickly and found the code snippets. I just copied and pasted without thinking further (I know I’m bad. I need to check later). Then the error had gone.
NOTE: ruby: compiling from external source tree /home/ats/projects/yocto/raspberry_pi/build-mine/workspace/sources/ruby
ERROR: ruby-3.2.2-r0 do_populate_sysroot: QA Issue: ruby-3.2.pc failed sanity test (tmpdir) in path /home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/sysroot-destdir/usr/lib/pkgconfig [pkgconfig]
ERROR: ruby-3.2.2-r0 do_populate_sysroot: QA staging was broken by the package built above
ERROR: Logfile of failure stored in: /home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/temp/log.do_populate_sysroot.4046588
ERROR: Task (/home/ats/projects/yocto/raspberry_pi/build-mine/workspace/recipes/ruby/ruby_3.2.2.bb:do_populate_sysroot) failed with exit code '1'
do_install:append:class-target () {
sed -i -e 's|${DEBUG_PREFIX_MAP}||g' \
${D}${libdir}/pkgconfig/*.pc
}
Then my devtool build ruby
returns succeeded. These are more like installing packages on Linux rather than Yocto, I think.
Deploy my image to RPI
To test the image I deployed it onto my RPI and it looked working!
$ devtool deploy-target ruby root@raspberrypi4-64.local
NOTE: Starting bitbake server...
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |#####################################################################################################################################################| Time: 0:00:00
Loaded 1644 entries from dependency cache.
Parsing recipes: 100% |###################################################################################################################################################| Time: 0:00:00
Parsing of 886 .bb files complete (883 cached, 3 parsed). 1647 targets, 56 skipped, 0 masked, 0 errors.
INFO: Successfully deployed /home/ats/projects/yocto/raspberry_pi/build-mine/tmp/work/cortexa57-poky-linux/ruby/3.2.2-r0/image
$ ssh root@raspberrypi4-64.local
Last login: Wed Jul 19 16:32:24 2023 from fe80::460:881e:1fdb:9351%wlan0
root@raspberrypi4-64:~# ruby -v
ruby 3.2.2 (2023-07-19 revision 3eef43e5b7) [aarch64-linux-gnu]
Merge the recipe to meta-ruby
devtool finish
command takes responsibility for merging. Easy.
$ devtool finish -f ruby ../meta-ruby/
NOTE: Starting bitbake server...
WARNING: Source tree is not clean, continuing as requested by -f/--force
NOTE: Reconnecting to bitbake server...
NOTE: Retrying server connection (#1)...
Loading cache: 100% |#####################################################################################################################################################| Time: 0:00:00
Loaded 1644 entries from dependency cache.
Parsing recipes: 100% |###################################################################################################################################################| Time: 0:00:00
Parsing of 886 .bb files complete (883 cached, 3 parsed). 1647 targets, 56 skipped, 0 masked, 0 errors.
WARNING: Specified destination layer is not currently enabled in bblayers.conf, so the ruby recipe will now be unavailable in your current configuration until you add the layer there
INFO: No patches or files need updating
INFO: Moving recipe file to /home/ats/projects/yocto/raspberry_pi/meta-ruby/recipes-ruby/ruby
INFO: Leaving source tree /home/ats/projects/yocto/raspberry_pi/build-mine/workspace/sources/ruby as-is; if you no longer need it then please delete it manually
Add layers to RPI image
Do what I did to meta-openembedded
before. Nothing different.
$ source poky/oe-init-build-env build-rpi/
### Shell environment set up for builds. ###
You can now run 'bitbake <target>'
Common targets are:
core-image-minimal
core-image-full-cmdline
core-image-sato
core-image-weston
meta-toolchain
meta-ide-support
You can also run generated qemu images with a command like 'runqemu qemux86'
Other commonly useful commands are:
- 'devtool' and 'recipetool' handle common recipe tasks
- 'bitbake-layers' handles common layer tasks
- 'oe-pkgdata-util' handles common target package tasks
$ bitbake-layers add-layer ../meta-ruby/
NOTE: Starting bitbake server...
$ bitbake-layers show-layers
NOTE: Starting bitbake server...
layer path priority
==========================================================================
meta /home/ats/projects/yocto/raspberry_pi/poky/meta 5
meta-poky /home/ats/projects/yocto/raspberry_pi/poky/meta-poky 5
meta-yocto-bsp /home/ats/projects/yocto/raspberry_pi/poky/meta-yocto-bsp 5
meta-oe /home/ats/projects/yocto/raspberry_pi/meta-openembedded/meta-oe 5
meta-python /home/ats/projects/yocto/raspberry_pi/meta-openembedded/meta-python 5
meta-networking /home/ats/projects/yocto/raspberry_pi/meta-openembedded/meta-networking 5
meta-multimedia /home/ats/projects/yocto/raspberry_pi/meta-openembedded/meta-multimedia 5
meta-raspberrypi /home/ats/projects/yocto/raspberry_pi/meta-raspberrypi 9
meta-ruby /home/ats/projects/yocto/raspberry_pi/meta-ruby 6
I need to add the ruby
image to conf/local.conf
. I’m not sure but I think I can replace IMAGE_INSTALL
with RDEPENDS
because my ruby image is just package, not including booting system, kernel, or rootfile system like image.
# Add this to conf/local.conf
IMAGE_INSTALL:append = " ruby"
Then I built it again but I got one error which is similar to the issue.
$ bitbake rpi-test-image
Loading cache: 100% | | ETA: --:--:--
Loaded 0 entries from dependency cache.
Parsing recipes: 100% |###################################################################################################################################################| Time: 0:00:56
Parsing of 2537 .bb files complete (0 cached, 2537 parsed). 3955 targets, 142 skipped, 0 masked, 0 errors.
NOTE: Resolving any missing task queue dependencies
Build Configuration:
BB_VERSION = "2.0.0"
BUILD_SYS = "x86_64-linux"
NATIVELSBSTRING = "universal"
TARGET_SYS = "aarch64-poky-linux"
MACHINE = "raspberrypi4-64"
DISTRO = "poky"
DISTRO_VERSION = "4.0.11"
TUNE_FEATURES = "aarch64 armv8a crc cortexa72"
TARGET_FPU = ""
meta
meta-poky
meta-yocto-bsp = "kirkstone:84dd3d0e6c90656f2a7105aabd303a62fa49eeba"
meta-oe
meta-python
meta-networking
meta-multimedia = "kirkstone:346753705e49a2486867dc150181a1c7f4d69377"
meta-raspberrypi = "kirkstone:43683cb14b6afc144619335b3a2353b70762ff3e"
meta-ruby = "master:132de2113718e279bfc9bbee6c420bd3fdd70091"
Initialising tasks: 100% |################################################################################################################################################| Time: 0:00:03
Sstate summary: Wanted 18 Local 0 Mirrors 0 Missed 18 Current 1939 (0% match, 99% complete)
Removing 2 stale sstate objects for arch raspberrypi4_64: 100% |##########################################################################################################| Time: 0:00:00
NOTE: Executing Tasks
WARNING: ruby-3.2.2-r0 do_populate_lic: QA Issue: ruby: No generic license file exists for: Unknown in any provider [license-exists]
ERROR: ruby-3.2.2-r0 do_package_qa: QA Issue: ruby: /usr/bin/ruby contains probably-redundant RPATH /usr/lib [useless-rpaths]
ERROR: ruby-3.2.2-r0 do_package_qa: Fatal QA errors were found, failing task.
ERROR: Logfile of failure stored in: /home/ats/projects/yocto/raspberry_pi/build-rpi/tmp/work/cortexa72-poky-linux/ruby/3.2.2-r0/temp/log.do_package_qa.4089639
ERROR: Task (/home/ats/projects/yocto/raspberry_pi/meta-ruby/recipes-ruby/ruby/ruby_3.2.2.bb:do_package_qa) failed with exit code '1'
NOTE: Tasks Summary: Attempted 4773 tasks of which 4733 didn't need to be rerun and 1 failed.
Summary: 1 task failed:
/home/ats/projects/yocto/raspberry_pi/meta-ruby/recipes-ruby/ruby/ruby_3.2.2.bb:do_package_qa
Summary: There was 1 WARNING message.
Summary: There were 2 ERROR messages, returning a non-zero exit code.
It is related to RPATH so that I just disable the rpath of ruby in conf/local.conf
.
EXTRA_OECONF = "\
--disable-install-rdoc \
--disable-rpath \
"
Then I finally built my cutom image including ruby. It’s is quite hard to follow first but I’m getting used to Yocto little by little through the exercise.
Yocto is very interesting! That’s it!
Appendix — my random notes
- Yocto が図解されててわかりやすい -> https://qiita.com/AngryMane/items/61d2fa47246a9f9217f5
- SDKs and drivers: https://rockchips-my.sharepoint.com/:f:/g/personal/lin_huang_rockchips_onmicrosoft_com/Ek7xdRT4fjZNtTMTiP_Wv4wB7YR8LDzUo3xcexcnnktUHA?e=NOgubm
- Rockchip で Yocto を動かせれば Balena が動く -> https://docs.balena.io/reference/OS/customer-board-support/
- examples
- cousera repo -> https://github.com/cu-ecen-aeld/ldd3
- linux official repo -> https://github.com/torvalds/linux/tree/master
- driver versions -> https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/devices.txt
- ls -la /dev/ -> check drivers major minor versions -> major: driver, mainor: deivce
- /dev -> kernel space -> list drivers
- cat /proc/devices -> list devices and drivers
- awk "\$2==\"loop\" {print \$1}" /proc/devices -> get major number of 'loop' driver
- insmod -> registar module/driver to /proc/devices
- mknod -> registar module/driver to root filesystem -> registar in /dev -> available by user space
- yocto quick starter docs -> https://docs.yoctoproject.org/2.0/yocto-project-qs/yocto-project-qs.html
- yocto kernel development manual -> https://docs.yoctoproject.org/kernel-dev/index.html
- qemu -> https://www.aps-web.jp/academy/18673/
- simple kernel driver -> https://qiita.com/kure/items/168c79ade50ad5c321a4
- check linux kernel driver source code -> https://elixir.bootlin.com
- gdb -> C language command line debugger -> https://qiita.com/arene-calix/items/a08363db88f21c81d351
- printk is most common way to debbug in kernel develompment
- printf belongs to userspace library
- linus is not useful
- time consuming should be avoided
- compile with CONFIG_DEBUG_INFO
- dmesg -> print kernel message from /proc/kmsg -> https://atmarkit.itmedia.co.jp/ait/articles/1612/20/news023.html
- klogd and syslogd
- strace cat /dev/kmsg -> trace systme calls and interactions between user space program and the driver (kmsg in this case)
- kernel driver development blog -> https://qiita.com/iwatake2222/items/1fdd2e0faaaa868a2db2
- kmemleak -> check memory leak in kernel
- bash -x ./hoge.sh -> show debugs during exectuion of hoge.sh
- ioctl -> interfaces to device other than read/write
- wait_event, wake_up -> macro for makeing drivers sleep
- 参考: https://git.yoctoproject.org/poky/plain/meta/recipes-devtools/ruby/ruby_3.2.2.bb