Armadilloが動作する仕組み

前章で実際にArmadilloを動かしてみて、Armadilloとはどのようなコンピューターなのか、大体のイメージが掴めたと思います。この章では、Armadilloがどのようなソフトウェアで構成されていて、それらがどのように動いているのか、その仕組みを詳しく説明していきます。

5.1. ソフトウェア構成

Armadilloは、以下のソフトウェアによって動作します。

5.1.1. ブートローダー

ブートローダーは、電源投入後、最初に動作するソフトウェアです。Armadillo-400シリーズではHermit-Atブートローダー(以降、単にHermit-Atと記述します)を使用します。

Hermit-Atは、二つの動作モードを持っています。一つは、オートブートモードです。オートブートモードでは、カーネルイメージをブートデバイス[46]から読み出し、メモリに展開してからカーネルに制御を移します。この動作は、「ブートローダーが行う処理」で詳しく説明します。

もう一つの動作モードは保守モードで、コンソールにプロンプトを表示し、ユーザーが入力したコマンドに応じてフラッシュメモリの書き換えなどを行います。

Hermit-Atは、フラッシュメモリのブートローダーリージョンに書き込まれている必要があります。

5.1.2. Linuxカーネル

Linuxカーネルは、プロセス管理(スケジューリング)、時間管理、メモリ管理、デバイスドライバ、プロトコルスタック、ファイルシステムなどのOSとしてのコア機能を提供します。Armadillo-400シリーズでは、標準のカーネルとしてLinux を使用します。

Linuxカーネルの初期化処理については、「カーネルの初期化処理」で詳しく説明します。

標準ではカーネルイメージはフラッシュメモリのカーネルリージョンに配置されます。カーネルイメージは、Hermit-Atのブートオプションを変更することで、ストレージ(microSD/SD)またはTFTPサーバー上にも配置することができます。

5.1.3. ユーザーランド

ユーザーランドとは、アプリケーションプログラムやライブラリ、設定ファイル、データファイル、デバイスファイルなどLinuxシステムが動作する上で必要なカーネル以外のものをいいます。

[注記]カーネルとユーザーランドとのインターフェース

Linuxカーネルは、ユーザーランドで動作するプログラムとの唯一のAPI(Application Program Interface)として、システムコールを提供します。ユーザーランドのプログラムは、必ずシステムコールを通してカーネルの機能を呼び出します。

Linuxシステムでは、ユーザーランドのファイルとディレクトリ[47]同士の位置関係を階層的な木構造として表現します。ファイルとディレクトリの木構造をファイルシステムといいます。また、木構造の最上位に位置するディレクトリをルートディレクトリといいます。全てのファイルはルートディレクトリから辿ることができます。

ファイルシステムは、通常、ストレージデバイス[48]に書き込まれて使用されます。ストレージデバイスをファイルシステムと関連付け、システムから使用できるようにすることを、「マウントする」といいます。Linuxシステムでは、任意のディレクトリにデバイスをマウントすることができます。特に、ルートディレクトリにマウントされたファイルシステムを、ルートファイルシステムといいます。

[注記]Windowsのファイルシステムとの違い

Windowsも階層的なファイル構造を持っていますが、Linuxシステムとは決定的な違いがあります。それは、Linuxシステムのファイルシステムにはドライブという考え方がないことです。

Windowsでは複数のストレージデバイスがある場合、デバイスごとにドライブという形で区別し、別々の階層構造を持ちます。一方で、Linuxシステムでは、複数のデバイスがある場合でも、ルートディレクトリから連なる一つの階層構造として表現します。つまり、USBメモリを/mnt/usbディレクトリにマウントし、SDカードを/mnt/usb/sdディレクトリにマウントするといったことができます。デバイスがどれだけ増えようとも、必ずルートディレクトリから辿ることができます。

Armadillo-400シリーズでは、ユーザーランドの標準ルートファイルシステムは、Atmark Distと呼ばれるソースコードベースの開発ディストリビューションを使用して作成します。Atmark Distには、アプリケーションプログラムやライブラリなどのソースコードが含まれています。Atmark Distは、それらのうち、ユーザーが指定したものをビルドしてルートファイルシステムを作成し、フラッシュメモリに書き込める形式のイメージファイルを生成します[49]

