Linux

【ZynqMP】2.認定Ubuntuのカーネルビルド

1.記事一覧

記事は複数回に分けて投稿する予定です。AMD/XilinxのARM64 SoC(ZynqMP Kria K26 SOM)で動作する、AMD/Xilinx公式認定Ubuntuやベアメタル開発を勉強していく覚書きです。

Zynq7000(armv7)版はこちら

2.【概要】Arm64 Ubuntu用カーネルをビルドする

XilinxのKria K26 SOMボードを搭載した公式評価ボード、KR260を用いたLinuxの勉強記事です。

このボード向けに配布されている、Xilinx認定Ubuntu22.04で開発をする上で、kernelの機能が足りなかったり、kernel configの設定を変更したい場合にlinux kernelのソースコードをリビルドする必要があります。

今回は公式の内容に沿ってビルドを行ってみたいと思います。ただし、私はDocker上で行うことにします。ちなみにビルド時間はそれなりにかかります。

今回使用する環境

開発PC Ubuntu20.04 LTS (ただし、Docker Ubuntu22.04imageを使用)
(以下ビルド時間の参考に。ビルド時間2時間45分)
CPU : 初代 intel core i5 750 (2010) 2.67GHz, 4C/4T
DRAM : DDR3 1333MHz 16GB
開発ツールapt-get build-dep :
 linux
apt-get install :
 fakeroot
 libncurses-dev
 gcc-aarch64-linux-gnu
 linux-tools-common
Docker-ce : version 24.0.5, build ced0996
Docker image : Ubuntu22.04 image
ターゲットボードXilinx社製 Kria KR260 ロボティクススターターキット(SK-KR260-G)
SOM : Xilinx社 Kria K26 SOM (Zynq UltraScale+ MPSoCベース)
   APU : Arm CA53x4 1333MHz arm64
   RPU : Arm CR5x2 533MHz armv7-R
SDRAM : DDR4 4GB
QSPI Firmware : Xilinx download – 2022.2_update1_BOOT.BIN
Linux Kernel : v5.15.0-1023-xilinx-zynqmp by 認定Ubuntu
OS : Xilinx認定Ubuntu22.04 LTS(arm64)

3.Dockerコンテナ準備

Ubuntu22.4コンテナイメージを使用して、ビルドコンテナを用意します。Dockerfileは記事の最後に貼っておきます。

$ ls
Dockerfile
$ docker image build ./ -t ub2204/kbuild

コンテナを起動します。

$ docker run --name "ubarm64build" -it "ub2204/kbuild" /bin/bash
user@15398cedc1c8:~$  cat /etc/os-release 
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

4.ビルド環境準備

公式のやり方に沿って準備します。公式は20.04focalでやっているので22.04jammyに適宜修正します。

4-1. ソースパッケージリポジトリの追加

まずはソースパッケージリポジトリを有効にします

$ echo "deb-src http://archive.ubuntu.com/ubuntu jammy main" | sudo tee -a /etc/apt/sources.list.d/jammy.list
$ sudo apt-get update

4-2. Linuxビルドパッケージの準備

aptでビルドパッケージを入れます。途中タイムゾーンが聞かれます。6と79を入力します。前者がAsia,後者がTokyoです。

$ sudo apt-get build-dep linux
[...]
Please select the geographic area in which you live. Subsequent configuration questions will narrow this down by presenting a list of cities, representing the time zones in which they are located.

  1. Africa  2. America  3. Antarctica  4. Australia  5. Arctic  6. Asia  7. Atlantic  8. Europe  9. Indian  10. Pacific  11. US  12. Etc
