Cubieboard2のシステム構築:Linux-sunxiベースの開発手順

目次- - 参考資料

  • その他参考
  • 概要
    1. 開発環境構築
  • 1.1 必要なツールのインストール
  • 1.2 ソースコードの取得
  • 1.3 Debianベースシステムの準備
    1. コンポーネントのビルド
  • 2.1 U-Bootのコンパイル
  • 2.1.1 U-Boot-sunxiのブランチ選択
  • 2.1.2 U-Bootのビルドプロセス
  • 2.2 sunxi-toolsのコンパイル
  • 2.3 カーネルの構成とビルド
  • 2.3.1 事前に準備されたカーネル設定のコピー
  • 2.3.2 カーネル設定のカスタマイズ
  • 2.3.3 カーネルのビルド実行
  • 2.3.4 メモリ領域の最適化
    1. ルートファイルシステムの作成
  • 3.1 ルートFSの初期設定
  • 3.2 阿里源への切り替え
  • 3.3 /etc/inittabファイルの内容
    1. フラッシュ作業
  • 4.1 事前準備
  • 4.2 フラッシュ実施
  • 4.2.1 パーティションの作成
  • 4.2.2 ブートローダーの書き込み
  • 4.2.3 その他データの焼入れ
  • 4.2.4 フラッシュ結果の確認
  • あとがき

参考資料

  • (一) ツール導入:https://blog.csdn.net/wb4916/article/details/72898266
  • (二) コードのダウンロード:https://blog.csdn.net/wb4916/article/details/72898747
  • (三) Debianベースシステムの構成:https://blog.csdn.net/wb4916/article/details/72899191
  • (四) コンポーネントのビルド:https://blog.csdn.net/wb4916/article/details/72900725
  • (五) ルートFSの作成:https://blog.csdn.net/wb4916/article/details/72916692

その他参考

概要

全体的な流れとしては、組み込み機器の起動時にブートローダーが実行され、ハードウェアとスタックの初期化を行った後、カーネルをRAMへ移動して起動し、続いてルートファイルシステムをマウントします。

本記事ではUbuntu 22.04上でCubieboard2用にarmhfベースのDebian Linuxを構築します。SPL、U-Boot、カーネル(Kernel)、ルートファイルシステム(ROOTFS)を含む構成です。

  1. 開発環境構築

mkdir -p ~/cubieboard2/targetfs     # ディレクトリ作成
PROJECT_DIR=~/cubieboard2           # プロジェクトルート
TARGET_FS_DIR=${PROJECT_DIR}/targetfs # ターゲットOSのルートFSディレクトリ

1.1 必要なツールのインストール:

sudo apt-get install build-essential libncurses5-dev u-boot-tools  \
                     qemu-user-static debootstrap git binfmt-support  \
                     libusb-1.0-0-dev pkg-config gcc-arm-linux-gnueabihf

1.2 ソースコードの取得

# GitHubの速度が遅いため、Giteeの同期リポジトリを使用
cd $PROJECT_DIR

# lichee/カーネルの取得
git clone https://gitee.com/luyaocf/linux-sunxi.git -b cubie/sunxi-3.4
tar -czvf linux-sunxi_cb2_`date +%Y%m%d_%H%M%S`.tar.gz linux-sunxi/

# U-Bootの取得
git clone https://gitee.com/luyaocf/u-boot-sunxi.git -b cubie/sunxi
tar -czvf u-boot-sunxi_cb2_`date +%Y%m%d_%H%M%S`.tar.gz u-boot-sunxi/

# sunxi-tools masterブランチ
git clone https://gitee.com/luyaocf/sunxi-tools.git 
tar -czvf sunxi-tools_cb2_`date +%Y%m%d_%H%M%S`.tar.gz sunxi-tools/

# sunxi-boards masterブランチ
git clone https://gitee.com/luyaocf/sunxi-boards.git
tar -czvf sunxi-boards_cb2_`date +%Y%m%d_%H%M%S`.tar.gz sunxi-boards/

仮想マシンでスナップショットを取ることを推奨します。次のステップでソース設定を複数回試行する必要があります。

1.3 Debianベースシステムの準備

cd $TARGET_FS_DIR

##/ man debootstrap :
 # --no-check-gpg :取得したReleaseファイルのGPG署名チェックを無効にする
 # manの例 "debootstrap stretch ./stretch-chroot http://deb.debian.org/debian" を参考に
 # 公式のURLではwheezyバージョンがサポートされていないため、アリババのミラーを指定して最新版bullseyeを使用
 #/ 
