Linux

【Zynq7】3.Linuxカーネルの構築

1.記事一覧

記事は複数回に分けて投稿します。Zynq7020SoCで動作する、YoctoベースのPetaLinuxを使わない素のLinuxを構築します。

ZynqMP(arm64版)はこちら

エッジArm Linux構築編(armv7l)

  1. 【Zynq7】Yoctoを使わずに素のLinuxをソースから構築する
  2. 【Zynq7】1.FSBL(1stStageBootLoader)の構築
  3. 【Zynq7】2.U-bootの構築
  4. 【Zynq7】3.Linuxカーネルの構築 ←本ページ
  5. 【Zynq7】4.Zyboz7ボードのデバイスツリー構築
  6. 【Zynq7】5.RootFSのマウント(Ubuntu18.04)
  7. 【Zynq7】6.カーネルモジュールの配置
  8. 【Zynq7】番外編1.u-bootが途中で止まる問題
  9. 【Zynq7】番外編2.MACアドレスをQSPIFlashから読み出して設定する

エッジArm Linux実践編(armv7l)

  1. 【Zynq7】実践1. LinuxにRTCを認識させる【I2Cデバイス】
  2. 【Zynq7】実践2. 温度センサをPython+Dockerで使う【I2Cデバイス】
  3. 【Zynq7】実践3. 組込みLinuxでコンテナ導入に苦労した話【Docker Engine編】
  4. 【Zynq7】実践4. LinuxでSPIを使う【液晶編1】
  5. 【Zynq7】実践5. ZynqPLのGPIOをLinuxで使う【液晶編2】
  6. 【Zynq7】実践6. PythonでSPI液晶を使う【液晶編3】
  7. 【Zynq7】閑話. SPI バス周波数が上がらない問題

2.目次

この記事ではlinuxの構築を行い、カーネルイメージ(uImage)ファイルを生成します。
uImageは起動用SDカードのbootパーティションに配置されます。

3.環境

開発PCUbuntu20.04, intel core i5 750 RAM 16G
DockerDocker Engine v23.0.0, Ubuntu20.04 base image

【追記2023/5】Ubuntu22.04 Docker imageでLinuxカーネルビルドに失敗することがありました。原因は20.04→22.04でarm-linux-gnueabihf-gccがver9→ver11 に変わり、armv7hf gccの仕様が変わったかららしいです。
Linux kernel v6.1(tag=xilinx-v2023.1)ではgcc11でビルドできました。
ターゲットボードDigilent Zybo z7-20 Rev.B.2(XC7Z020-1CLG400C, DDR3 1GB)
LinuxカーネルXilinxがGitHubで提供するソースコード tag=xilinx-v2022.2
Linux kernel v5.15
https://github.com/Xilinx/linux-xlnx/tree/xilinx-v2022.2
mkimageubootに対応したLinuxカーネルイメージを生成するツール
XilinxがGithubで提供するソースを使用。tag=xilinx-v2022.2
u-boot 2022.01
https://github.com/Xilinx/u-boot-xlnx/tree/xilinx-v2022.2

u-boot構築に引き続き、Linuxカーネルのビルド環境にはDockerコンテナ環境を使用します。理由は私の開発PCではすでに別の開発環境が入っており、クリーンでないからです。再現性を高めるためなので、必ずしも使う必要はなく、直接開発PC上に環境構築しても問題ありません。

4.ビルド環境の構築

前記事のu-bootの構築で使用した、Dockerコンテナ環境を使用します。

4-1. mkimageのインストール

前回u-bootのgitリポジトリをcloneしてありますので、そこからmkimageコマンドを持ってきます。

Bash
sudo cp ./u-boot-xlnx/tools/mkimage /usr/local/bin/

4-2. Linuxカーネルクロスビルド環境変数(zynq7なのでarmv7l)

Bash
$ export CROSS_COMPILE=arm-linux-gnueabihf-

4-3. libncurses-devのインストール

この後menuconfigによる設定を行う際、画面表示するために必要です。

Bash
$ sudo apt install libncurses-dev

4-4. bcコマンドのインストール

makeコマンドの内部処理で必要になります。

Bash
$ sudo apt install bc

5.Linuxカーネルのmenuconfig設定