Geographic area: 6
[...]
Please select the city or region corresponding to your time zone.

  1. Aden      9. Baghdad   17. Chita       25. Dushanbe     33. Irkutsk    41. Kashgar       49. Macau         57. Omsk        65. Rangoon        73. Taipei    81. Ujung_Pandang  89. Yekaterinburg
  2. Almaty    10. Bahrain  18. Choibalsan  26. Famagusta    34. Istanbul   42. Kathmandu     50. Magadan       58. Oral        66. Riyadh         74. Tashkent  82. Ulaanbaatar    90. Yerevan
  3. Amman     11. Baku     19. Chongqing   27. Gaza         35. Jakarta    43. Khandyga      51. Makassar      59. Phnom_Penh  67. Sakhalin       75. Tbilisi   83. Urumqi
  4. Anadyr    12. Bangkok  20. Colombo     28. Harbin       36. Jayapura   44. Kolkata       52. Manila        60. Pontianak   68. Samarkand      76. Tehran    84. Ust-Nera
  5. Aqtau     13. Barnaul  21. Damascus    29. Hebron       37. Jerusalem  45. Krasnoyarsk   53. Muscat        61. Pyongyang   69. Seoul          77. Tel_Aviv  85. Vientiane
  6. Aqtobe    14. Beirut   22. Dhaka       30. Ho_Chi_Minh  38. Kabul      46. Kuala_Lumpur  54. Nicosia       62. Qatar       70. Shanghai       78. Thimphu   86. Vladivostok
  7. Ashgabat  15. Bishkek  23. Dili        31. Hong_Kong    39. Kamchatka  47. Kuching       55. Novokuznetsk  63. Qostanay    71. Singapore      79. Tokyo     87. Yakutsk
  8. Atyrau    16. Brunei   24. Dubai       32. Hovd         40. Karachi    48. Kuwait        56. Novosibirsk   64. Qyzylorda   72. Srednekolymsk  80. Tomsk     88. Yangon
Time zone: 79

残りのfakerootやクロスコンパイラをインストールします。

#build-depに含まれないパッケージのインストール
$ sudo apt-get install git fakeroot libncurses-dev gcc-aarch64-linux-gnu linux-tools-common

4-3. 環境変数の設定

環境変数を設定します。

#環境変数設定
$ export ARCH=arm64
$ export $(dpkg-architecture -aarm64)
$ export CROSS_COMPILE=aarch64-linux-gnu-

#気になったので確認
$ echo $(dpkg-architecture -aarm64)
echo $(dpkg-architecture -aarm64)
dpkg-architecture: warning: specified GNU system type aarch64-linux-gnu does not match CC system type x86_64-linux-gnu, try setting a correct CC environment variable
DEB_BUILD_ARCH=amd64
DEB_BUILD_ARCH_ABI=base
DEB_BUILD_ARCH_BITS=64
DEB_BUILD_ARCH_CPU=amd64
DEB_BUILD_ARCH_ENDIAN=little
DEB_BUILD_ARCH_LIBC=gnu
DEB_BUILD_ARCH_OS=linux
DEB_BUILD_GNU_CPU=x86_64
DEB_BUILD_GNU_SYSTEM=linux-gnu
DEB_BUILD_GNU_TYPE=x86_64-linux-gnu
DEB_BUILD_MULTIARCH=x86_64-linux-gnu
DEB_HOST_ARCH=arm64
DEB_HOST_ARCH_ABI=base
DEB_HOST_ARCH_BITS=64
DEB_HOST_ARCH_CPU=arm64
DEB_HOST_ARCH_ENDIAN=little
DEB_HOST_ARCH_LIBC=gnu
DEB_HOST_ARCH_OS=linux
DEB_HOST_GNU_CPU=aarch64
DEB_HOST_GNU_SYSTEM=linux-gnu
DEB_HOST_GNU_TYPE=aarch64-linux-gnu
DEB_HOST_MULTIARCH=aarch64-linux-gnu
DEB_TARGET_ARCH=arm64
DEB_TARGET_ARCH_ABI=base
DEB_TARGET_ARCH_BITS=64
DEB_TARGET_ARCH_CPU=arm64
DEB_TARGET_ARCH_ENDIAN=little
DEB_TARGET_ARCH_LIBC=gnu
DEB_TARGET_ARCH_OS=linux
DEB_TARGET_GNU_CPU=aarch64
DEB_TARGET_GNU_SYSTEM=linux-gnu
DEB_TARGET_GNU_TYPE=aarch64-linux-gnu
DEB_TARGET_MULTIARCH=aarch64-linux-gnu