debootstrap --foreign --no-check-gpg --arch armhf bullseye . http://mirrors.aliyun.com/debian/

cd $TARGET_FS_DIR && sudo cp /usr/bin/qemu-arm-static usr/bin/

LC_ALL=C LANGUAGE=C LANG=C chroot . /debootstrap/debootstrap --second-stage

  1. コンポーネントのビルド

2.1 U-Bootのコンパイル

Ubuntu 22.04を使用しているため、デフォルトのgcc-arm-linux-gnueabihfバージョンは11.2.0です

# 既存のツールチェーンのアンインストール
apt-get remove gcc-arm-linux-gnueabi*

# ツールチェーンのダウンロード
wget https://releases.linaro.org/components/toolchain/binaries/4.9-2016.02/arm-linux-gnueabihf/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf.tar.xz
# 解凍
mkdir /usr/local/arm
tar -vxf gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf.tar.xz -C /usr/local/arm
# 環境変数設定(/root/.bashrcに追加)
export PATH=$PATH:/usr/local/arm/gcc-linaro-4.9-2016.02-x86_64_arm-linux-gnueabihf/bin
# 設定反映
. ~/.bashrc

# テスト
-> arm-linux-gnueabihf-gcc -v
Using built-in specs.
COLLECT_GCC=arm-linux-gnueabihf-gcc
......
gcc version 4.9.4 20151028 (prerelease) (Linaro GCC 4.9-2016.02) 

2.1.1 U-Boot-sunxiブランチ

# git branch -a
cubie/sunxi             # make実行時にエラー発生
lichee-dev              # Cubieboard2非対応
lichee-dev-a20          # Cubieboard2非対応
lichee/lichee-dev       # Cubieboard2非対応
lichee/lichee-dev-ICS   # Cubieboard2非対応
lichee/lichee-dev-mmc   # Cubieboard2非対応
old/sunxi-current       # make実行時にエラー発生
sunxi                   # make実行時にエラー発生
wip/a20                 # make実行時にエラー発生

# git checkout cubie/sunxi
# cubie/sunxiブランチを選択

2.1.2 U-Bootのビルド

cd $PROJECT_DIR/u-boot-sunxi

# クリア
sudo make distclean CROSS_COMPILE=arm-linux-gnueabihf-
# ビルド
sudo make cubieboard2 CROSS_COMPILE=arm-linux-gnueabihf-

エラー1:arm-linux-gnueabihf-gcc: error: unrecognized -march target: armv5

grep -rn "armv5" でarmv5を含む箇所を検索。arch/arm/cpu/armv7/config.mk:11に以下が存在するため、armv5をarmv7-aに変更可能

# armv7-aがGCCでサポートされていない場合、より多くのツールチェーンでサポートされているarmv5にフォールバック
PF_CPPFLAGS_ARMV7 := $(call cc-option, -march=armv7-a, -march=armv5)

cubieboard2のCPUアーキテクチャは実際には「ARMv7 Cortex-A7」です

参考:https://archlinuxarm.org/platforms/armv7/allwinner/cubieboard-2

エラー2:compiler-gcc.h:93:1: fatal error: linux/compiler-gcc11.h: ファイルまたはディレクトリが見つからない include/linux配下のcompiler-gcc3.hやcompiler-gcc4.hをcompiler-gcc11.hとしてコピー cp include/linux/compiler-gcc3.h include/linux/compiler-gcc11.h

参考:https://blog.csdn.net/p1279030826/article/details/113931568

2.2 sunxi-toolsのコンパイル

  • sunxi-toolsはfexc、nand-partなどのツールを提供しており、システムのインストールやカスタマイズ時に使用されるため、事前にコンパイルしておくことが推奨されます。
  • これらのツールは通常、ホストシステム(x86-64 Ubuntu Linux)上でターゲットデバイスやターゲットシステムに対して実行されるため、x86-64の実行ファイルとしてコンパイルします。
  • コンパイル:
cd $PROJECT_DIR/sunxi-tools
make

2.3 カーネルの設定とビルド

その他参考:https://blog.csdn.net/CNflysky/article/details/125417838

2.3.1 事前に準備されたカーネル設定のコピー

# カーネルコードディレクトリへ移動
cd $PROJECT_DIR/linux-sunxi/

# 設定ファイルのコピー
cp arch/arm/configs/sun7i_defconfig .config

2.3.2 カーネル設定

設定画面を開く:

cp .config bak1_orig.config
make ARCH=arm menuconfig
cp .config bak2_soloforce.config