5-1. Linuxカーネルソースのclone

適当な作業用フォルダを作成し、git cloneします。

Bash
$ mkdir linux_wk
$ cd linux_wk
$ git clone https://github.com/Xilinx/linux-xlnx.git -b xilinx-v2022.2 --depth 1

5-2. menuconfigの起動

まず、zynq標準defconfigで初期化します。

Bash
$ cd linux-xlnx
$ make ARCH=arm xilinx_zynq_defconfig

menuconfigを起動します。

Bash
$ make ARCH=arm menuconfig

以下の画面が表示されます。

5-3. menuconfigについて

標準defconfigで初期化された後はほとんどのドライバが無効になっているため、必要に応じて有効化します。なひたふ氏の書籍では

  • USB-Host、USB-LAN(USB接続EtherのLSI)、USBWifiドングル、USBHubの有効化
  • RTC(Real Time Clock)デバイスの有効化
  • 画像表示(フレームバッファ)の有効化

といった例を解説されています。今回は各デバイスが用意できず確認できないため、バージョン名を改変とUSB機能周りを有効化して終えます。残りは別の機会に遊んでみます。
また、Linux起動後にSSHでログインを使うためのGigabitEtherはデフォルトで使えます。

5-4. menuconfig操作方法

基本的にキーボード操作です。上下矢印キーでカーソル移動、左右矢印キーで<Select><Exit><Help><Save><Load>を移動します。<Select>でEnterを押すと選択されているカーソル項目の中の階層に入ります。<Exit>でEnterで上の階層に戻ります。

半角スペースキーで項目の有効(*)/無効( )/ローダブルモジュール(M)の3つを切り替えます。有効は組込みモジュール、ローダブルモジュールは必要になったときのみ読み込むモジュールです。

5-5. カーネルバージョン名の変更

General setup>Local versionを選択し、製品名などに書き換えることができます。
今回は適当に"-zyboz7_custom"に変えておきます。

最後はトップ階層で<Exit>でデータ保存をyesにします。保存データの.configはlinux-xlnx/.configにあります。

5-6. USB機能の有効化

DeviceDriver > USB Support > USB announce new devicesを有効(*)にします。
DeviceDriver > USB Support > OTG supportを有効(*)にします。

それと私個人的にUSBシリアルデバイスでマイコン間通信しようと考えているので、
以下をカーネルイメージに組込みます。
DeviceDriver > USB Support > USB Serial Converter support を有効(*)して中に入る
DeviceDriver > USB Support > USB Serial Converter support >
USB Generic Serial Driverを有効(*)
USB Serial Simple Driverを有効(*)
USB Winchiphead CH341 Single Port Serial Driverを有効(*)
USB CP210x family of UART Bridge Controllersを有効(*)
USB FTDI Single Port Serial Driverを有効(*)

6.Linuxカーネルのビルド

6-1. ビルド実行

linux-xlnxフォルダ直下でビルドを実行します。
時間がかかるので、並列Jobオプション(-j*)をつけて高速化します。開発PCのMAX論理コア数+1個の並列数までにします。私の環境だとMAX -j5になります。

Bash
$ make -j5 ARCH=arm UIMAGE_LOADADDR=0x8000 uImage
...
Kernel: arch/arm/boot/uImage is ready #<--ビルド成功

ビルドが終わると上記のメッセージが出ます。20分程かかりました。
linux-xlnx/arch/arm/boot/uImageにカーネルイメージができています。

6-2. カーネルイメージの確認

ヘッダ情報を見てみます。

Bash
$ mkimage -l uImage
Image Name: Linux-5.15.0-zyboz7_custom
Created: Mon Feb 13 10:12:50 2023
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 4598256 Bytes = 4490.48 KiB = 4.39 MiB
Load Address: 00008000
Entry Point: 00008000

サイズが4.39MiBですね。作成して初めて気づくことですが、カーネル本体は想像以上にとてもコンパクトです。多くのドライバが無効だからですが、有効ドライバを増やしていくとどのくらい増えるか気になります。

7.最後に

本記事はなひたふ氏の著書「ZYNQで実用的なシステムを構築するための本」を参考に実践した内容です。本記事では一部しか内容を取り上げていません。もっとディープな内容がほしい方は是非買ってみてください。

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