4-4. LinuxカーネルソースのClone

先に、実機のKR260で動作している現行のLinuxカーネルverを確認します。

#KR260上で実行
ubuntu@kria:~$ uname -r
5.15.0-1023-xilinx-zynqmp

git cloneします。Xilinx-Wikiの例はUbuntu20.04focalなので、22.04jammyに修正します。

$ mkdir work
$ cd work
# 1.55GB位になります。
$ git clone https://git.launchpad.net/~canonical-kernel/ubuntu/+source/linux-xilinx-zynqmp/+git/jammy

$ cd jammy
# KR260の現行カーネルと同じリリースタグを探してチェックアウトします。
$ git tag |grep 1023
Ubuntu-xilinx-zynqmp-5.15.0-1023.27
$ git checkout Ubuntu-xilinx-zynqmp-5.15.0-1023.27

# 適当なブランチを作っておく
$ git switch -c kr260-custom

5.Linux Menuconfigでカスタム設定

configを初期化して、menuconfigを開きます。ここで機能を変更、追加します。今回は予行練習なので何もしないでそのままビルドします。

$ fakeroot debian/rules clean
$ fakeroot debian/rules editconfigs

Exitして抜けます。Saveするかと聞かれるのでYesを押して終了します。

6.Linux kernelのビルド

いよいよビルドします。かなり長い時間がかかります。今回はtimeコマンドで実行時間を測ってみます。

$ fakeroot debian/rules clean
# ビルドします。長時間かかります。
$ time fakeroot debian/rules binary
[...]
real	165m3.712s
user	504m38.897s
sys	71m20.980s
$ ls ../
jammy
linux-buildinfo-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
linux-headers-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
linux-image-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
linux-modules-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
linux-xilinx-zynqmp-headers-5.15.0-1023_5.15.0-1023.27_all.deb
linux-xilinx-zynqmp-tools-common_5.15.0-1023.27_all.deb
linux-xilinx-zynqmp-tools-host_5.15.0-1023.27_all.deb

ビルド成果物はルートソースフォルダの親フォルダに置かれます。

ビルド時間は165分=2時間45分になりました。Zynq7000のときのカーネルのみのビルド時間が15分程度だったことを考えるとかなりいろいろなものをビルドしていることがわかります。

ちなみにmakeビルド時の並列ジョブ数オプション(-j4など)がありますが、このビルドでは自動で論理コア数分にセットされます。

7.カーネルdebパッケージのインストール

以下のビルド成果物ができたので、実機のKR260に転送し、インストールします

  • linux-buildinfo-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
  • linux-headers-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
  • linux-image-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
  • linux-modules-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
  • linux-xilinx-zynqmp-headers-5.15.0-1023_5.15.0-1023.27_all.deb
  • linux-xilinx-zynqmp-tools-common_5.15.0-1023.27_all.deb
  • linux-xilinx-zynqmp-tools-host_5.15.0-1023.27_all.deb
$ ls
jammy
linux-buildinfo-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
linux-headers-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
linux-image-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
linux-modules-5.15.0-1023-xilinx-zynqmp_5.15.0-1023.27_arm64.deb
linux-xilinx-zynqmp-headers-5.15.0-1023_5.15.0-1023.27_all.deb
linux-xilinx-zynqmp-tools-common_5.15.0-1023.27_all.deb
linux-xilinx-zynqmp-tools-host_5.15.0-1023.27_all.deb