具体的な設定項目:

  • *:該当ドライバはカーネルイメージに直接組み込まれます。
  • M:該当ドライバは独立したモジュールとしてコンパイルされ、必要に応じてinsmodやmodprobeでロードできます。
  • カスタムモジュール以外はすべて「選択」(<*>)に変更することを推奨します。
説明 第1階層 第2階層 第3階層 第4階層 第5階層
無線ネットワーク ネットワーキングサポート ワイヤレス Generic IEEE 802.11 Networking Stack (mac80211)
SATA デバイスドライバ シリアルATAおよびパラレルATAドライバ SoftWinner Platform AHCI SATAサポート
Tun/Tap デバイスドライバ ネットワークデバイスサポート Universal TUN/TAPデバイスドライバサポート
USB LAN デバイスドライバ ネットワークデバイスサポート Wireless LAN (NEW) Ralinkドライバサポート
赤外線 デバイスドライバ 入力デバイスサポート キーボード (NEW) sunxi IRサポート (NEW)
GPIO デバイスドライバ GPIOサポート sunxiプラットフォーム用GPIOサポート
エラー デバイスドライバ ハードウェア監視サポート
カメラ デバイスドライバ マルチメディアサポート Video captureアダプタ (NEW) V4L USBデバイス (NEW) USB Video Class (UVC)
HDMI デバイスドライバ グラフィックサポート フレームバッファデバイスサポート HDMIドライバサポート(sunxi)
USBシリアル デバイスドライバ USBサポート(NEW) USBシリアルコンバータサポート USB Prolific 2303 Single Port Serialドライバ

2.3.3 カーネルのビルド

# バックアップ
cp .config bak_`date +%Y%m%d_%H%M%S`.config
# ビルド
make -j12 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage modules

ビルド完了後、カーネルファイルが生成されます:

ll arch/arm/boot/uImage

2.3.4 メモリの有効活用

参考:https://blog.csdn.net/CNflysky/article/details/125467518

  1. ルートFSの作成

3.1 ルートFSの初期設定

cd $PROJECT_DIR/targetfs
chroot . passwd

echo "Cubieboard2" > etc/hostname && cat etc/hostname

echo "127.0.0.1 Cubieboard2" >> etc/hosts && cat etc/hosts

# カーネルイメージのインストール
cp ../linux-sunxi/arch/arm/boot/uImage boot/
make -C ../linux-sunxi INSTALL_MOD_PATH=. ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_install

# inittabファイルの初期化
echo T0:2345:respawn:/sbin/getty -L ttyS0 115200 vt100 >> etc/inittab && cat etc/inittab

# sources.listファイルの初期化
vi etc/apt/sources.list
cat etc/apt/sources.list

chroot . apt-get update
chroot . apt-get upgrade
chroot . apt-get install openssh-server locales wireless-tools wpasupplicant vim lrzsz net-tools firmware-ralink 
echo "en_US.UTF-8 UTF-8" > etc/locale.gen
echo "zh_CN.UTF-8 UTF-8" >> etc/locale.gen
chroot . locale-gen

# この時点でDebianベースシステムは構成済みです。$TARGET_FS_DIRを圧縮ファイルとして保存しておくことを推奨します。
cd ../ && sudo tar -czvf targetfs_cb2_`date +%Y%m%d_%H%M%S`.tar.gz targetfs/

3.2 阿里源への切り替え

deb http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye main non-free contrib
deb http://mirrors.aliyun.com/debian-security/ bullseye-security main
deb-src http://mirrors.aliyun.com/debian-security/ bullseye-security main
deb http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-updates main non-free contrib
deb http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib
deb-src http://mirrors.aliyun.com/debian/ bullseye-backports main non-free contrib

3.3 /etc/inittabファイルの内容

