Armadillo の製品マニュアルの
「特定のイメージファイルだけを書き換える」
に記載されいている方法は、Armadillo に
PC などの端末を接続しての操作を必要としています。
製品出荷後でもソフトウェアをアップデートできるような機能をつける場合、
可能な限り簡単な手順でアップデートできる仕組みが望ましいところです。
また、ソースコードの管理も重要です。
これは前述したアップデートの仕組みの前段階として、
「ブートローダーやカーネル等が更新されて新しいソースコードが配布された場合、
古くなったソースコードに行っていたカスタマイズを、
どうやって新しいソースコードに適用するのか」
という話になります。
ソースコードの管理には所謂バージョン管理システムを利用します。
バージョン管理システムには様々ありますが、ここでは
Git
を使用していきます。
Git を利用すると、
古くなったソースコードに行っていたカスタマイズを、
新しいソースコードに適用することが簡単にできます。
また、バージョン管理システムの基本的な機能として、
ソースコードの変更内容を確認したり、
変更前の状態に戻したりすることもできます。
ここからは、
Armadillo-640
のブートローダーのソースコードを例に、
「古くなったソースコードに行っていたカスタマイズを、
新しいソースコードに適用する」
ための具体的な手順を説明していきます。
流れとしては次のとおりです。
-
Gitリポジトリの作成
-
ベースとなるソースコード
(u-boot-a600-v2018.03-at7)
を登録
-
ソースコードの修正
-
ベースとなるソースコードの更新
(u-boot-a600-v2018.03-at7
から
u-boot-a600-v2018.03-at8
へ)
-
更新後のベースとなるソースコードにソースコードの修正を適用
まずは、
https://download.atmark-techno.com/armadillo-640/source/u-boot-a600-v2018.03-at7.tar.gz
をATDEにダウンロードして、
tarコマンドで展開します。
[ATDE ~]$ wget https://download.atmark-techno.com/armadillo-640/source/u-boot-a600-v2018.03-at7.tar.gz
[ATDE ~]$ tar xf u-boot-a600-v2018.03-at7.tar.gz
[ATDE ~]$ ls --all -1 u-boot-a600-v2018.03-at7
.
..
.checkpatch.conf
.gitignore
.mailmap
.travis.yml
Documentation
Kbuild
Kconfig
Licenses
MAINTAINERS
Makefile
README
api
arch
board
cmd
common
config.mk
configs
disk
doc
drivers
dts
env
examples
fs
include
lib
net
post
scripts
snapshot.commit
test
tools
| |
---|
後で新しいソースコードに更新する作業を体験するため、
ここでは、あえて最新ではないソースコードをダウンロードしています。 実際の開発では最新のソースコードをダウンロードしてください。 |
展開が終わったら、
mv
コマンドでディレクトリ名を変更します。
ソースコードのバージョン管理は
Git
で行えるのでバージョンを除いたディレクトリ名とします。
[ATDE ~]$ mv u-boot-a600-v2018.03-at7 u-boot-a600-v2018.03-at
ディレクトリ名を変更したら、
cd
コマンドでディレクトリを移動し、
空のGitリポジトリを作成します。
[ATDE ~]$ cd u-boot-a600-v2018.03-at
[ATDE ~/u-boot-a600-v2018.03-at]$ git init
Initialized empty Git repository in /home/atmark/u-boot-a600-v2018.03-at/.git/
ベースとなるソースコードをGitリポジトリに登録します。
git add
で対象となるファイルを指定し、
git commit
で対象のファイルをひとまとまりの修正として登録します。
登録の際は、対象のファイルでどのような修正が行われたか、
を説明するためのコミットメッセージ
を記述します。
[ATDE ~/u-boot-a600-v2018.03-at]$ git add -f $(find . -mindepth 1 -maxdepth 1)
[ATDE ~/u-boot-a600-v2018.03-at]$ git commit -m"Imported from u-boot-a600-v2018.03-at7.tar.gz"
| |
---|
ここで登録した「ひとまとまりの修正」を Git では
コミットと呼びます。 Git はコミット単位でバージョンを管理します。 |
| |
---|
git commit
の -m オプションは、
コマンドライン引数でコミットメッセージを記述するためのものです。 -m オプションを指定しなかった場合は自動でエディタが起動するので、
エディタでコミットメッセージを記述します。 |
| |
---|
$()は、()内の
find . -mindepth 1 -maxdepth 1
を実行し出力された文字列をコマンドライン上に展開します。 git add $(find . -mindepth 1 -maxdepth 1)
はカレントディレクトリのファイル全てを
git add
するという意味になります。
つまり、以下のコマンドを実行するのと同じです。
[ATDE ~/u-boot-a600-v2018.03-at]$ git add ./.git ./tools ./test ./snapshot.commit ./scripts ./post ./net ./lib ./include ./fs ./examples ./env ./dts ./drivers ./doc ./disk ./configs ./config.mk ./common ./cmd ./board ./arch ./api ./README ./Makefile ./MAINTAINERS ./Licenses ./Kconfig ./Kbuild ./Documentation ./.travis.yml ./.mailmap ./.gitignore ./.checkpatch.conf |
Git でのソースコードの修正は、以下の流れで行います。
-
新しいbranch(ブランチ)の作成
-
ファイルの編集
-
編集したファイルのgit add
-
git commit
先程git commitしたベースとなるソースコードは、
デフォルトのブランチである
master
に積まれています。
ここから新しいブランチを作成して、
そのブランチ上でソースコードのカスタマイズを行っていきます。
master
とブランチを分けることで、
「ベースとなるソースコードの更新」と
「ソースコードのカスタマイズ」を区別することができます。
git log
を実行すると現在のブランチに積まれているコミットを確認できます。
[ATDE ~/u-boot-a600-v2018.03-at]$ git log
commit 8c22d30fcb0c254d3f0cf28cb9da4611a7100d70
Author: atmark <atmark@atde7>
Date: Wed May 13 14:39:35 2020 +0900
Imported from u-boot-a600-v2018.03-at7.tar.gz
ここから新しいブランチを作成して、
そのブランチをチェックアウトする
(現在のブランチからそのブランチに切り替える)
には
git checkout -b
を実行します。
ブランチの名称は製品プロジェクトの名称等で構いません。
ここでは x11a としています。
[ATDE ~/u-boot-a600-v2018.03-at]$ git checkout -b x11a
Switched to a new branch 'x11a'
現在のブランチを確認するには、
git branch
を実行します。
[ATDE ~/u-boot-a600-v2018.03-at]$ git branch
master
* x11a
新しいブランチをチェックアウトしたら、
ソースコードのカスタマイズをしていきます。
ここでは、U-Bootのデフォルトの環境変数に
aguide=Software Development
を追加していきます。
[ATDE ~/u-boot-a600-v2018.03-at]$ vi include/configs/armadillo-640.h
を次のように修正します。
編集が終わったら
git diff
を実行します。
git diff
により、
現状のソースコードにどのような変更が行われたのか確認することができます。
[ATDE ~/u-boot-a600-v2018.03-at]$ git diff
diff --git a/include/configs/armadillo-640.h b/include/configs/armadillo-640.h
index 7235241..78ad680 100644
--- a/include/configs/armadillo-640.h
+++ b/include/configs/armadillo-640.h
@@ -121,7 +121,8 @@ int wlan_rtc_i2c_read(void);
BOOTCOMMAND_USB\
"tftpboot=tftpboot uImage; tftpboot 0x83000000 a640.dtb; bootm ${loadaddr} - 0x83000000;\0"\
STOP_NR3225SA_ALARM_ENV_NAME "=" STOP_NR3225SA_ALARM_DEFAULT ";\0"\
- ENABLE_PF3000_LPM_ENV_NAME "=" ENABLE_PF3000_LPM_DEFAULT "\0"
+ ENABLE_PF3000_LPM_ENV_NAME "=" ENABLE_PF3000_LPM_DEFAULT "\0"\
+ "aguide=Software Development\0"
#define CONFIG_BOARD_LATE_INIT
正しく修正できていたら、
git add
と
git commit
でコミットを作成します。
[ATDE ~/u-boot-a600-v2018.03-at]$ git add include/configs/armadillo-640.h
[ATDE ~/u-boot-a600-v2018.03-at]$ git commit -m"デフォルトの環境変数にaguideを追加"
[ATDE ~/u-boot-a600-v2018.03-at]$ git log
commit 280d3336a73f0f80269dc166e6653dfcec1a15ca
Author: atmark <atmark@atde7>
Date: Wed May 13 15:13:38 2020 +0900
デフォルトの環境変数にaguideを追加
commit 8c22d30fcb0c254d3f0cf28cb9da4611a7100d70
Author: atmark <atmark@atde7>
Date: Wed May 13 14:39:35 2020 +0900
Imported from u-boot-a600-v2018.03-at7.tar.gz
ベースとなるソースコードの更新は、
master
ブランチに対して行っていきます。
流れとしては次のとおりです。
-
master ブランチのチェックアウト
-
古くなったソースコードの削除
-
新しいソースコードのダウンロード
-
新しいソースコードの展開
-
新しいソースコードのgit add, git commit
master
ブランチをチェックアウトし、
古くなったソースコードの削除していきますが、
その前に
git commit
していない変更がないかを
git status
で確認してください。
当然ながら、ファイルを削除すると、
git commit
していない変更は失われ、
復元できなくなります。
[ATDE ~/u-boot-a600-v2018.03-at]$ git status
On branch x11a
nothing to commit, working tree clean
ソースコードの削除には
git rm
を使用します。
git rmはGitリポジトリに登録されているファイルを削除するコマンドです。
それでは、
master
ブランチをチェックアウトし、
古くなったソースコードの削除していきます。
[ATDE ~/u-boot-a600-v2018.03-at]$ git checkout master
Switched to branch 'master'
[ATDE ~/u-boot-a600-v2018.03-at]$ git rm -r --ignore-unmatch $(find . -mindepth 1 -maxdepth 1)
| |
---|
git rm -r --ignore-unmatch
は、指定されたGitリポジトリに登録されているファイルを全て削除する、
という意味になります。
-r オプションでディレクトリ内のファイルを再帰的に削除し、
--ignore-unmatch
オプションでGitリポジトリに登録されていないファイルが指定されていても、
コマンドがエラーしないようにしています。 |
Gitリポジトリ登録されていないファイルがなければ、以下のように
".git"
だけがある状態になります。
[ATDE ~/u-boot-a600-v2018.03-at]$ ls --all -1
.
..
.git
次に新しいソースコード
(u-boot-a600-v2018.03-at8.tar.gz)
をダウンロードし、Gitリポジトリに展開し、
不要なファイルは削除します。
[ATDE ~/u-boot-a600-v2018.03-at]$ wget https://download.atmark-techno.com/armadillo-640/source/u-boot-a600-v2018.03-at8.tar.gz
[ATDE ~/u-boot-a600-v2018.03-at]$ tar xf u-boot-a600-v2018.03-at8.tar.gz
[ATDE ~/u-boot-a600-v2018.03-at]$ ls --all -1 u-boot-a600-v2018.03-at8
.
..
.checkpatch.conf
.gitignore
.mailmap
.travis.yml
Documentation
Kbuild
Kconfig
Licenses
MAINTAINERS
Makefile
README
api
arch
board
cmd
common
config.mk
configs
disk
doc
drivers
dts
env
examples
fs
include
lib
net
post
scripts
snapshot.commit
test
tools
[ATDE ~/u-boot-a600-v2018.03-at]$ mv $(find u-boot-a600-v2018.03-at8 -mindepth 1 -maxdepth 1) ./
[ATDE ~/u-boot-a600-v2018.03-at]$ rmdir u-boot-a600-v2018.03-at8/
[ATDE ~/u-boot-a600-v2018.03-at]$ rm u-boot-a600-v2018.03-at8.tar.gz
新しいソースコードをGitリポジトリに登録します。
[ATDE ~/u-boot-a600-v2018.03-at]$ git add -f $(find . -mindepth 1 -maxdepth 1)
[ATDE ~/u-boot-a600-v2018.03-at]$ git commit -m"Update to u-boot-a600-v2018.03-at8"
[ATDE ~/u-boot-a600-v2018.03-at]$ git log
commit 761d05239a5deeedbba1a915cab099cf31a06b53
Author: atmark <atmark@atde7>
Date: Wed May 13 16:23:03 2020 +0900
Update to u-boot-a600-v2018.03-at8
commit 8c22d30fcb0c254d3f0cf28cb9da4611a7100d70
Author: atmark <atmark@atde7>
Date: Wed May 13 14:39:35 2020 +0900
Imported from u-boot-a600-v2018.03-at7.tar.gz
これで、ベースとなるソースコードの更新は完了です。
8.8.1.5. 更新後のベースとなるソースコードにソースコードの修正を適用
更新後のベースとなるソースコードに
「ソースコードの修正」
を適用していきます。
この作業は、コンフリクトが起きなければ、
非常に簡単です。
| |
---|
Gitが自動でブランチを統合できないことをコンフリクト
(conflict)
といいます。 |
流れとしては次のとおりです。
-
適用するソースコードの修正を行ったブランチをチェックアウト
-
git rebaseで更新後のベースとなるソースコードのブランチにリベース
[ATDE ~/u-boot-a600-v2018.03-at]$ git checkout x11a
Switched to branch 'x11a'
[ATDE ~/u-boot-a600-v2018.03-at]$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: デフォルトの環境変数にaguideを追加
Using index info to reconstruct a base tree...
M include/configs/armadillo-640.h
Falling back to patching base and 3-way merge...
Auto-merging include/configs/armadillo-640.h
Auto packing the repository in background for optimum performance.
See "git help gc" for manual housekeeping.
[ATDE ~/u-boot-a600-v2018.03-at]$ git log
commit 40a9afcdcfc585feb23575338b93ee279a2c2a44
Author: atmark <atmark@atde7>
Date: Wed May 13 15:13:38 2020 +0900
デフォルトの環境変数にaguideを追加
commit 761d05239a5deeedbba1a915cab099cf31a06b53
Author: atmark <atmark@atde7>
Date: Wed May 13 16:23:03 2020 +0900
Update to u-boot-a600-v2018.03-at8
commit 8c22d30fcb0c254d3f0cf28cb9da4611a7100d70
Author: atmark <atmark@atde7>
Date: Wed May 13 14:39:35 2020 +0900
Imported from u-boot-a600-v2018.03-at7.tar.gz
以上で完了となります。
コンフリクトが起きた際は、
コマンド(git rebase)
が出力したメッセージに従って修正作業をしていくことになります。
どのような修正を行うかは、その時々で異なるので、
具体的な説明はできません。
修正前のソースコードはどんなものだったのか、
どんな修正なのか、といった視点からその修正が必要なのかを判断し、
修正していく必要があります。
git rebaseでコンフリクトが起き、
とりあえずブランチをもとの状態
(git rebase 前の状態)
に戻したい場合は、
git rebase --abort
を実行します。
[ATDE ~/u-boot-a600-v2018.03-at]$ git rebase --abort
8.8.4. インターネットを使用してのアップデート
インターネットから最新のソフトウェアをダウンロードしてアップデートする方法を紹介します。
8.8.4.1. APT でインストールしたソフトウェアのアップデート
実は apt コマンドでインストールしたソフトウェア(debian package)については既に、
定期的に最新のソフトウェアをインターネットからダウンロードしてインストールする機能が、
有効になっています。
この機能は、 APT(debian package) に含まれている
複数の Unit ファイルによって実現されています。
この
APT の自動アップデート機能が有効になっているかどうかは、
次のようにして確認できます。
apt-daily-upgrade.timer
と
apt-daily.timer
が enabled なら有効になっています。
[armadillo ~]# systemctl list-unit-files | grep apt
apt-daily-upgrade.service static
apt-daily.service static
apt-daily-upgrade.timer enabled
apt-daily.timer enabled
apt の自動アップデート機能を利用するだけであれば、
以上の情報があれば十分ですが、
ここからは、APT の
Unit ファイルについて簡単に解説しておきます。
インターネットを使用してのアップデートの実装の一つとして、
参考になるはずです。
|
6時および18時にタイマーが起動するよう設定しています。
|
|
タイマーの起動を設定時刻から最大12時間後まで、
ランダムに遅らせるよう設定しています。
|
RandomizedDelaySec の項目は非常に重要です。
Armadilloを量産した際、全てのArmadilloに
図8.14「/lib/systemd/system/apt-daily.timer」
が書き込まれて動作します。
この場合、RandomizedDelaySec の設定をしていなければ、
全てのArmadilloが、
6時または18時ちょうど(つまりほぼ同時)に、
サーバーにアクセスするため、
サーバーに多大な負荷がかかってしまいます。
|
apt upgrade は、
apt update を実行した後でなければ実行する意味がないため、
apt-daily.timer
の後に動作するよう設定しています。
|
|
6時にタイマーが起動するよう設定しています。
|
|
タイマーの起動を設定時刻から最大60分後まで、
ランダムに遅らせるよう設定しています。
|
|
インターネット接続後でなければアップデートできないため、
network-online.target
の後に起動するよう設定しています。
|
|
インターネット接続後でなければアップデートできないため、
network-online.target
が起動される場合のみ起動するよう設定しています。
|
|
apt upgrade は、
apt update を実行した後でなければ実行する意味がないため、
apt-daily.service
の後に動作するよう設定しています。
|
|
停止の要求を出してから、停止まで 900 秒間は待つよう設定しています。
|
8.8.4.2. APT でインストールしたソフトウェア以外のソフトウェアのアップデート
APT でインストールしたソフトウェア以外のソフトウェアと言うと、
次のようなソフトウェアが該当します。
-
ブートローダーイメージ
-
Linuxカーネルイメージ
-
DTB(Device Tree Blob)
-
APT 以外のパッケージ管理ソフトウェア[]でインストールしたソフトウェア
-
C や Python などで自作したアプリケーション
-
アプリケーションの起動を管理するための自作 Unit ファイル
「APT 以外のパッケージ管理ソフトウェアでインストールしたソフトウェア」については、
パッケージ管理ソフトウェアでのアップデートを定期的に実行すれば良いでしょう。
それ以外のソフトウェアについては、
大量にあると制御が大変なので、
tar コマンドで1つに結合したファイルをWebサーバーに配置しておくことにします。
例として、次のような動作を考えます。
-
毎日定時に特定のシェルスクリプトを実行する。
シェルスクリプトでは、以下の処理をおこなう。
-
pip でインストールしたパッケージのアップデート確認
-
必要であれば、pip でインストールしたパッケージのアップデート
-
Webサーバーにアクセスし、更新すべきソフトウェアがあるか確認する。
-
ファイルがある場合、ダウンロードしてストレージに書き込みアップデート。
-
正常に書き込みが完了したら、変更を反映するためにリブート。
毎日定時にスクリプトを実行する処理には、systemdを利用することにします。
systemdについては、
「systemdで定期実行する」
を参照してください。
毎日4:00に処理を実行する場合の設定は以下のようになるでしょう。
ただし、製品を量産した時のことを考慮して
RandomizedDelaySec
を設定し、
4:00ちょうどには実行しないようにします。
イメージのアップデートを行うスクリプトは、
/root/web_software_update.sh
という名前だとします。
systemdから実行される
web_software_update.sh
は、次のようになります。
pip-review
により pip でインストールした
Python の各種パッケージをアップデート、
その後、ブートローダー、Linuxカーネル、DTB、アプリケーションについて、
最新バージョンのチェックを行い、
最新バージョンがインストールされていなかった場合は、
ソフトウェアの更新を行ってから
Armadillo
を再起動させます。
SERVER_IP_ADDRESS(WebサーバーのIPアドレス)、
PROTCOL(httpまたはhttps)、
USER_NAME(認証を行う場合のユーザー名)、
PASSWORD(認証を行う場合のパスワード)等の各変数は、
環境に合わせて書き換えてください。
wgetコマンドは、httpsプロトコルを使用することができます。
また、USER_NAME
と
PASSWORD 変数を指定することで、
basic認証またはdigest認証を利用できます。
| |
---|
html2 コマンドを使用するには、
xml2
をインストールしておく必要があります。 [armadillo ~]# apt install xml2 |