#適当なフォルダに移動して圧縮
$ mkdir build
$ mv ./*.deb ./build
$ tar czf build.tar.gz ./build

#KR260に転送
$ scp ./build.tar.gz ubuntu@<KR260のIPアドレス>:~/

KR260にSSHなどで入り、インストールします。終了後再起動。

ubuntu@kria:~/$ ls
build.tar.gz
# 解凍
ubuntu@kria:~/$ tar xzf build.tar.gz

# インストール
ubuntu@kria:~/$ sudo dpkg -i ./build/*.deb

#再起動
# sudo reboot

以上で終わりになります。

8.必要ストレージ容量とビルド時間

8-1. Dockerコンテナサイズ

ビルド後のdockerコンテナのサイズは28.6GBです。そこそこ大きなサイズになりました。Xilinx-Wikiで実機セルフビルドやる時はSDカードではなくハードディスク追加推奨と記載があります。(そもそもセルフビルドやる人おるんかな…?)

$ docker ps -s
CONTAINER ID   IMAGE           COMMAND       CREATED        STATUS       PORTS     NAMES          SIZE
15398cedc1c8   ub2204/kbuild   "/bin/bash"   29 hours ago   Up 2 hours             ubarm64build   28.4GB (virtual 28.6GB)

8-2. ビルド時間比較

今回使用したPCは流石に古い(14年前のCPU)ので、M2 Macbook AirとKR260セルフビルドもやってみました。

  • 初代 intel core i5 750 (2010) 2.67GHz, 4C/4T +Dockerコンテナ : 2時間45分
  • M2 Macbook Air +Dockerコンテナ : 67分
  • 実機KR260+Dockerコンテナ: 9時間27分

流石に実機セルフビルドは1日がかりですが、”組込み機器なのにLinuxセルフビルド可能になった”というところが、時代の進化を感じます。

M2 MBAは爆速でしたね。Vivado動いたら良いのですが…

9.2回目のビルドがコケる問題

ここから本編?です。

9-1. ビルドエラーの現象

今回の一連のビルドをやっていて、2回目のリビルドが失敗することに気が付きました。実行から約1分経過後、以下のエラーが出ます。

#2回目のビルド
$ fakeroot debian/rules clean
$ fakeroot debian/rules binary
[...]
/home/user/work/jammy/debian/linux-libc-dev/usr/include//./mtd/mtd-user.h
/home/user/work/jammy/debian/linux-libc-dev/usr/include//./mtd/inftl-user.h
11215 blocks
mkdir /home/user/work/jammy/debian/linux-libc-dev/usr/include/aarch64-linux-gnu
mkdir: cannot create directory '/home/user/work/jammy/debian/linux-libc-dev/usr/include/aarch64-linux-gnu': File exists
make: *** [debian/rules.d/2-binary-arch.mk:569: install-arch-headers] Error 1

$

debian/rules.d/2-binary-arch.mk:569付近にあるmkdirでエラーが起こったようです。既にフォルダが存在するとのこと。

“debian/linux-libc-dev/usr/include/aarch64-linux-gnu”にフォルダがあるか確認するとありました。そしてclone直後の未ビルドのソースツリーにはありません。1度目のビルドで作成され、make cleanで消えてなくて衝突したのでしょうか?

ビルドスクリプトはdebian/rules.d/2-binary-arch.mkのinstall-arch-headers:です。mkdir580行目ですね。(ちなみに.mkってMakefileのことなんでしょうか?)

このあたりの処理はarch情報に合わせてヘッダツリー構成を再構成しているようです。詳しくはよくわかりません。

install-arch-headers:
	@echo Debug: $@
	dh_testdir
	dh_testroot
ifeq ($(do_libc_dev_package),true)
	dh_prep -plinux-libc-dev
endif

	rm -rf $(headers_tmp)
	install -d $(headers_tmp) $(headers_dir)/usr/include/

	$(hmake) $(defconfig)
	mv $(headers_tmp)/.config $(headers_tmp)/.config.old
	sed -e 's/^# \(CONFIG_MODVERSIONS\) is not set$$/\1=y/' \
	  -e 's/.*CONFIG_LOCALVERSION_AUTO.*/# CONFIG_LOCALVERSION_AUTO is not set/' \
	  $(headers_tmp)/.config.old > $(headers_tmp)/.config
	$(hmake) syncconfig
	$(hmake) headers_install

	( cd $(headers_tmp)/install/include/ && \
		find . -name '.' -o -name '.*' -prune -o -print | \
                cpio -pvd --preserve-modification-time \
			$(headers_dir)/usr/include/ )
	mkdir $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)
	mv $(headers_dir)/usr/include/asm $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)/

	rm -rf $(headers_tmp)