コードを表示```

/etc/inittab: init(8)の設定

$Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $

デフォルトのランレベル

id:2:initdefault:

起動時のシステム設定/初期化スクリプト

これは緊急(-b)モード以外では最初に実行されます

si::sysinit:/etc/init.d/rcS

単一ユーザーモードでの処理

~~:S:wait:/sbin/sulogin

/etc/init.dはSとKスクリプトをランレベル変更時に実行します

ランレベル0はシャットダウン

ランレベル1は単一ユーザー

ランレベル2-5はマルチユーザー

ランレベル6は再起動

l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6

通常到達しないが、緊急時用にフォールスルー

z6:6:respawn:/sbin/sulogin

CTRL-ALT-DELが押されたときの処理

ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

特殊なキー押下時の処理 (ALT-UpArrow)

#kb::kbrequest:/bin/echo "Keyboard Request--edit /etc/inittab to let this work."

電源の失敗/復帰時の処理

pf::powerwait:/etc/init.d/powerfail start pn::powerfailnow:/etc/init.d/powerfail now po::powerokwait:/etc/init.d/powerfail stop

/sbin/gettyのランレベルでの呼び出し

"id"フィールドは必ずデバイスの最後の文字列("tty"以降)と一致する必要があります

形式:

:::

注: 多くのDebianシステムではtty7がX Window Systemに使用されるため、

Xを実行している場合はtty7にgettyを追加しないでください。

1:2345:respawn:/sbin/getty 38400 tty1 2:23:respawn:/sbin/getty 38400 tty2 3:23:respawn:/sbin/getty 38400 tty3 4:23:respawn:/sbin/getty 38400 tty4 5:23:respawn:/sbin/getty 38400 tty5 6:23:respawn:/sbin/getty 38400 tty6

シリアルラインにgettyを配置する例(端末用)

#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100 #T1:23:respawn:/sbin/getty -L ttyS1 9600 vt100

モデムラインにgettyを配置する例

#T3:23:respawn:/sbin/mgetty -x0 -s 57600 ttyS3


4. フラッシュ作業
-----

### 4.1 事前準備

1)作業ディレクトリ

PROJECT_DIR=~/cubieboard2
TARGET_FS_DIR=${PROJECT_DIR}/targetfs


2)必要なツール

  • (1)U-Boot $PROJECT_DIR/u-boot-sunxi/u-boot-sunxi-with-spl.bin

  • (2)カーネル $PROJECT_DIR/linux-sunxi/arch/arm/boot/uImage

  • (3)boot.scr $PROJECT_DIR/boot.scr

  • (4)script.bin $PROJECT_DIR/sunxi-boards/sys_config/a20/script.bin

  • (5)rootfs $PROJECT_DIR/targetfs.tar.gz


### 4.2 フラッシュ実施

#### 4.2.1 パーティション作成

ll /dev/sd* # パーティション名の確認(通常sdb) card=/dev/sdb dd if=/dev/zero of=${card} bs=1M count=1 # dd if=<入力ファイル> of=<出力ファイル> bs=<ブロックサイズ> count=<ブロック数> sfdisk -r ${card} # パーティションの順序を整える fdisk ${card} # パーティションの編集

d # 旧パーティションの削除

n [Enter] [Enter] [Enter] +64M # パーティション1の作成

n [Enter] [Enter] [Enter] [Enter] # パーティション2の作成

t 1 c w # パーティションタイプの指定

パーティション1、2のフォーマット

mkfs.vfat ${card}1 mkfs.ext4 ${card}2


#### 4.2.2 ブートローダーの書き込み

cd $PROJECT_DIR/u-boot-sunxi dd if=u-boot-sunxi-with-spl.bin of=$card bs=1024 seek=8


#### 4.2.3 その他データの焼入れ

1)パーティション1にuImage、script.bin、boot.scrを書き込む:

mount ${card}1 /mnt mkdir /mnt/boot

カーネルuImageのインストール

cp $PROJECT_DIR/linux-sunxi/arch/arm/boot/uImage /mnt/boot

script.binのインストール

cp $PROJECT_DIR/sunxi-boards/sys_config/a20/script.bin /mnt/boot

boot.scrのインストール

cp $PROJECT_DIR/boot.scr /mnt/

sync && umount /mnt


2)パーティション2にファイルシステムを書き込む:

rootfsのインストール

mount ${card}2 /mnt

cp $PROJECT_DIR/targetfs.tar.gz /mnt/ tar -zxvf targetfs.tar.gz

sync && umount /mnt


#### 4.2.4 フラッシュ結果の確認

lsb_release -a # Ubuntuバージョンの確認 cat /etc/issue # Ubuntuバージョンの確認 cat /etc/debian_version # Ubuntu下でのDebianバージョンの確認
cat /etc/os-release # システム詳細の確認


あとがき
--

> 2022-08-07時点での記録:
> 複数回試みましたが、上述の手順ではシステムが正常に起動しませんでした。
> 最終的に公式のU-Bootとカーネルを使用し、rootfsのtargetfs.tar.gzを/dev/sdb2に解凍したところ成功し、システムはDebian 11になりました。

タグ: Debian U-Boot Linux-sunxi ARM rootfs

6月8日 16:08 投稿