目次- - 参考資料
- その他参考
- 概要
-
- 開発環境構築
- 1.1 必要なツールのインストール
- 1.2 ソースコードの取得
- 1.3 Debianベースシステムの準備
-
- コンポーネントのビルド
- 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 メモリ領域の最適化
-
- ルートファイルシステムの作成
- 3.1 ルートFSの初期設定
- 3.2 阿里源への切り替え
- 3.3 /etc/inittabファイルの内容
-
- フラッシュ作業
- 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
その他参考
- https://blog.csdn.net/MicroMehhh/article/details/142290729
- Ubuntu:https://old-releases.ubuntu.com/releases/
- http://releases.linaro.org/components/toolchain/binaries/
- https://github.com/peng-zhihui/Planck-Pi
概要
全体的な流れとしては、組み込み機器の起動時にブートローダーが実行され、ハードウェアとスタックの初期化を行った後、カーネルをRAMへ移動して起動し、続いてルートファイルシステムをマウントします。
本記事ではUbuntu 22.04上でCubieboard2用にarmhfベースのDebian Linuxを構築します。SPL、U-Boot、カーネル(Kernel)、ルートファイルシステム(ROOTFS)を含む構成です。
- 開発環境構築
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
- コンポーネントのビルド
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
- ルート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になりました。