define dh_all
	dh_installchangelogs -p$(1)
	dh_installdocs -p$(1)
	dh_compress -p$(1)
	dh_fixperms -p$(1) -X/boot/
	dh_shlibdeps -p$(1) $(shlibdeps_opts)
	dh_installdeb -p$(1)
	dh_installdebconf -p$(1)
	$(lockme) dh_gencontrol -p$(1) -- -Vlinux:rprovides='$(rprovides)' $(2)
	dh_md5sums -p$(1)
	dh_builddeb -p$(1)
endef
define newline


endef
define dh_all_inline
        $(subst ${newline},; \${newline},$(call dh_all,$(1),$(2)))
endef

とりあえず、mkdir -pオプション付けて回避します。再実行。

/home/user/work/jammy/debian/linux-libc-dev/usr/include//./mtd/mtd-user.h
/home/user/work/jammy/debian/linux-libc-dev/usr/include//./mtd/inftl-user.h
11215 blocks
debug hoge /home/user/work/jammy/debian/linux-libc-dev/usr/include/aarch64-linux-gnu
mkdir -p /home/user/work/jammy/debian/linux-libc-dev/usr/include/aarch64-linux-gnu
mv /home/user/work/jammy/debian/linux-libc-dev/usr/include/asm /home/user/work/jammy/debian/linux-libc-dev/usr/include/aarch64-linux-gnu/
mv: cannot move '/home/user/work/jammy/debian/linux-libc-dev/usr/include/asm' to '/home/user/work/jammy/debian/linux-libc-dev/usr/include/aarch64-linux-gnu/asm': Directory not empty
make: *** [debian/rules.d/2-binary-arch.mk:571: install-arch-headers] Error 1

$

今度は次の行(2-binary-arch.mk:581}のmvでエラーです。移動先フォルダが空で無いのでエラーになった様ですね。移動元と移動先のフォルダを比較してみます。

#差分ゼロ
$ diff -r /home/user/work/jammy/debian/linux-libc-dev/usr/include/asm/ /home/user/work/jammy/debian/linux-libc-dev/usr/include/aarch64-linux-gnu/asm/
$ 

差分がないのでフォルダ削除してmvでも良いのですが、rsyncで同期を行ってみます。今度はエラーが出ずビルド完了することを確認しました。バイナリが一致するかはわかりません。

修正後のdebian/rules.d/2-binary-arch.mk:install-arch-headers:を載せておきます。真似はおすすめしません。

install-arch-headers:
	@echo Debug: $@
	dh_testdir
	dh_testroot
ifeq ($(do_libc_dev_package),true)
	dh_prep -plinux-libc-dev
endif

	rm -rf $(headers_tmp)
	install -d $(headers_tmp) $(headers_dir)/usr/include/

	$(hmake) $(defconfig)
	mv $(headers_tmp)/.config $(headers_tmp)/.config.old
	sed -e 's/^# \(CONFIG_MODVERSIONS\) is not set$$/\1=y/' \
	  -e 's/.*CONFIG_LOCALVERSION_AUTO.*/# CONFIG_LOCALVERSION_AUTO is not set/' \
	  $(headers_tmp)/.config.old > $(headers_tmp)/.config
	$(hmake) syncconfig
	$(hmake) headers_install

	( cd $(headers_tmp)/install/include/ && \
		find . -name '.' -o -name '.*' -prune -o -print | \
                cpio -pvd --preserve-modification-time \
			$(headers_dir)/usr/include/ )
	mkdir -p $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)
	rsync -a --remove-source-files $(headers_dir)/usr/include/asm $(headers_dir)/usr/include/$(DEB_HOST_MULTIARCH)/

	rm -rf $(headers_tmp)

