基于Yocto Project为Juno板自定义Linux kernel和相关软件栈,并安装Sysdig
Tert-Butyllithium

作者:HiiragiKano(Github)

1.准备仓库

参考该文档的2.Prerequisites 和4.Syncing and Building software stack

repo init -u https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms-manifest.git -m juno-yocto.xml -b refs/tags/JUNO-2020.08.28 出现SyntaxError: invalid syntax错误**

原因是需要python3版本,但是修改Ubuntu的默认python为python3仍有后续问题.

解决:

  • Download last version of repo : curl https://storage.googleapis.com/git-repo-downloads/repo-1 > repo

  • Change right to make it executable : chmod a+x repo

  • Run your repo init with python3 and the “repo” you just download : python3 repo init -u [email protected]:xxx/xx_manifest.git -b xxx

因此最终使用如下命令初始化yocto仓库:

1
2
3
4
5
6
7
8
9
10
11
12
mkdir <workspace>
cd <workspace>
python3 repo init -u https://git.linaro.org/landing-teams/working/arm/arm-reference-platforms-manifest.git -m juno-yocto.xml -b refs/tags/JUNO-2020.08.28
python3 repo sync -j6

export DISTRO="poky"
export MACHINE="juno"
source setup-environment

//以后每次需要更改仓库需要在终端先执行6-8行设置环境后再进行

//bitbake core-image-minimal //!!!!!!先不要执行这一步!!!!!!

2.定制yocto

所有路径都假设当前在workspace目录下

增加包管理工具

./conf/juno/local.conf添加如下参数:

1
2
IMAGE_FEATURES += "package-management"
PACKAGE_CLASSES ?= 'package_rpm'

编译镜像

之后执行下面的那条命令开始编译一个带基本内核开发环境的镜像。

1
2
3
4
5
bitbake core-image-kernel-dev

//yocto 带有大量预配置的recipes,有需求的话可以按需修改。如:
core-image-kernel-dev.bb 在./layers/openembedded-core/meta/recipes-extended/images
core-image-minimal.bb 在./layers/openembedded-core/meta/recipes-core/images

该命令之后会自动下载所有的依赖源代码,包括内核,并编译。需要大量的时间,请耐心等待。当第一次成功后会建立cache,以后就很快了。

有时会出现个别task failed的问题。出现该问题的原因是因为网络问题导致下载的包源码错误,如遇到该问题,请根据终端的提示,确定失败的包,例如Binutil-2.30失败,则执行以下命令:

1
2
bitbake -c cleanall Binutil-2.30
bitbake Binutil-2.30

完成后再重新执行,会从上次进度继续

1
bitbake core-image-kernel-dev

配置Linux内核

当编译镜像步骤成功后,会在./build-poky/tmp-poky/deploy/images/juno生成我们需要的内核和根文件系统。但此时的内核还无法启动,直接放到juno板上会出现**starting kernel **卡死的问题。

因此我们需要config内核的编译选项。这里基于原版OE源码中的linux内核编译.config为基础修改进行了配置,下载该newconfig 重命名后覆盖linux内核源码编译目录,例如./build-poky/tmp-poky/work/juno-poky-linux/linux-yocto/5.4.50+gitAUTOINC+416566e1f0_94667198aa-r0/linux-juno-standard-build下的.config

之后按以下命令可以根据需求进一步配置,并编译和部署。

1
2
3
4
5
6
7
8
9
10
11
#config
bitbake -c menuconfig virtual/kernel

#compile
bitbake virtual/kernel -c compile -f

or try
bitbake virtual/kernel -C compile (to invalidate the stamps and force all tasks starting from do_compile)

#deploy
bitbake virtual/kernel -c deploy

3.安装

固件与内核

在./build-poky/tmp-poky/deploy/images/juno下,将固件firmware-image-juno.tar.gz下的所有内容解压到Juno Board的MMC SDcard。也可以继续用官方原版的固件,感觉没啥区别。

从./build-poky/tmp-poky/deploy/images/juno下找到编译出来的内核,例如Image--5.4.50+git0+416566e1f0_94667198aa-r0-juno-20210304043237.bin,重命名为Image并替换juno sdcard SOFTWARE目录中的内核

根文件系统

官方文档的根文件系统制作方法无效,在juno启动时会出现kernel panic.

因此手动准备一个U盘或硬盘。假设U盘为/dev/sdb,参考如下的格式和大小将U盘分为两个分区并格式化

1
2
/dev/sdb/sdb1 fat16 100MB
/dev/sdb/sdb2 ext4 剩下的所有容量

找到image下的rootfs压缩包,例如core-image-kernel-dev-juno-20210302135408.rootfs.tar.bz2,解压所有文件到sdb2下,可能需要用到sudo。

4.配置包管理环境

按以上步骤成功进入系统后,开始配置包管理环境。Yocto的包管理机制是利用yocto的host主机作为服务器端来成为repo 源,在target机器使用dnf工具来进行安装。

Juno端配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1.编辑/etc/dnf/dnf.conf,设置gpgcheck=0

