boot.scrは、U-BOOTコマンドをバッチ実行するバイナリ化されたブート用スクリプトファイルです。 各転送やブートの設定を自動で実行出来るように記述します。 組込みLinuxでU-BOOTを使う場合、このboot.scrは非常に重要なのでここで少し紹介しておきます。
boot.scrの構成
- U-BOOTシェルコマンドで記述
- ブート用の環境変数に値設定
- 新しい環境変数の定義と初期値設定
テキストファイルを作成
U-BOOTシェルコマンドでスクリプトとしてテキストファイルを作り、mkimageでバイナリ化する。 テキストファイル名はなんでも構いませんが、バイナリ化ファイル名はboot.scrでなければなりません。 拡張子はtxtでもcmdでもOK。 以下の例は、microSDからブートし、TFTPでホストPCからKernel ImageのuImageとデバイスツリーの.dtbをDDRにロードして、Kernelが立ち上がって、microSDの第2パーティションをファイルシステムext3のルートFSとしてマウントしています。 このページの下の方でboot.scrに変換しています。
echo **************Wowowo ichiri************ setenv ipaddr 192.168.27.2 setenv serverip 192.168.27.1 setenv loadaddr 0x82000000 setenv fdtaddr 0x88000000 echo ********** Booting from microSD ... ******* setenv autoload no tftpboot ${loadaddr} uImage tftpboot ${fdtaddr} am335x-boneblack.dtb setenv bootargs console=ttyS0,115200n8 noinitrd rootfstype=ext3 root=/dev/mmcblk0p2 rw mem=512m debug rootwait bootm ${loadaddr} - ${fdtaddr}
例で使われているコマンド等説明
- echoは、画面上に文字表示させる。 ””で囲っても囲わなくてもOK。
- setenvは、変数に値を設定。 setenv ipaddr 192.168.27.2はU-BOOTの予約環境変数のipaddrにBBBのアドレスとして設定している。 serveripも予約環境変数で、U-BOOTでtftpやnfsを使う時にサーバーのアドレスとして設定する。 これらのアドレスや環境変数はKernelが起動するとbootargs以外は引き継がない。アドレスはなくなるので初期設定シェルスクリプトで設定が必要。
- tfptbootは、予め設定されたtftpサーバーからuImageや.dtbをtftp通信でダウンロードして、DDRの指定アドレスから格納しています。
- bootmは、uImageと.dtbがDDRに格納されている先頭アドレスを指定して、DDRメモリからKernelを起動するコマンド。
- ${変数名} で変数の値を代入できる。
- 変数は、複数のコマンドを保持できる。 複数コマンドを保持する場合『;』で区切る。
- 変数にコマンドが入っていると、run 変数名で実行することができる。
実行内容説明
- 行目は、正常にboot.scrが呼び出されたら、『**********Wowowo ichiri************』が表示されます。 表示されなかったら、何かの問題でboot.scrが認識されていないことになります。
- 行目は、自分自身(この場合BBB)のIPアドレスを示すU-BOOT予約環境変数 ipaddrにIPアドレスを設定しています。 サーバーと同じネットマスク(この場合、192.168.27)でなければなりません。
- 行目は、TFTPサーバーとしてのホストPC(私の場合、uBuntu PC)のLANポートのIPアドレスをU-BOOTに登録しています。 U-BOOTがBBBからTFTP通信をする時、serveripのIPアドレスでサーバーを探しに行きます。 ホストPC側でもLANポートのIPアドレスをこのserveripと同じに設定しておく必要があります。 またTFTPサーバーとしての設定が必要ですが、次の回で説明します。
echo **************Wowowo ichiri************ setenv ipaddr 192.168.27.2 setenv serverip 192.168.27.1
- 行目は、uImageをDDRにロードする先頭アドレス用のU-BOOT予約環境変数の、loadaddrに、アドレス0x82000000を設定しています。 通常、BBB用のdefconfigファイルを指定してU-BOOTをビルドするので、loadaddrには既に0x82000000、ftdaddrには0x88000000が入っているので、これらの行は書いても書かなくても構いません。 因みに、BBBの場合、DDRのベースアドレスは0x80000000と決まっており、その情報はMLOのヘッダに書かれていて、MLOのではu-boot.imgを0x80000000にロードします。 なので、余裕を持って、uImageは0x82000000に書かれるようになっていますが、u-boot.imgが肥大化したり、uImageが肥大化した時は、お互い上書きされて動作品かならないように、ロードアドレスを調整したり、不要機能を削ってイメージファイルを小さくする必要があります。
- 行目は、.dtbをDDRにロードする先頭アドレス用のU-BOOT予約環境変数の、ftdaddrに、アドレス0x88000000を設定しています。
- 行目は、『Booting from microSD』と表示します。 これでここまでは正常に実行されたことが分かります。
- 行目は、boot.scrで起動をかけていくので、U-BOOTに組み込まれた自動ブートをしない様に、U-BOOT予約環境変数のautoloadにnoを設定してます。
setenv loadaddr 0x82000000 setenv ftdaddr 0x88000000 echo ********** Booting from microSD ... ******* setenv autoload no
- 行目は、TFTP通信を使って、uImageファイルをダウンロードしてDDRのloadaddrのアドレスにロードします。 loadaddrは上で0x82000000で設定しています。 ${変数名}で変数内の値を取り出します。 TFTPはTrivial File Transfer Protocolで通常のTCPのFTPでなく、UDPでしょうもない(Trivial:ささいな)FTPという意味です。 しかし、サイズを軽量にしなければならないu-boot.imgでTFTPで実行できると、UARTに比べ転送速度が格段に速いので非常に重宝します。
- 行目は、同様に、デバイスツリーをDDRのftdaddrの値のアドレスにロードしています。
tftpboot ${loadaddr} uImage tftpboot ${ftdaddr} am335x-boneblack.dtb
- 行目は、Kernelに引数を引き渡すことが出来る、U-BOOT予約環境変数のbootargsに各種設定をせっていしています。
- consoleは、Kernelが立ち上がってもttyS0という名前で、115200n8設定で通信するように設定
- noinitrdは、initrd(initramfsの前身)は使用せず、uImageだけでルートファイルシステムを立ち上げるのでinitrdを探してエラーで落ちるなとの指定。
- rootfstypeは、マウントしたルートFSのファイルシステムはext3だと指定。(通常はext4が一番良いいのですが、私のmicroSDはext3で設定してしまったのでext3としています。) ext4だと指定は不要と思います。
- rootはルートFSが格納されているデバイスとパーティションを示しています。 mccblk0p2はmicroSDの第2パーティション。 rwにしておかないと、書き込みが出来ず、ルートFSが立ち上がらない。 エラーログも取れない。
- memは、Kernelにどれだけのメモリーを使っていいか指定しています。
- debugは、Kernelが立ち上がって、ルートFS をマウントして初期化スクリプト完了まで、詳細なKernelメッセージを表示する指定です。 量産時は不要ですが、デバッグ時は助けになります。
- rootwaitは、ルートFSをマウントする際いろいろなデバイスドライバが起動するまで時間がかかりエラーで落ちないよう、待つ指定を入れています。 すぐ起動がかかれば無視されるので、お決まりで入れておいたほうが良いです。
- 行目は、uImageのloadaddrと.dtbのftdaddrを指定して、メモリからブートをしています。
setenv bootargs console=ttyS0,115200n8 noinitrd rootfstype=ext3 root=/dev/mmcblk0p2 rw mem=512m debug rootwait bootm ${loadaddr} - ${ftdaddr}
boot.scrバイナリファイルに変換
- mkimageで以下の様に、boot_sd_tftp.cmdテキストファイル(ファイル名は何でも構いません)をboot.scrに変換します。
- そして、boot.scrはMLO, u-boot.imgと一緒にmicroSDの第1パーティションにコピーします。
- -A : architecture
- -O : operating system
- -C : compression type
- -T : type
- -a : load address
- -e : entry point
- -d : data file
- -n : image nage
$ mkimage -A arm -O linux -T script -C none -a 0 -e 0 -d boot_sd_tftp.cmd boot.scr
mkimageコマンドはU-BOOTには含まれていません。 別途、aptでインストールが必要です。
$ sudo apt update $ sudo apt install u-boot-tools //私の場合はこちらでインストールしました。 // 又は、sudo apt install uboot-mkimage //こっちは試していませんが、mkimageだけインストールするので少ない容量のはずです。
mkimageはboot.scr以外にも色々なイメージファイルを生成できます。 生成できるイメージタイプを以下でリストアップします。
$ mkimage -T list
boot.scr中身
バックアップを取ってからboot.scrを見ます。 boot.scrは、記述した文字列の先頭にバイナリのヘッダが追加されます。 なので中身を見ると元の文字列が見えるのでデバッグ時には便利です。 バイナリ部分を削除して文字部分を編集して、再度mkimageでboot.scrに変換するとboot.scrを編集できます。
boot.scr実行例
u-boot.imgがboot.scrを見つけて、呼び出し実行すると、以下のようなメッセージがminicomに表示されます。
Found U-Boot script /boot.scr // Found となる 734 bytes read in 4 ms (178.7 KiB/s) // バイト数が表示される(上記のファイルとは異なるので数値は異なると思います) ## Executing script at 80000000 // MLOはDDRの0x8000000にロードされboot.scrを呼び出しています **************Wowowo ichiri************ ********** Booting from microSD ... ******* link up on port 0, speed 100, full duplex Using cpsw device // TIのEthernetサービスcpswが立ち上がって TFTP from server 192.168.27.1; our IP address is 192.168.27.2 //TFTPサーバーを検知して Filename 'uImage'. Load address: 0x82000000 //uImageをDDRの0x82000000に転送開始したのが分かります Loading: ###################### : :
(参考)その他のboot.scr if文、for文
if文
if test "${boot_target}" = "mmc0" || test "${boot_target}" = "mmc1"; then if run loadimage; then run mmcboot; fi fi
for文
for boot_target in ${boot_targets}; do echo item ${c}; done item 1 item 2 item 3
||で条件実行
左辺が真であれば、右辺は実行されない。 偽であれば実行される。
U-BOOTコマンド、変数一覧
その2でも紹介しましたが、上記boot.scrの参考用にここにも入れておきます。
コマンド・予約変数 | 説明 | |
---|---|---|
? | コマンド | helpと同じ |
addrmap | コマンド | 32bit CPU用の仮想物理メモリマップを表示する => addrmap vaddr paddr size ================ ================ ================ e0000000 fe0000000 00100000 00000000 00000000 04000000 04000000 04000000 04000000 80000000 c00000000 10000000 90000000 c10000000 10000000 a0000000 fe1000000 00010000 |
askenv | コマンド | 標準入力からの入力で環境変数を設定... => askenv env1;echo $? Please enter 'env1': val1 |
autoscr | コマンド | メモリ上のスクリプトの実行 |
base | コマンド | 標準入力からの入力で環境変数を設定... |
bdinfo | コマンド | ボードの情報を表示 |
boot | コマンド | ブートコマンド |
bootelf | コマンド | ELF イメージの uboot 用アプリケーションの実行.. |
bootm $kernel_addr $dtb_addr | コマンド | 指定した番地に格納されているカーネルとinitを起動させる。 //指定したKernelアドレスとdtbアドレスを指定してブートを開始する bootm 0x82000000 - 0x88000000 OSとアプリケーションの起動 |
bootp | コマンド | BOOTP プロトコルで IPv4 アドレスを取得. |
bootvx | コマンド | ELF イメージの vxWorks を起動 |
bootz ${loadaddr} - ${fdtaddr} | コマンド | bootmと同じ。zImage時に使う。 |
bubt ${file_name} | コマンド | u-bootを更新するときに使う。仕組みはtftpで$file_nameのイメージファイルを取得しFlash ROMなど適切なところにオーバライドする。 予めネットワークの設定が必要 Burn an ATF image on the Boot Nand Flash ? |
cat | コマンド | ファイル内を文字列で表示 => cat mmc 0:1 hello hello world |
chpart | コマンド | アクティブパーティションの変更 |
cmp | コマンド | メモリの比較 |
coninfo | コマンド | コンソールデバイスの表示 |
cp | コマンド | メモリ間のコピー |
dhcp | コマンド | DHCP プロトコルで IPv4 アドレスを取得 |
echo | コマンド | u-boot.imgがブートしている時に表示できる。 "ありでもなしでも動作する。 echo ****ichiri**** echo "****ichiri****" |
echp | コマンド | テキストを表示. |
setexpr[.b, .w, .l .s] setexpr[.b, .w, .l] setexpr setexpr setexpr | コマンド | 評価の結果により環境変数に値を書き込む また、指定のフォーマットで値を設定する => setexpr foo fmt %d 0x100 => echo $foo 256 => setexpr foo fmt 0x%08x 63 => echo $foo 0x00000063 |
cmp [.b, .w, .l, .q] addr1 addr2 count | コマンド | メモリの内容比較 => cmp 0x1000000 0x101000 0xc |
env | コマンド | 環境変数操作 env default env default -a --- 全ての環境変数を初期値に戻す env delete env grep --- 文字列を環境変数から検索 env print --- printenvと同じ env save --- saveenvと同じ env set ---setenvと同じ |
env import 0x80200000 No_of_bytes | コマンド | env import 0x80200000 No_of_bytes |
erase | コマンド | フラッシュメモリの消去. |
event | コマンド | EVENT_SPYで発行された一覧を表示する。 デバッグ用。 もしCONFIG_EVENT_DEBUG=yでなければ、SPYのラベルは『unknown』で表示される。 |
exit | コマンド | スクリプトの終了 |
ext4load | コマンド | ext4フォーマットからファイル読み出し |
fatload | コマンド | fatファイルシステムからファイルを読むコマンド |
flinfo | コマンド | ファイルシステム情報の表示 |
for | コマンド | forループコマンド => for c in 1 2 3; do echo item ${c}; done item 1 item 2 item 3 |
fpga loadb mmc | コマンド | u-bootからFPGAをコンフィグレーションするための変数 |
fsinfo | コマンド | フラッシュ上のファイルシステムからファイルのロード |
go | コマンド | uboot 用アプリケーションの実行 |
gpio gpio read gpio status [-a] [ | コマンド | General Purpose IOのアクセス gpio input:入力モード変更 gpio set:出力モード変更、出力のOn/Off gppio clear gpio toggle gpio read gpio status |
help help | コマンド | help |
imiinfo | コマンド | アプリケーションイメージヘッダの表示 |
imls | コマンド | フラッシュの中にあるイメージを探す. |
itest | コマンド | 整数と文字列の比較テスト |
load | コマンド | ファイルを読み出してデバイスに書き込み。 //SDカードのパーティション2の/boot/ディレクトリからam33x-boneblack.dtbを読み出し、DDRの0x88000000に書き込む。 load mmc 0:2 0x88000000 /boot/am33x-boneblack.dtb またメモリから読み出してファイルに書き込むことも可能 => load mmc 0:1 $loadaddr test.txt 260096 bytes read in 13 ms (19.1 MiB/s) |
loadb | コマンド | シリアル経由でファイルのダウンロード(kermit モード).... |
loads | コマンド | シリアル経由で S レコード形式のファイルのダウンロード |
loadx ????? | コマンド | Xmodemでファイル転送? |
loop | コマンド | 指定した範囲のアドレスを読み続ける無限ループ. |
ls | コマンド | ファイルシステムの中身を一覧表示 ls ls mmc 0:1 |
md <.オプション> $addr <$len> | コマンド | Memory Dump 指定したアドレスの内容を表示する 例:md.l 0xc1932588 0x500 <オプション> b:1バイト w:2バイト(Word) l:4バイト(Long:default) q:8バイト(Quadword) <$len> 16進 0x40 (default) |
mm $addr | コマンド | アドレス番地を指定した後に、ライトしたい内容を16進で記述 |
mmc指定 | コマンド | mmc info --現在指定されているmmcデバイス情報表示 mmc list --使用できるmmcデバイス一覧表示 mmc |
mtest | コマンド | 簡単なメモリのテスト |
mw | コマンド | nm mmと同じだが、同じアドレスを終了するまで何回も変更できる。GPIOレジスタを指定して次々値を変化させるなどで便利。 |
nand | コマンド | nand メモリへのアクセス nand erase 0x200000 0x1e0000 nand erase.part kernel nand erase.part rootfs nand write 0x18100000 0x200000 0x1e0000 nand write 0x18100000 kernel 0x600000 nand write.trimffs 0x18100000 rootfs $filesize |
nfs | コマンド | NFS プロトコルでファイルをダウンロード nfs 0x82000000 192.168.27.1:/srv/nfs/bbb/uImage |
nm | コマンド | 同一アドレスのメモリ内容を対話的に変更 |
pci | コマンド | PCI バスの一覧と、PCI コンフィグレーションスペースのアクセス. |
printenv | コマンド | 変数を指定しないと、変数一覧を表示 |
printenv $env print $env | コマンド | 変数$envを表示する。ちなみに、printとだけ打つと全部の変数が出てくる。 printenv soc //特定の環境変数を見れる |
ping | コマンド | ICMP ECHO_REQUEST パケットを指定ホストに送る |
protect | コマンド | フラッシュメモリのプロテクトの設定 |
rarpboot | コマンド | RARP プロトコルで IPv4 アドレスを取得 |
reset | コマンド | CPU のリセット |
run $env | コマンド | 変数内容を実行する |
sleep | コマンド | 指定した秒数遅延させる |
setenv $env arg setenv $env 'arg1 arg2' | コマンド | 変数を$envをセットする。 setenv serverip 192.168.27.2 スペースがある場合は囲いが必要。 setenv my_own_var 'mmc list' シェルスクリプトのように複数のコマンドを変数を入れrunで実行することもできる。 コマンドの区切りは『;』 run my_own_var // ログメッセージの出力先指定とルートファイルシステムの場所指定 setenv bootargs console=ttyO0,115200 root=/dev/mmcblk0p2 rw //mmcblk0p2はmmc 0:2と同じだが、bootargsには/dev/mmcblk0p2で指定する。 |
saveenv | コマンド | setenvで内容を書き換えても揮発する。これでFlash ROMなどに値が保存される 実際のセーブ先はソースコードを見る。 |
sound | コマンド | CONFIG_CMD_SOUND=y時 sound init サウンドドライバ初期化 sound playビープを鳴らす len: 初期値1000ms freq:初期値400Hz |
test | コマンド | シェルライクな test の最小限の実装. |
temperature list temperature get [thermal device name] | コマンド | !ERROR! C69 -> Formula Error: Unexpected operator '>' |
tftpboot アドレス ファイル名 | コマンド | tftpサーバーのtftpルートフォルダからファイルを取得して、アドレスにロードする |
tftpput address size [[hostIPaddr:]filename] | コマンド | ClientのメモリからHostにファイルを転送する。先にファイルサイズを知る必要がある。 => load mmc 0:1 $loadaddr test.txt 260096 bytes read in 13 ms (19.1 MiB/s) => tftpput $loadaddr $filesize 192.168.1.3:upload/test.txt |
ums | コマンド | USBメモリにアクセス確認 devは、mmc, sata, scsi, usb, ... CONFIG_CMD_USB_MASS_STORAGE=yが必須で、CONFIG_USB_USB_GADGET と CONFIG_BLKの設定次第 |
usb start usb reset usb stop | コマンド | USBをホストとして使う時に使用 usb info usb storage usb dev usb part usb read addr blk# cnt usb write addr blk# cnt |
version | コマンド | uboot のバージョンの表示 |
wget address [[hostIPaddr:]path] | コマンド | HTTP over TCP @Port:80 => wget ${loadaddr} 192.168.1.254:/index.html |
xxd | コマンド | 文字列やファイルを簡単にメモリに書き込める => xxd mmc 0:1 hello 00000000: 68 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 01 02 03 hello world..... 00000010: 04 05 |
IFS | 予約変数 | Hush パーサのトークンのセパレータで |
autoload | 予約変数 | bootp, dhcp, rarpboot コマンドで IP アドレスを取得したあと、自動的にファイルをダウンロードするかどうかを決める |
autoscript | 予約変数 | |
autostart | 予約変数 | |
boudrate | 予約変数 | コンソールのボーレートを設定。 9600 | 19200 | 38400 | 57600 | 115200 初期値115200 |
bootaddr | 予約変数 | |
bootargs | 予約変数 | OS に渡す起動パラメータを設定。 |
bootcmd | 予約変数 | デフォルトのカーネル起動方法を設定。 起動時に自動で実行されるコマンドを入れておく変数。 tftp $kernel_addr uImage; tftp $initrd_addr initramfs: bootm $kernel_addr $initrd_addr などと書いておけば、tftpして起動する。 |
bootdelay | 予約変数 | |
bootfile | 予約変数 | |
boot_scripts | 予約変数 | setenv boot_scripts boot.scr2 boot 初期値では、boot.scrしか見ないが、別のブートスクリプトファイル名を指定してブート出来る。 デバッグ時、boot.scrで失敗した後、U-BOOTプロンプトからバックアップのboot.scr2で起動することが出来る。 |
dnsip2 | 予約変数 | |
domain | 予約変数 | |
ethact | 予約変数 | |
ethaddr | 予約変数 | |
eth1addr | 予約変数 | |
ethprime | 予約変数 | |
fileaddr | 予約変数 | |
filesize | 予約変数 | |
ftdaddr | 予約変数 | デバイスツリーブロブの.dtbをDDRにロードする先頭アドレス。 BBBの場合は、初期値は0x88000000 |
gatewayip | 予約変数 | |
hostname | 予約変数 | |
ipaddr | 予約変数 | 自身のIPアドレス |
loadaddr | 予約変数 | Linux KernelのバイナリuImageをロードする先頭アドレス BBBの場合は、初期値は0x82000000 Zynq-7000 DDRベースアドレス 0x30000000 Zynq-UltraScale+ MPSoCとVersal ACAP DDRベースアドレス 0x20000000 |
loads_echo | 予約変数 | |
netmask | 予約変数 | 255.255.255.0でスラッシュ24と同じ意味 |
netentry | 予約変数 | |
nfsargs | 予約変数 | |
nfsbase | 予約変数 | setenv nfsbase 192.168.3.91:/usr/src/mldbox/ |
nvlan | 予約変数 | |
preboot | 予約変数 | 自動起動の前に実行するコマンドを設定 |
rootpath | 予約変数 | |
serveripclear | 予約変数 | tftpのサーバやnfsサーバドレス設定 |
stdin | 予約変数 | 標準入力に使うデバイスを設定 |
stdout | 予約変数 | 標準出力に使うデバイスを設定 |
stderr | 予約変数 | 標準エラー出力に使うデバイスを設定 |
verify | 予約変数 | |
vlanコマンド.q:8バイト(Quadword) | 予約変数 | |
uenvcmd | uEnv.txt専用変数 | uEnv.txtの最後の行に書くお決まりの変数名。 u-boot.imgはuEnv.txt内の左辺のuenvcmdを見ると、その右辺を実行していく |
root | bootargs引数 | マウントする場所を指定 rwがないと書き込みできない root=/dev/nfs rw |
rootfsstype | bootargs引数 | SDの第2パーティションにルートFSがあり、フォーマットがext4のとき rootfstype=ext4 NFSにルートFSがある時 rootfstype=nfs |
console | bootargs引数 | UARTコンソール入出力ポート名と転送Baudrateとフォーマット指定 console=ttyS0,115200n8 |
debug | bootargs引数 | Kernelブート詳細メッセージ表示 |
コメント