define dh_all
	dh_installchangelogs -p$(1)
	dh_installdocs -p$(1)
	dh_compress -p$(1)
	dh_fixperms -p$(1) -X/boot/
	dh_shlibdeps -p$(1) $(shlibdeps_opts)
	dh_installdeb -p$(1)
	dh_installdebconf -p$(1)
	$(lockme) dh_gencontrol -p$(1) -- -Vlinux:rprovides='$(rprovides)' $(2)
	dh_md5sums -p$(1)
	dh_builddeb -p$(1)
endef
define newline


endef
define dh_all_inline
        $(subst ${newline},; \${newline},$(call dh_all,$(1),$(2)))
endef

ビルドシステムをよく知らず改造すると怖いので、代案を考えます。一度しかビルドできないという前提で、2回目以降のビルドは新しくgit cloneし直して、過去のビルドのカーネルコンフィグを移植してみましょう。

9-2. Kernel configを移植しようとすると.configが無い?

1.5GBあるので上記の方法でcloneすると、私の環境では15分ほどかかり面倒ですが、既にタグ名がわかるので指定して–depth=1でcloneします。1分強ほどで完了。

$ git clone https://git.launchpad.net/~canonical-kernel/ubuntu/+source/linux-xilinx-zynqmp/+git/jammy -b Ubuntu-xilinx-zynqmp-5.15.0-1023.27 --depth=1
$ cd jammy
$ git switch -c kr260-custom

続いて前のビルドで使ったカーネルコンフィグを移植します。.configと呼ばれるファイルを前環境から取ってきます。他のケースでは、既にカスタム済みのコンフィグを持ってくる場合にもよく使います。(またmenuconfigするのはしんどい)

しかし、.configが見当たりません。findで探しますが、それっぽいものがありません。なぜだ…

Ubuntuのビルドシステムの勉強が必要と思い、以下のページを見ました(2014年記事です)。

第333回カーネルパッケージをビルドしよう|gihyo.jp

柴田さんの記事ですね。debian.環境名/config/amd64/config.flavour.genericのように、archとフレーバーと呼ばれるビルド設定ごとにconfigが管理されて、スクリプトで結合されてdebian/build以下に生成されるようです。

しかし、debian/buildが見つかりません。よくよく調べると以下のことがわかりました。

  • fakeroot debian/rules editconfigsでmenuconfigを実行中はdebian/build/.configが現れる
  • menuconfigを終了すると、buildごと消える

menuconfigの設定は2回目以降も生きているので、.configはどこかに移されたか、別の形に変換されたみたいです。次はconfigが結合される前のフレーバーごとのconfigを探してみます。

今回の環境の場合はdebian/debian.envは以下の内容なので、debian.環境名フォルダ=debian.zynqmpになります。

$ cat ./debian/debian.env 
DEBIAN=debian.zynqmp

そしてdebian.zynqmp/config以下はannotationsというファイルだけでした。.configありませんね…

$ ls ./debian.zynqmp/config/
annotations

annotationsの中身です。初めて見るファイルですが、.configっぽい内容が書かれていそうです。また謎が増えましたね…

# Menu: HEADER
# FORMAT: 4
# ARCH: arm64
# FLAVOUR: arm64-xilinx-zynqmp

include "../../debian.master/config/annotations"

CONFIG_ACCESSIBILITY                            policy<{'arm64': 'n'}>
CONFIG_ACCESSIBILITY                            note<'LP: #1967702'>

CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT       policy<{'arm64': '-'}>
CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT       note<'LP:1845820'>

CONFIG_BLK_DEV_RAM                              policy<{'arm64': 'y'}>
CONFIG_BLK_DEV_RAM                              note<'LP #1593293'>
[...]

9-3.新Kernel configフォーマットannotations【Ubuntu23.04】

いろいろ調べた結果ついにゴールが見えてきました。Ubuntu23.04よりkernel configの管理が.configベースからannotationsという先程のファイルに移行されたみたいです。そしてUbuntu22.04にバックポートもされたとあるので今回の環境も対象のようです。(3ヵ月前のニュース、最近やん…)