2.set up the configuration
mkdir /etc/yum.repos.d
touch /etc/yum.repos.d/oe-packages.repo

3.Edit oe-packages.repo,要设为host机器的ip地址

[aarch64]
baseurl=http://10.11.9.3
name=aarch64
enabled=1

[juno]
baseurl=http://10.11.9.3
name=juno
enabled=1

[noarch]
baseurl=http://10.11.9.3
name=noarch
enabled=1


Host端配置

1
2
3
4
5
6
7
1.初始化包索引
bitbake package-index

2.进入`./build-poky/tmp-poky/deploy/rpm`目录

3.使用python3开启在`rpm`目录的http服务器
sudo python3 -m http.server --bind 10.11.9.3 80

Juno端使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#更新缓存
dnf makecache

#查找可以install的包
dnf info |grep "xxx"

#安装需要的包,如cmake
dnf install cmake

#intsall info里有的包失败,需要在host端先编译加入rpm,并更新索引,juno端需更新缓存
例如`mdadm`,可按如下步骤
在host端使用 `bitbake mdadm` 安装,接着用`bitbake package-index`更新索引
在juno端,用`dnf makecache`更新缓存,再尝试安装

#卸载包
dnf remove cmake

如果host的recpies没有配置所需的包,bitbake失败,则可以用下载源码到juno的方式来尝试解决

5.安装sysdig

在安装前,先提前配置juno的环境。

1.使用dnf 安装实验所需工具cmake, git, pkgconfig, openssh-sftp-server, python3-pip, gdb,vim

2.配置linux kernel编译环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#忽略
~~1.建立软连接,供依赖 uname -r的makefile查找
ln -s /lib/modules/5.4.50-yocto-standard/ /lib/modules/`name -r`~~


~~2.提前make modules 一次,解决后续编译driver出现找不到types.h的问题。
cd /lib/modules/5.4.50-yocto-standard/build
make ARCH=arm64 modules
最后会出现make error,不用管~~

3.因为无法安装glibc-static和libstdc++-static,将所需要的静态库手动拷贝到/usr/lib/,解决gcc_plgin编译失败的问题
下载[staticlib包](https://drive.google.com/file/d/1UlgCFt8RurHD_DN4PAyBD5-Mkqa0WZpR/view?usp=sharing),将所有.a文件拷贝到/usr/lib下

4.下载lua源码包[lua-5.1.5.tar.gz](https://drive.google.com/file/d/1fF59N1pcapGijFr8KC1n9Hg-_9u_Oleb/view?usp=sharing),make和make install

5.下载经过修改的[elfutils-0.63](https://drive.google.com/file/d/1p8kws2f8Ai1nBdXqmlsnTiiNuX9Dk5rR/view?usp=sharing),解压进入libelf目录,make和make install。解决libelf编译不通过和缺少libelf1 headers 的问题


3.编译安装sysdig

1
2
3
4
5
6
mkdir build
cd build
#不编译sysdig驱动,因为juno的/lib/modules/build目录存在许多问题,放弃在juno本机编译,留到后面在主机交叉编译
cmake -DUSE_BUNDLED_LUAJIT=OFF -DBUILD_DRIVER=OFF ..
make

在make执行到编译最后一个依赖grpc时,会出现编译失败的问题。因juno安装的系统的glibc库是2.3版本,sysdig使用到的grpc是1.8版本,该旧版本的gettid()函数和新版本的glibc2.3有冲突,需手动修复。而grpc的src会在make命令开始后才会下载,因此无法提前修改。请按以下链接的commit操作对三个相应的grpc源码文件进行修改。https://github.com/grpc/grpc/pull/18950/commits/57586a1ca7f17b1916aed3dea4ff8de872dbf853

  • 修改完成后重新执行make,会继续接着编译,最后应该就能顺利完成sysdig的构建。

  • 在Ubuntu主机交叉编译juno的驱动module。下载Arm官方的最新x86交叉编译工具链,至少9.3以上。yocto的交叉工具链gcc9.3在./build-poky/tmp-poky/sysroots-components/x86_64/gcc-cross-aarch64/usr/bin/aarch64-poky-linux/,但是缺少as,无法使用。

  • 将sysdig 的/driver文件夹单独拷贝到Ubuntu主机,修改/src/Makefile,将KERNELDIR 改为yocto仓库下的linux kernel目录,例如

KERNELDIR ?= /home/dog/Downloads/codework/yocto-juno/build-poky/tmp-poky/work/juno-poky-linux/linux-yocto/5.4.50+gitAUTOINC+416566e1f0_94667198aa-r0/linux-juno-standard-build/

  • 手动指定下载的交叉编译工具链,进行sysdig驱动编译,命令可参考如下:

make ARCH=arm64 CROSS_COMPILE=/home/dog/Downloads/codework/cross-gcc-compile/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-

  • 将编译好的驱动.ko拷到juno上,加载驱动,运行sysdig!
1
console=ttyAMA0,115200n8 root=/dev/sda2 rw rootwait earlycon=pl011,0x7ff80000 debug user_debug=31 androidboot.hardware=juno loglevel=9 iommu=memaper=3