Atmark Distで作成したルートファイルシステムイメージは、フラッシュメモリのユーザーランドリージョンに配置されます。ルートファイルシステムイメージは、起動時にHermit-Atによって読み出され、メモリ(RAM)に展開されます。Armadilloは、メモリの一部をストレージのようにして使う、RAMディスクという仕組みを用いてメモリ上に展開されたファイルシステムを、ルートファイルシステムとしてマウントします。

ルートファイルシステムイメージは、Hermit-Atのブートオプションを設定することで、TFTPサーバー上にも配置することができます。また、カーネルオプションを設定することで、RAMディスクではなく、microSD/SDやUSBメモリといった通常のストレージにあるファイルシステムをルートファイルシステムとして使うこともできます。

[注記]標準以外のユーザーランド

Atmark Distで作成した標準ユーザーランドの他に、オプションとしてDebian GNU/Linux 7 (コードネーム "wheezy")ベースのユーザーランドも提供しています。

Debian GNU/Linuxベースのシステムでは、ソフトウェアパッケージのインストールが一つのコマンドできたり、セルフコンパイル環境を整えることもできます。開発の初期段階や、サーバーとして使用する場合にはDebian GNU/Linuxをユーザーランドとして選択するのも良いでしょう。

5.2. 起動の仕組み

本章では、標準状態のArmadilloに電源を投入してから、ログイン画面が表示されるまでの起動シーケンスを詳しく説明します。ブートローダー、カーネルイメージ、ユーザーランドのルートファイルシステムイメージは、フラッシュメモリのそれぞれ対応するリージョンに書き込まれているものとします。

大まかな起動の流れは、以下のようになります。

  1. ブートローダーが行う処理

    1. ブートローダが起動し最低限のハードウェア初期化を行う
    2. カーネルイメージとルートファイルシステムイメージをメモリに展開する。
    3. ブートローダーを抜けて、カーネルに実行を移す。
  2. カーネルの初期化処理

    1. カーネルが様々なコアやデバイスドライバの初期化処理をおこなう。
    2. カーネルがユーザーランドのinitというアプリケーションプログラムを実行する。
  3. ユーザーランドの初期化処理

    1. initがシステム初期化処理を実行する。
    2. initがgettyというアプリケーションプログラムを起動する。
    3. gettyがloginというアプリケーションプログラムを起動する。
    4. loginがログイン画面を表示する。

5.2.1. ブートローダーが行う処理

Armadilloシリーズは、汎用CPUボードという性格上、ユーザーが書き換え可能なフラッシュメモリを搭載しています。ユーザーが操作を誤ってフラッシュメモリを消去してしまっても復旧が可能なように、Armadilloはジャンパによって、電源投入後の動作(ブートモード)を変更することができます。

Armadillo-400シリーズでは、JP1の設定によってUARTブートモードと、オンボードフラッシュメモリブートモードを選択することができます。JP1をショート[50]にすると、UARTブートモードとなります。JP1をオープン[51]にしておくと、オンボードフラッシュメモリブートとなります。オンボードフラッシュメモリブートモードでは、フラッシュメモリのブートローダーリージョンに配置されたブートローダー(Hermit-At)が起動されます。

Hermit-Atは起動されると、まず、DRAMの初期化、拡張インターフェースのIOポートを入力にするなどの必要最小限の設定をおこないます。その後の動作は、JP2の設定によって決定されます。JP2をショートにしておくと保守モード、オープンにしておくとオートブートモードとなります。

ジャンパの設定による、ブートモードの違いを表5.1「ジャンパ設定」にまとめます。

表5.1 ジャンパ設定

JP1 JP2 ブートモード

オープン

オープン

オンボードフラッシュメモリブート/オートブートモード

オープン

ショート

オンボードフラッシュメモリブート/保守モード

ショート

オープン/ショート

UART ブート


5.2.1.1. UARTブートモード

JP1をショートした状態で起動すると、UARTブートモードとなります。UARTブートモードは、フラッシュメモリのブートローダーが壊れた場合など、システム復旧のために使用します。詳しくは、「Armadillo-400シリーズ ソフトウェアマニュアル」の「ブートローダーを出荷状態に戻す」を参照してください。

