本章では、 Armadillo-600シリーズのブートローダーである U-Boot の起動モードや利用することができる機能について説明します。
| |
---|
Armadillo-200 シリーズ、400シリーズでは、ブートローダーに Hermit を使用していました。 Armadillo-600シリーズ では、他の最近の Armadillo シリーズ (Armadillo-IoT など) に合せ、U-Boot を採用しています。 |
U-Boot は Open Source で開発されているブートローダーで、特に組み込み機器に良く使われています。 U-Boot のマニュアルは、 Denx Software Engineering の U-Boot のページ (https://www.denx.de/wiki/U-Boot/WebHome) からアクセスできます。
U-Boot はブートローダーなので、OS を起動するのが仕事です。しかし OS を起動する以外にも、いろいろと便利な機能が U-Boot には備わっています。
Armadillo-600シリーズ の U-Boot には 2つの起動モードがあります。「保守モード」と「オートブートモード」です。 Armadillo-600シリーズ に接続している USBシリアル変換アダプターのスライドスイッチによって、モードを切り替えることができます。 Armadillo-400シリーズの Hermit にもあった機能です。このモード切り換えは、 GPIO によって実現しています。 U-Boot 本家にはまだマージされておらず、 Armadillo-600シリーズ 用の U-Boot に独自実装されている機能です。
ブートローダーが起動すると、USBシリアル変換アダプタのスライドスイッチの状態により、2つのモードのどちらかに遷移します。USBシリアル変換アダプタのスライドスイッチの詳細については、「スライドスイッチの設定について」を参照してください。
表9.1 ブートローダー起動モード
起動モードの種別 | スライドスイッチ | 説明 |
---|
保守モード | 外側 | 各種設定が可能なU-Bootコマンドプロンプトが起動します。 |
オートブートモード | 内側 | 電源投入後、自動的にLinuxカーネルを起動させます。 |
| |
---|
USBシリアル変換アダプタが未接続の場合オートブートモードとなり、Linuxが起動します。 |
U-Boot が起動すると、U-Boot のバージョンや、ビルド時間、CPUの情報、DRAMのサイズなどボード情報が表示されます。
⇒
が U-Boot のプロンプトです。プロンプトが出るのは保守モードの時だけです。Armadillo-600シリーズ では U-Boot のプロンプトが表示され、コマンド入力を受け付ける状態を「保守モード」と呼んでいます。
U-Boot の 機能を使うには U-Boot のコマンドプロンプトからコマンドを入力します。コマンドプロンプトは保守モードにすることで表示されます。
U-Bootの保守モードでは、U-Bootのバージョン番号を表示したり、あるメモリアドレスの値を表示したり Linuxカーネルの起動オプションの設定などを行うことができます。保守モードで利用できる有用なコマンドは、プロンプトで help
と入力すると表示されます。
各コマンドのヘルプを表示するにはU-Bootコマンドのヘルプを表示のようにします。
良く使うと思われるコマンドを以下で説明します。
-
boot
-
環境変数
bootcmd
に指定されているコマンドを実行。デフォルトでは Linuxを起動。オートブートモード時はこのコマンドが呼ばれている
-
env
-
U-Boot の環境変数に関連したコマンド (下記で詳しく説明)
-
ext4load
-
Ext4ファイルシステムからファイルをメモリにロード
-
ext4ls
-
Ext4ファイルシステムにあるファイルをリスト
-
fuse
-
CPUの内部 Fuse の値の読み書き
-
help
-
コマンド一覧、または指定されたコマンドのヘルプを表示
-
mmc
-
MMC/SD 関連のコマンド群 「mmc コマンド」 で詳しく説明
-
ping
-
ICMP ECHO_REQUEST を送信
-
run
-
環境変数に登録されているコマンドの実行
-
tftpboot
-
TFTP による起動
-
usb
-
USB関連のコマンド群
-
version
-
U-Boot のバージョン番号表示
help
で表示されるコマンドには、Git のようにサブコマンドを持つものがあります。 env
や usb
などがそうです。 help env
とすることで、 指定したコマンドのサブコマンドが表示されます。
-
env default
-
環境変数をリセット
-
env delete
-
指定した環境変数を削除
-
env grep
-
指定した文字列を環境変数から検索
-
env print
-
指定した環境変数を表示します。指定が無ければ、すべて表示。
printenv
コマンドと同じ
-
env save
-
環境変数を eMMC に保存。
saveenv
コマンドと同じ。「U-Boot の環境変数」 で詳しく説明
-
env set
-
環境変数を設定。
setenv
コマンドと同じ
-
mmc info
-
現在指定されている MMCデバイスの情報を表示
-
mmc list
-
ボード上の MMCデバイスのリストを表示
-
mmc dev
-
現在指定されている MMCデバイスを表示。または指定された番号で示されるMMCデバイスを選択
U-Boot は、環境変数を持つことができます。デフォルトの環境変数は、U-Boot をビルドした時に値が決定します。実行に環境変数を変更したり、変更した環境変数を保存したりすることも可能です。
env print
コマンドで、現在設定されているすべての環境変数を表示できます。
=> env print
baudrate=115200
bootcmd=run setup_mmcargs; ext4load mmc 0:2 ${loadaddr} /boot/uImage; ext4load m
mc 0:2 0x83000000 /boot/${fdt_file}; bootm ${loadaddr} - 0x83000000;
bootdelay=0
enable_pf3000_lpm=no
ethact=FEC
fdt_file=a640.dtb
loadaddr=0x82000000
setup_bootcmd_usb=setenv bootcmd run setup_usbargs\\; usb start\\; ext4load usb
0:2 \\${loadaddr} /boot/uImage\\; ext4load usb 0:2 0x83000000 /boot/\\${fdt_file
}\\; usb stop\\; bootm \\${loadaddr} - 0x83000000\\;
setup_mmcargs=setenv bootargs root=/dev/mmcblk0p2 rootwait ${optargs};
setup_usbargs=setenv bootargs root=/dev/sda2 rootwait rw ${optargs};
stderr=serial
stdin=serial
stdout=serial
stop_nr3225sa_alarm=no;
tftpboot=tftpboot uImage; tftpboot 0x83000000 ${fdt_file}; bootm ${loadaddr} - 0
x83000000;
usbboot=run setup_bootcmd_usb; boot;
Environment size: 826/524284 bytes
=>
|
fdt_file変数のデフォルト値は、Armadillo-640では "a640.dtb"、Armadillo-610では "a610.dtb" となります。
|
または env print
コマンドで変数を指定すると、その変数の値だけを表示することも可能です。
=> env print loadaddr
loadaddr=0x82000000
=>
新しく変数を追加したり、すでに設定されている値を変更するには env set
を使います。
=> env set hello world
=> env print hello
hello=world
=> env set hello armadillo
=> env print hello
hello=armadillo
=>
不要な変数を削除するには env delete
を使います。
=> env delete hello
=> env print hello
## Error: "hello" not defined
=>
環境変数を保存するには env save
コマンドを使います。
=> env set hello armadillo
=> env save
Saving Environment to MMC... Writing to MMC(0)... OK
=>
....電源入れなおし....
U-Boot 2018.03-at8 (Feb 14 2020 - 10:21:57 +0900)
CPU: Freescale i.MX6ULL rev1.1 at 396 MHz
Reset cause: POR
I2C: ready
DRAM: 512 MiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
Loading Environment from MMC... OK
In: serial
Out: serial
Err: serial
PMIC: PFUZE3000 DEV_ID=0x30 REV_ID=0x11
Net: FEC
=> env print hello
hello=armadillo
=>
表示された文字からも分るように、Armadillo-600シリーズでは環境変数を MMC の 0番、つまりオンボード eMMC に保存します。U-Boot の環境変数が保存される場所は、オンボード eMMC の先頭から 512 KByte オフセットです。eMMC の 1 MByte オフセットから第1パーティションが始まっているので、環境変数を保存できるのは 512 KByte になります。 eMMC のアドレスマップについては 表3.4「eMMCメモリマップ」 を参照してください。
環境変数をデフォルト値に戻したい場合は env default
コマンドを使います。
=> env print bootdelay
bootdelay=0
=> env set bootdelay 1
=> env print bootdelay
bootdelay=1
=> env default bootdelay
=> env print bootdelay
bootdelay=0
=>
もし、すべての環境変数をデフォルト値に戻したい場合は、 オプション -a
を付けてください。
| |
---|
特定の変数は、値を変更するタイミングで U-Boot の関数が実行されます。環境変数 baudrate もそのうちの1つです。つまり値が変更されるだけでなく、実際にボーレートが変更されます。 他にも値の変更できなくなっていたり、変更回数が決まっているものもあります。環境変数 ethaddr もその1つです。それらの変数は、変更する必要はあまり無いと思いますが、もし変更する場合には U-Boot のマニュアルを参照してください。 |
9.4. U-Boot が Linux を起動する仕組み
U-Boot は、 boot
コマンドによって、OS を起動します。 boot
コマンドは、 環境変数 bootcmd
に登録されているコマンドを実行するコマンドです。つまり run bootcmd
と同じ意味です。
=> env print loadaddr
loadaddr=0x82000000
=> env print bootcmd
bootcmd=run setup_mmcargs; ext4load mmc 0:2 ${loadaddr} /boot/uImage; ext4load m
mc 0:2 0x83000000 /boot/${fdt_file}; bootm ${loadaddr} - 0x83000000;
=> run bootcmd
6601520 bytes read in 207 ms (30.4 MiB/s)
27838 bytes read in 56 ms (485.4 KiB/s)
## Booting kernel from Legacy Image at 82000000 ...
Image Name: Linux-4.14-at19
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 6601456 Bytes = 6.3 MiB
Load Address: 82000000
Entry Point: 82000000
Verifying Checksum ... OK
## Flattened Device Tree blob at 83000000
Booting using the fdt blob at 0x83000000
Loading Kernel Image ... OK
Loading Device Tree to 9eef9000, end 9ef02cbd ... OK
Starting kernel ...
環境変数 bootcmd
には複数のコマンドが ;
で区切られて並んでいます。 U-Boot の run
コマンドは、並んでいるコマンドを順次実行していきます。
bootcmd=ext4load mmc 0:2 ${loadaddr} /boot/uImage; ext4load mmc 0:2 0x83000000 /boot/${fdt_file}; bootm ${loadaddr} - 0x83000000;
最初のコマンドは ext4load
です。このコマンドは、0
番目の MMC
デバイスにある、 2
番目パーティションにアクセスし /boot/uImage
を、環境変数 loadaddr
で指定されているメモリアドレスにロードします。コマンドで環境変数を参照するには、変数を ${…}
でくくります。出荷状態では、オンボード eMMC の第2パーティションが EXT4 でフォーマットされており、 /boot/
ディレクトリに uImage
というファイル名で Linux カーネルが配置されています。つまり最初のコマンドは、Linux カーネルをメモリにロードしているわけです。
=> help ext4load
ext4load - load binary file from a Ext4 filesystem
Usage:
ext4load <interface> [<dev[:part]> [addr [filename [bytes [pos]]]]]
- load binary file 'filename' from 'dev' on 'interface'
to address 'addr' from ext4 filesystem
=>
同じコマンドを U-Boot のプロンプトで手で実行しても、同じ動作結果になります。コマンドを1つだけ入力するときは ;
を付けても付けなくても問題ありません。
=> ext4load mmc 0:2 ${loadaddr} /boot/uImage
6601520 bytes read in 206 ms (30.6 MiB/s)
=>
| |
---|
Armadillo-600シリーズ では 512 MByte (0x20000000 ) の DRAM が 0x80000000 から 0xA0000000 までマップされています。この情報は bdinfo コマンドで確認することができます。 |
次のコマンドも同じく ext4load
で、環境変数 fdt_file
で指定されているファイルをメモリアドレス 0x83000000
にロードしている事が分ります。環境変数 fdt_file
は、他の環境変数とは異なり、デフォルト値がArmadilloの起動時に決まります。Armadillo-640では fdt_file=a640.dtb
、Armadillo-610では fdt_file=a610.dtb
となります。このファイルは「Device Tree Blob (dtb)」というもので、ボードのデバイス情報が記録されています。最近の Linuxカーネルでは必須のファイルです。このファイルのロードアドレスは、 uImage
と異なり変数になっておらず値 (0x83000000
) がそのまま記載されています。ファイルがある場所は、 uImage
と同じくオンボード eMMC の第2パーティションで /boot/
です。
=> ext4load mmc 0:2 0x83000000 /boot/${fdt_file}
27838 bytes read in 55 ms (494.1 KiB/s)
=>
これで、Linuxを起動するために必要なファイル 2つ (uImage
と a640.dtb
または a610.dtb
) をメモリに配置することができました。次のコマンド bootm
で実際に Linux をブートします。 bootm
コマンドは、引数に 3つのアドレスを取ります。
bootm ${loadaddr} - 0x83000000
1つ目が、Linuxカーネルを置いたアドレス (${loadaddr}
== 0x82000000
)、2つ目が initrd のアドレスですが Armadillo-600シリーズ では使用してないので -
を書きます。3つ目が Device Tree Blob を置いたアドレス (0x83000000
) です。 U-Boot は Linux 以外も起動することができるので、 bootm
のヘルプでは Linuxカーネルを "Application image" と記載しています。
=> help bootm
bootm - boot application image from memory
Usage:
bootm [addr [arg ...]]
- boot application image stored in memory
passing arguments 'arg ...'; when booting a Linux kernel,
'arg' can be the address of an initrd image
When booting a Linux kernel which requires a flat device-tree
a third argument is required which is the address of the
device-tree blob. To boot that kernel without an initrd image,
use a '-' for the second argument. If you do not pass a third
a bd_info struct will be passed instead
:
:
=>
実際に bootm
コマンドを使って Linux を起動してみます。ここではあえて loadaddr
ではなく 0x82000000
を入力してみます。
=> bootm 0x82000000 - 0x83000000
## Booting kernel from Legacy Image at 82000000 ...
Image Name: Linux-4.14-at19
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 6601456 Bytes = 6.3 MiB
Load Address: 82000000
Entry Point: 82000000
Verifying Checksum ... OK
## Flattened Device Tree blob at 83000000
Booting using the fdt blob at 0x83000000
Loading Kernel Image ... OK
Loading Device Tree to 9eef9000, end 9ef02cbd ... OK
Starting kernel ...
このように、手で入力しても手順さえ間違わなければ、Linux を起動することができます。もちろん uImage
の場所やファイル名を変更しても、 U-Boot で正しく指定すれば同様に動作します。
9.5. U-Boot から見た eMMC / SD
起動コマンドから分るように Armadillo-600シリーズ では、オンボード eMMC が 0 番目の MMCデバイスです。これは mmc list
コマンドでも確認できます。
=> mmc list
FSL_SDHC: 0 (eMMC)
FSL_SDHC: 1
MMCデバイス情報は mmc info
コマンドで表示できます。 mmc info
コマンドは、引数でどのデバイスかを指定するのではなく、事前に mmc dev
コマンドで使うデバイスを指定しておく必要があります。
=> mmc dev
switch to partitions #0, OK
mmc0(part 0) is current device
mmc dev
コマンドでデバイス番号を指定しないと、現在指定されているデバイスを表示します。
=> mmc info
Device: FSL_SDHC
Manufacturer ID: 13
OEM: 14e
Name: S0J35
Bus Speed: 52000000
Mode : MMC High Speed (52MHz)
Rd Block Len: 512
MMC version 5.1
High Capacity: Yes
Capacity: 3.5 GiB
Bus Width: 8-bit
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 3.5 GiB ENH WRREL
User Enhanced Start: 0 Bytes
User Enhanced Size: 3.5 GiB
Boot Capacity: 31.5 MiB ENH
RPMB Capacity: 4 MiB ENH
GP1 Capacity: 8 MiB ENH WRREL
GP2 Capacity: 8 MiB ENH WRREL
GP3 Capacity: 8 MiB ENH WRREL
GP4 Capacity: 8 MiB ENH WRREL
これが、オンボード eMMC の情報です。次に 1番目のデバイスを指定してみます。
microSDカードが装着されていれば、次のように表示されます。
=> mmc dev 1
switch to partitions #0, OK
mmc1 is current device
=> mmc info
Device: FSL_SDHC
Manufacturer ID: 2
OEM: 544d
Name: SA08G
Bus Speed: 50000000
Mode : SD High Speed (50MHz)
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 7.2 GiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes
=>
カードの種類によって表示される値は異なります。もし SDカードに入れている Linux カーネルを起動する場合は、先の ext4load
コマンドでデバイス 1
を指定すれば良いことが分ります。
=> ext4load mmc 1:1 ${loadaddr} /boot/uImage
上記の例は、 microSD の 1番目のパーティションにある /boot/uImage
をロードする例です。
Linuxカーネルは、ブートローダーから「カーネルパラメーター」と呼ばれる起動オプションを受けとる事ができます。U-Boot では 環境変数 bootargs
に入っている文字列を Linux に渡します。
Armadillo-600シリーズ では bootargs
の値は setup_mmcargs
変数の内部で一旦setenvすることで以下のように設定しています
setup_mmcargs=setenv bootargs root=/dev/mmcblk0p2 rootwait ${optargs};
この文字列で、ルートファイルシステムが /dev/mmcblk0p2
であり、mmcblk0
がみつかるまで待つ (rootwait
) ように指示しています。 前述の通り Armadillo-600シリーズ では オンボード eMMC が 0 番目の MMCデバイスです。Armadillo-600シリーズでは初期出荷時に、オンボード eMMCの第2パーティションに Debian をインストールして出荷しているので 「オンボード eMMC、つまり 0番目の MMCデバイスの第2パーティション」を表わす /dev/mmcblk0p2
を指定しています。
もし microSDカードに、Debian を構築し、そのパーティションをルートファイルシステムとして指定したい場合、
=> setenv setup_mmcargs setenv bootargs root=/dev/mmcblk1p1 rootwait ${optargs};
としてください。 前述の通り microSD は 1番目の MMCデバイスなので root=/dev/mmcblk1p1
で microSD の第1パーティションという意味になります。
| |
---|
Linuxカーネル起動オプション Linuxカーネルには様々な起動オプションがあります。詳しくは、Linuxの解説書や、Linuxカーネルのソースコードに含まれているドキュメント (Documentation/kernel-parameters.txt ) を参照してください。 |