Kernel configuration in Ubuntu

というわけで公式通りに.configを抽出して移植します。

前ビルド環境annotationsから.configを取り出す

前のソースビルド環境はannotationsでkernel configが管理されているのでスクリプトを使って抽出します。スクリプトも名前がannotationsでややこしいですが、こちらはpythonで書かれています。見た感じpython3.9で導入された文法を使っていたのでUbuntu20.04だとおそらく実行厳しいかもしれません。dockerで22.04にしておいて正解でした。

さて、以下を実行すると.configに変換してくれます。

# ソースフォルダのルートにいるとします
$ ./debian/scripts/misc/annotations --file ./debian.zynqmp/config/annotations --arch arm64 --flavour xilinx-zynqmp --export > ../.config

$  ls -a ../
.  ..  .config  jammy 

--help, -h:
オプション説明見れます。

--file , -f:
annotationsファイルのpath。debian.zynqmp/config/やdebian.master/config/などの環境別でフォルダがあるが、debian/debian.envを見ればどのフォルダがアクティブかがわかる。

--arch, -a :
annotationsファイルはarchの違いを管理する。そのため指定が必要。archの選択肢はannotationsファイルの先頭ヘッダに対応ARCHが記載されている。

--flavour, -l :
フレーバーはUbuntu・Debian系ビルド環境の固有名詞(と思われる)。generic、server、lowlatencyなどがある。annotationsファイルはのフレーバーの違いを管理する。そのため指定が必要。フレーバーの選択肢はannotationsファイルの先頭ヘッダに対応FLAVOURが記載されている。フレーバのフォーマットは以下のようになっている。

# FLAVOUR: <ARCH_1>-<FLAVOUR_1> <ARCH_2>-<FLAVOUR_2> …

例:FLAVOUR:arm64-xilinx-zynqmpの場合、引数指定するときは、”arch-“部分を削除したxilinx-zynqmpを指定する。

  • annotations file header : # FLAVOUR: arm64-xilinx-zynqmp
  • >>>> --flavour xilinx-zynqmp

--export, -e :
.configの内容に変換して標準出力する。

.configを新環境のannotationsへ取り込む

以下で.configを取り込めます。

#exportした.configを適当なところに置く
$ ./debian/scripts/misc/annotations --file ./debian.zynqmp/config/annotations --arch arm64 --flavour xilinx-zynqmp --import .config

# annotations全体の更新。必ず必要
$ fakeroot debian/rules clean updateconfigs

--import, -i:
.configの内容を見てannotationsを更新する。.configのpathを指定する。

以上で、2回目のビルドも無事できそうです。

10.Dockerfile

今回記事で使用したDockerfileです。特に特別なことはやっていません。

# Ubuntu Kernel Build for Xilinx ZynqMP(arm64)
FROM ubuntu:22.04

#準備
#RUN echo "deb-src http://archive.ubuntu.com/ubuntu jammy main" | tee -a /etc/apt/sources.list.d/jammy.list
RUN apt-get update && apt-get install -y  sudo libssl-dev git

#一般ユーザを作成
## ユーザ名
ARG USERNAME=user
ARG GROUPNAME=user
## ユーザIDはホストマシンの自身のユーザIDと一致させる。$ id コマンドで調べる
ARG UID=1000
ARG GID=1000
ARG PASSWORD=user
## ユーザを作成する。またsudo実行権限を付与する
RUN groupadd -g $GID $GROUPNAME && \
    useradd -m -s /bin/bash -u $UID -g $GID -G sudo $USERNAME && \
    echo $USERNAME:$PASSWORD | chpasswd && \
    echo "$USERNAME   ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
USER $USERNAME
WORKDIR /home/$USERNAME/
CMD ["/bin/bash"]

ABOUT ME
sh-goto
組込エンジニア. 最近の遊びはLinuxの低レイヤいじりとXilinxのZynqとFPGAを使った電子工作
関連記事