5.2.1.2. 保守モード

JP1をオープン、JP2をショートにした状態で起動すると、Hermit-Atの保守モードとなります。保守モードの場合、Hermit-Atブートローダーはプロンプトを表示し、コマンド入力待ちとなります。保守モードでは、フラッシュメモリの更新、ブートデバイスやカーネルパラメータの設定などを行うことができます。詳しくは、「Armadillo-400シリーズ ソフトウェアマニュアル」の「付録AHermit-Atブートローダー」を参照してください。

参考として、図5.1「Hermit-At保守モード時の表示」に保守モード起動時のシリアルコンソールへの表示を示します。このような表示になった場合は、ジャンパピンの設定を確認してください。

Hermit-At v3.8.0 (armadillo4x0) compiled at 12:09:14, Oct 12 2015
hermit>

図5.1 Hermit-At保守モード時の表示


5.2.1.3. オートブートモード

JP1とJP2を共にオープンにした状態で起動すると、オートブートモードとなります。これが通常運用での設定です。

Hermit-Atは、最低限のハードウェアの初期化を行った後、自分自身をメモリ(RAM)にコピーします[52]

ブートローダーのコピー

図5.2 ブートローダーのコピー


次にブートデバイス[53]からカーネルイメージとユーザーランドのルートファイルシステムイメージを読み出し、メモリ上にコピーします。

カーネルとユーザーランドをコピー

図5.3 カーネルとユーザーランドをコピー


その後、ブートローダーを抜け、カーネルの開始番地へ実行を移します。この一連の処理を、Linuxカーネルをブートすると表現します。

カーネルの起動

図5.4 カーネルの起動


Hermit-AtがLinuxカーネルをブートするときの、コンソールへの出力を図5.5「Hermit-Atオートブートモード時の表示」に示します。

Hermit-At v2.0.1 (armadillo4x0) compiled at 21:10:18, Apr 27 2010  1
Uncompressing  kernel.............................................................................
....................................done.  2
Uncompressing ramdisk.............................................................................
..................................................................................................
..................................................................................................
..................................................................................................
.......................................................done.  3
Booting Linux on physical CPU 0x0 4
Initializing cgroup subsys cpuset
Initializing cgroup subsys cpu
Initializing cgroup subsys cpuacct
Linux version 3.14.36-at4 (atmark@atde5) (gcc version 4.6.3 (Debian 4.6.3-14atmark1) ) #3 PREEMPT Mon Oct 12 11:00:18 JST 2015
:
:
:

図5.5 Hermit-Atオートブートモード時の表示


1

Hermit-Atはシリアルの初期化が完了すると自身のバージョンを表示します。

2

カーネルイメージが圧縮されている場合、展開しながらメモリ上にコピーします。

3

同様に、ユーザーランドイメージを展開しながらメモリ上にコピーします。ユーザーランドイメージのコピーが完了すると、カーネルに実行を移します。

4

この行以降は、カーネルが表示しています。

5.2.2. カーネルの初期化処理

ブートローダーから実行を移されると、ようやくLinuxカーネルが動作を開始します。

Armadilloのカーネル起動ログの例として、Armadillo-420の起動ログを図5.6「Armadillo-420カーネルブートログ」に示します。

Linux version 3.14.36-at (atmark@atde5) (gcc version 4.6.3 (Debian 4.6.3-14atmark1) ) #3 PREEMPT Mon Oct 12 11:00:18 JST 2015
CPU: ARM926EJ-S [41069264] revision 4 (ARMv5TEJ), cr=00053177
CPU: VIVT data cache, VIVT instruction cache
Machine: Armadillo-420
Memory policy: Data cache writeback
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 16256 1
Kernel command line: console=ttymxc1,115200 root=/dev/ram0 2
PID hash table entries: 256 (order: -2, 1024 bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
allocated 131072 bytes of page_cgroup
please try 'cgroup_disable=memory' option if you don't want memory cgroups
Memory: 33792K/65536K available (4498K kernel code, 222K rwdata, 1368K rodata, 164K init, 143K bss, 31744K reserved)
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xfff00000 - 0xfffe0000   ( 896 kB)
    vmalloc : 0xc4800000 - 0xff000000   ( 936 MB)
    lowmem  : 0xc0000000 - 0xc4000000   (  64 MB)
    modules : 0xbf000000 - 0xc0000000   (  16 MB)
      .text : 0xc0008000 - 0xc05c2ebc   (5868 kB)
      .init : 0xc05c3000 - 0xc05ec324   ( 165 kB)
      .data : 0xc05ee000 - 0xc0625880   ( 223 kB)
       .bss : 0xc062588c - 0xc0649528   ( 144 kB)
Preemptible hierarchical RCU implementation.
        Dump stacks of tasks blocking RCU-preempt GP.
NR_IRQS:16 nr_irqs:16 16
MXC IRQ initialized 3
:
各デバイスやカーネル内部の初期化処理
:
RAMDISK: ext2 filesystem found at block 0 4
RAMDISK: Loading 24576KiB [1 disk] into ram disk... done.
VFS: Mounted root (ext2 filesystem) on device 1:0. 5
devtmpfs: mounted 6

図5.6 Armadillo-420カーネルブートログ


1

ブートローダーから実行が移ると、カーネルはまず自身のバージョン、CPUアーキテクチャ、マシン名、メモリの状態などを表示します。

2

カーネルパラメータは、「console=ttymxc1,115200」が使用されています。

3

ここから、ボード固有のデバイスの初期化が始まります。

4

RAMディスクのblock0にext2ファイルシステムを検出しました。

5

検出したファイルシステムをルートファイルシステムとしてマウントします。

6

ルートファイルシステムの所定のパスにinitプログラムが見つかると、カーネルはinitを実行します。この行から、initによって表示されています。

5.2.3. ユーザーランドの初期化処理

カーネルの初期化が完了すると、最初のプロセスとしてinitというアプリケーションプログラムが実行されます。initは、まず、コンソールの初期化をおこない、次に/etc/inittabというファイルに書かれた設定に従って、コマンドを実行します。

この時、処理状況を表示するシステムコンソールには、カーネルパラメータのconsoleオプションで指定されたデバイスを使用します。もし、console オプションが指定されていない場合は、/dev/consoleを使おうとします。図5.6「Armadillo-420カーネルブートログ」で示したように、標準でconsoleオプションにttymxc1が指定されます。ttymxc1は、Armadillo-400シリーズのシリアルインターフェース1に対応する、シリアルデバイスです[54]。そのため、initは、シリアルインターフェース1をシステムコンソールとして設定します。

次に、initは、/etc/inittabファイルの中身を読み込み、その内容に従って処理を行います。inittabには、一行ごとにinitが実行すべきコマンドが記述してあります。inittabの書式は、以下のようになっています。

id:runlevel:action:process

図5.7 inittabの書式


idには起動されるプロセスが使用するコンソールを指定します。省略した場合は、システムコンソールが使用されます。

runlevelは、Atmark Distで生成されるユーザーランドに含まれるinitでは、無効です。

actionはどのような状態のときにprocessに指定したコマンドを実行すべきかをあらわします。actionに指定可能な値を表5.2「initのactionに指定可能な値」に示します。

表5.2 initのactionに指定可能な値

いつ process を実行するか

sysinit

システム初期化時。

respawn

sysinit 終了後。このアクションで起動されたプロセスが終了すると、再度 process を実行する。

shutdown

システムをシャットダウンする前。

ctrlaltdel

Ctrl-Alt-Delete キーの組み合わせが入力されたとき。


例として、Armadillo-420のinittabは以下のようになっています。

::sysinit:/etc/init.d/rc

::respawn:/sbin/getty -L 115200 ttymxc1 vt102

::shutdown:/etc/init.d/reboot
::ctrlaltdel:/sbin/reboot

図5.8 Armadillo-420のinittab


図5.8「Armadillo-420のinittab」からわかるように、システム初期化時には/etc/init.d/rcが実行されます。

Armadilloでは、/etc/init.d/rcはシェルスクリプトになっています。シェルスクリプトは、シェルで実行できるコマンドを記述したスクリプトです。詳細は、第2部の「シェルスクリプトプログラミング」で説明します。

Armadillo-420の/etc/init.d/rcは以下の処理を実行します。

  1. procfsをマウントします。[55]
  2. 一度ルートファイルシステムをリードオンリーでリマウントし、fsckにより、ルートファイルシステムをチェックします。問題があればリブートします。
  3. ルートファイルシステムをリード/ライト可能でリマウントします。
  4. sysfs、tmpfsをマウントします。[55]
  5. ログ関連のファイルをクリアします。
  6. /etc/issue/etc/issuet.netファイルの設定をします。[56]
  7. /etc/rc.d/ディレクトリにある、Sから始まるファイル(初期化スクリプト)を順番に実行します。
  8. 赤色LEDが点滅していたら、点滅を停止し赤色LEDを消灯させます。

/etc/rc.dディレクトリ内には、Sからファイル名が始まる、初期化スクリプトがあります。これらの初期化スクリプトで、コンフィグ領域のリストアや、ファイヤーウォールの設定、ネットワークインターフェースの有効化、各サーバーの起動などをおこないます。初期化スクリプトはファイル名の順番に実行されます。そのため、Sに続く2桁の数字が小さいファイル名のスクリプトから順に実行されます。

また、処理の一番最後に/etc/config/rc.localというファイル名で実行可能なファイルがあるか確認し、ファイルがあればそれを実行します。/etc/config/ディレクトリは、flatfsdでコンフィグ領域に保存可能なディレクトリですので、開発時などに自動起動プログラムを試したいという場合に使用することができます。

sysinitアクションに指定された以上の処理が完了すると、initは次に、respawnアクションに指定されたコマンドを実行します。Armadillo-400シリーズの場合は、gettyというプログラムを起動します。

gettyは、/etc/issueの内容を読み取り、コンソールに表示します。そして、ログインユーザー名の入力待ちになります。ログインユーザー名が入力されると、それを引数として、loginというプログラムを起動します。

loginは、ログイン名を指定されて起動されると、パスワードの入力待ちになります。パスワードが入力されると、/etc/passwd及び/etc/shadowの内容とログインユーザー名、パスワードを照合して、認証をおこないます。ユーザー名とパスワードが一致すると、/etc/passwdで指定されたユーザー用のシェルを起動します。

シェルは、起動されるとプロンプトを表示して、コマンドの入力待ちになります。

5.3. ルートファイルシステムのディレクトリ構成

Linuxシステムでのディレクトリ構成には、デファクトスタンダード(事実上の標準)となっている構成があります。それぞれのディレクトリに何を格納するかということも、慣習的に決まっています。それぞれのディレクトリには特定の役割がありますので、それを理解することで、ファイルを探す場合にどのディレクトリを探せばよいか、また、ファイルを追加する場合にどのディレクトリに置けば適切かということが分かります。

[注記]ディレクトリ構成の標準規格

ディレクトリ構成の標準規格としてFHS(Filesystem Hierarchy Standard : ファイルシステム階層標準)があります。

すべてのLinuxシステムがこの標準に従っているわけではありませんが、特別な理由がない限り、FHSに従ったディレクトリ構成とするのが望ましいでしょう。

Armadillo-400シリーズのルートファイルシステムの主なディレクトリの構成は、以下のようになっています。

表5.3 ディレクトリ構成

ディレクトリ ディレクトリの内容

/

ルートディレクトリ、ルートファイルシステムのマウントポイント

/bin

基本的なユーザーコマンドの実行ファイル

/dev

デバイスファイル

/etc

設定ファイル

/etc/config

フラッシュメモリのコンフィグ領域に保存できるファイル

/etc/default

コンフィグ領域の初期化のためのファイル

/etc/init.d

初期化スクリプト

/etc/rc.d

初期化スクリプトへのシンボリックリンク

/home

ホームディレクトリ

/home/ftp

ftpユーザーのホームディレクトリ

/home/guest

guestユーザーのホームディレクトリ

/home/www-data

Webサーバーのドキュメントルート

/lib

基本的なライブラリ

/mnt

一時的にマウントするファイルシステムのマウントポイント

/proc

procfsのマウントポイント(プロセス情報)

/root

rootユーザーのホームディレクトリ

/sbin

基本的なシステム管理用コマンドの実行ファイル

/sys

sysfsのマウントポイント(システム情報)

/tmp

一時的なファイル

/usr

ユーザー共有情報ファイル

/usr/bin

必須でないユーザーコマンドの実行ファイル

/usr/sbin

必須でないシステム管理者用コマンドの実行ファイル

/usr/lib

必須でないライブラリ

/var

頻繁に更新されるファイル

/var/log

ログが保存されるディレクトリ


5.3.1. 実行ファイル

アプリケーションの実行ファイルは、/bin/usr/bin/sbin/usr/sbinディレクトリに置かれます。

これらのディレクトリ内にあるファイルが、シェルでコマンドを入力したときに検索されます。そしてコマンドと同じファイル名のファイルがこれらのディレクトリに合った場合、そのファイルが実行されます。

5.3.2. ホームディレクトリ

ユーザーごとのホームディレクトリは/homeディレクトリに用意されています。

Armadillo-400シリーズでは、ftpguestwww-dataディレクトリがあります。但し、ftpとwww-dataユーザーでは、ログインすることはできません。また、rootユーザーでログインした場合のホームディレクトリは、/rootディレクトリになります。

/home/ftpはftpユーザーのホームディレクトリです。ftpユーザーはArmadilloにFTPでログインし、anonymousもしくはftpユーザーとしてログインした場合に使用されます。/home/ftp/pubディレクトリは、ftpで書き込み可能なディレクトリです。ramfs[57]でマウントされているので、RAMが許す限りの大きなファイルを書き込むことができます。

/home/www-dataは、Webサーバーのドキュメントルートになっています。ドキュメントルート以下にディレクトリ、ファイルを配置することで、Webサーバーでファイルを公開することができます。

5.3.3. ライブラリ

ライブラリファイルは/libまたは/usr/libディレクトリに置かれます。共有ライブラリを使用するプログラムを実行する場合は、これらのディレクトリ内に共有ライブラリを置いておく必要があります[58]

5.3.4. デバイスファイル

/devディレクトリには、デバイスファイルが置かれます。

デバイスファイルは、デバイスを仮想的にファイルとして表したものです。デバイスファイルに対して操作を実行することにより、デバイスを制御することができます。

例として、/dev/ttymxc1はシリアルインターフェース1のシリアルデバイスをファイルとして表したものです。/dev/ttymxc1に対してデータの読み書きをすることで、シリアルデバイスからデータを受信/送信することができます。

5.3.5. プロセス、システムの状態

/proc/sysディレクトリ内のファイルを操作することで、プロセス、システムの状態を参照、変更することができます。

/procにはprocfs/sysにはsysfsがマウントされています。procfs、sysfsはカーネル内部のデータ構造にアクセスすることができる機能を提供する仮想的なファイルシステムです。

5.3.6. ログ

カーネルメッセージやアプリケーションの動作ログなどは/var/logディレクトリに保存します。

5.3.7. 設定ファイル

設定ファイルは、/etcに置かれます。

/etc/configディレクトリ以下のファイルは、flatfsdコマンドを使って、フラッシュメモリのコンフィグ領域に保存することができます。コンフィグ領域の内容は、初期化スクリプトで/etc/configディレクトリにリストアします。

このディレクトリにrc.localという名前で実行可能なファイルを置くと、起動時に初期化スクリプトによって実行されます。



[46] 標準設定の場合は、フラッシュメモリです。Armadillo-400シリーズではmicroSD/SDやTFTPサーバーも指定可能です。

[47] Windowsでのフォルダと同様の概念です。

[48] HDD(ハードディスクドライブ)やUSBメモリなど

[49] 同時にカーネルイメージも生成します。

[50] ジャンパソケットを挿した状態

[51] ジャンパソケットを挿していない状態

[52] この処理は、保守モードでも同様です。

[53] 標準設定の場合は、フラッシュメモリです。

[54] 「Armadillo-400シリーズ ソフトウェアマニュアル」の「UART」参照

[55] 仮想ファイルシステムと呼ばれるもので、カーネル内部の状態がファイル内容に動的に反映されます。

[56] これらは、コンソール(issue)またはネットワーク経由(issue.net)のログイン時に表示される文字を制御します。

[57] RAMの一部を直接使用するファイルシステム

[58] LD_LIBRARY_PATH環境変数を指定することによって、これらのディレクトリ以外に共有ファイルを置くこともできます。