特集 : 最新組み込みLinux実践講座Part7

対象製品: Armadillo-500Armadillo-300Armadillo-9Armadillo-240Armadillo-230Armadillo-220Armadillo-210Armadillo(HT1070)Armadillo-J
先頭 Part 6

(株)アットマークテクノ
中井真大
NAKAI Masahiro

この文書は技術評論社「Software Design」2007年11月号に掲載されたものです。

本章では,ここまでに作成してきたアプリケーションやデータを1 つのイメージファイルにまとめ,スタンドアロンシステムとして運用できるようにシステムを完成させます.

ここまでのおさらい

前章までは,アンケートツールというシステムを構築するための準備を行ってきました.具体的には,それぞれの機能を実現するためのソフトウェアの構築と,それらを使用してシステム全体をまとめるアプリケーション(CST)を作成しました.

CSTをAtmark Distに組み込み,ビルドすればすべての機能を網羅したイメージを作成できます.そのイメージをArmadillo-500のフラッシュメモリに書き込み,コンソールでいくつかのコマンドを実行すればCST が起動しますが,毎回起動させるためにコンソールで操作しなければならないのでは,組み込みシステムとは呼べないでしょう.

そこで本章では,システムを起動させたときに自動でCSTが起動するように設定して,1つのプロダクトとなるように仕上げていきます.

プロダクト化

Atmark Distでは,atmark-dist/vendorsの下にベンダごとのプロダクトが登録されています.ベンダとして「AtmarkTechno」が用意されているので,今回はこの中にアンケートツール用のディレクトリを作成することとします.

プロダクトのベースとなるのは,今まで使用していた「Armadillo-500」です.このディレクトリをまるごと「CST.Armadillo-500」という名前でコピーします.このようにするだけで,コンフィギュレーション時に「CST.Armadillo-500」を選択できるようになります(図1).

●図1 プロダクトをコピー

$ cd ~/work.sd
$ cd atmark-dist/vendors/AtmarkTechno
$ cp -a Armadillo-500 CST.Armadillo-500

しかし,これだけでは「Armadillo-500」と同じイメージを作成することしかできないので,CST.Armadillo-500ディレクトリ以下のファイルを修正していきます.

CST をAtmark Dist へ組み込む

DirectFBやsane-backendsは,すでにAtmark Distへ組み込まれている状態ですので,次にCST を組み込んでみます.

CST が他のプラットフォームでも同じように動作するのであれば,atmark-dist/userに組み込むのですが,今回作成したソースコードでは他のプラットフォームで動作させるにはまだまだ不十分です.したがって,CSTのソースコードはCST.Armadillo-500ディレクトリ以下に配置することにします.

本特集6章で説明したソースコードをアーカイブにしたものを,http://download.atmark-techno.com/misc/softwaredesign_2007-11/からダウンロードできます.これをCST.Armadillo-500ディレクトリへ展開します(図2).

●図2 CST をAtmark Dist に組み込む

$ cd ~/work.sd
$ wget http://download.atmark-techno.com/misc/softwaredesign_2007-11/chapter6/cst.tar.gz
$ cd atmark-dist/vendors/AtmarkTechno/CST.Armadillo-500
$ tar zxf ../../../../cst.tar.gz

次に,コンフィギュレーションでCST を選択可能にします.ここで修正するファイルは,CST.Armadillo-500 ディレクトリ下にあるConfig.in とMakefile になります.記述方法は,DirectFB やsane-backendsと同じです(リスト1,2).

リスト1 .../CST.Armadillo-500/Config.in

15: comment 'Applications'
16: 
17: bool 'cst' CONFIG_VENDOR_CST_CST                 追加
18: bool 'swmgr' CONFIG_VENDOR_SWMGR_SWMGR
19:
●リスト2 .../CST.Armadillo-500/Makefile

47: SUBDIR_y =
48: SUBDIR_$(CONFIG_VENDOR_CST_CST) += cst/          追加
49: SUBDIR_$(CONFIG_VENDOR_SWMGR_SWMGR) += swmgr/
50:
51: all:

自動起動

カーネルは,初期化が終わるとinitを実行します.initはすべてのプロセスの親であり,/etc/inittabに記述されている内容を忠実に実行していきます.これにより,プロセスの起動やログインプロンプトの表示などを行うのです.

inittabのsysinitエントリは,システム起動時のいかなるエントリよりも先に実行されます.CST.Armadillo-500ディレクトリのetc/inittab(リスト3)を参照してみると,sysinitエントリに/etc/init.d/rcが設定されています.Atmark Distの中で/etc/init.d/rcに該当するのは,CST.Armadillo-500/etc/init.d/rcになります.

●リスト3 .../CST.Armadillo-500/etc/inittab

1: ::sysinit:/etc/init.d/rc
2:
3: ::respawn:/sbin/getty -L 115200 ttymxc0 vt102
4: ::respawn:/sbin/getty -L 115200 ttymxc1 vt102
5: ::respawn:/sbin/getty 38400 tty1 linux
6:
7: ::shutdown:/etc/init.d/reboot
8: ::ctrlaltdel:/sbin/reboot

この中を参照すると,“Running local start scripts.”と表示された後に/etc/rc.d/S*の各スクリプトが実行されることがわかります.このスクリプトには,各プロセスの起動や設定などが記述されています.CST.Armadillo-500のMakefileで/etc/rc.d/S*が作成されているので,同じようにCST が起動されるように登録していきます(リスト4,5).

●リスト4 .../CST.Armadillo-500/etc/init.d/cst

 1: #!/bin/sh
 2:
 3: . /etc/init.d/functions
 4:
 5: PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin 
 6: LOG=/var/log/cst-dfb.log
 7:
 8: echo -n "Starting cst: "
 9: rm -f $LOG
10: cst --dfb:log-file=$LOG &
11: check_status
●リスト5 .../CST.Armadillo-500/Makefile

117:        $(ROMFSINST) -s /etc/init.d/sshd /etc/rc.d/S70sshd
118:
119:        [ "$(CONFIG_VENDOR_CST_CST)" != "y" ] || \                 追加
120:        $(ROMFSINST) -s /etc/init.d/cst /etc/rc.d/S80cst           追加
121:
122:        $(ROMFSINST) -s /etc/init.d/misc /etc/rc.d/S99misc

デバイスノード

DirectFBがインプットデバイスを使用するためには,/dev/input/event*のデバイスノードが必要となります.今回プロダクトのベースとなったArmadillo-500はudevを使用していますが,udev.conf やrulesファイルがないため,自動的に/dev/inputへデバイスノードを作成してくれません.

そこで,udevdの起動スクリプトの中でインプットデバイスのデバイスノードが作成されるようにします(リスト6).

●リスト6 .../CST.Armadillo-500/etc/init.d/udevd

21: }
22:
23: create_input_node() {                                                追加
24:         mkdir -p /dev/input                                          追加
25:         for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15               追加
26:         do                                                           追加
27:                 ln -s /dev/event$i /dev/input/                       追加
28:         done                                                         追加
29: }                                                                    追加
30:
31: create_early_node() {
(略)
42:         ln -s /dev/rtc0 /dev/rtc
43:
44:         create_input_node                                            追加
45:         create_flash_node

PATH の追加

etc/profileを見てみると,PATHには「/bin:/usr/bin:/sbin:/usr/sbin」が設定されています.DirectFB-examples の各実行ファイルは/usr/local/bin にインストールされるので,念のためPATHに「/usr/local/bin:/usr/local/sbin」を追加します(リスト7).

●リスト7 .../CST.Armadillo-500/etc/profile

 7: TZ=JST-9
 8:
 9: PATH="/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin"  修正
10: PS1="[\u@\h (`tty | cut -b6-`) \w]\\$ "

ビルド

RAMDISKの最大サイズを変更

これでCST を動作させるためのソースコードの 作成と修正は終了しました.システム全体のコン フィギュレーションを行い,ビルドしてみましょ う(図3).

●図3 コンフィギュレーションで変更する個所

$ make menuconfig
*** Main Menu ***
Vendor/Product Selection  --->
        (AtmarkTechno) Vendor
        (CST.Armadillo-500) AtmarkTechno Products
Kernel/Library/Defaults Selection  --->
        (default) Cross-dev
        (None) Libc Version
        [*] Default all settings (lose changes)
        [*] Customize Kernel Settings
        [*] Customize Vendor/User Settings
        
*** Linux Kernel Configuration ***
Device Drivers  --->
        Input device support  --->
                  <*>   Touchscreen interface
                  (640)   Horizontal screen resolution
                  (480)   Vertical screen resolution
        USB support  --->
                  <*> USB Touchscreen Driver
                  [*]   eGalax device support
                  [*]     Adjustment of QT-701AV-S
                
*** Userland Configuration ***
Vendor specific  --->
        [*] cst
Library Configuration  --->
        [*] Build directfb
Miscellaneous Applications  --->
        [*] directfb-examples
        [*] imagemagick
        [*] sane-backends
        [*]   scanimage
        [*]   backend - plustek
        
$ make
(略)
$ ls images
linux.bin  linux.bin.gz  romfs.img  romfs.img.gz

できたイメージファイルをArmadillo-500のフラッシュメモリに書き込み再起動してみると,エラーが発生してしまいます(図4).エラー内容を見るとRAMDISKの容量が足りないようです.カーネルで設定されているRAMDISKの最大サイズが16,384K バイトなのに対し,ユーザーランドイメージのサイズが26,971Mバイトとなっているからです.

●図4 エラー内容

RAMDISK: ext2 filesystem found at block 0
RAMDISK: image too big! (26971KiB/16384KiB)
No filesystem could mount root, tried: ext3 ext2 msdos vfat
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(1,0)

このエラーの対策としては,カーネルのコンフィギュレーションでRAMDISK の最大サイズを大きく設定するか,カーネル起動オプションでRAMDISKの最大サイズを変更する方法が考えられます.ここでは,後者の方法で対策してみます.

Armadillo-500 のJP1 をショートさせて電源を入れ,ブートローダのコマンドプロンプトを表示させます.boot コマンドの引数に起動オプションを設定します(図5).

●図5 起動オプションを設定してカーネルを起動

Hermit-At v1.1.9 (Armadillo-500) compiled at 14:13:54, Jul 27 2007
hermit> boot console=ttymxc0     ramdisk_size=30000
             ↑コンソールの指定   ↑ RAMDISK サイズの指定

これで無事にシステムを起動させることができました.

デフォルト設定の登録

現在のコンフィギュレーション内容をCST.Armadillo-500のデフォルト設定になるように登録していきます.

デフォルトの設定は,カーネルの場合はatmarkdist/linux-2.6.x/arch/arm/configs/の下に,ユーザランドの場合atmark-dist/vendors/AtmarkTechno/CST.Armadillo-500/の下に登録します(図6,7).カーネルのデフォルト設定を変更するには,CST.Armadillo-500/tools/config-linux.confの設定を変更する必要があります(リスト8).

●図6 カーネルのデフォルト設定の追加

$ cd atmark-dist/linux-2.6.x
$ cp .config arch/arm/configs/cst-armadillo500_defconfig
●図7 ユーザランドのデフォルト設定の追加

$ cd atmark-dist
$ cp config/.config vendors/AtmarkTechno/CST.Armadillo-500/config.vendor
●リスト8 .../CST.Armadillo-500/tools/config-linux.conf

1: DEFCONFIG_2_4=
2: DEFCONFIG_2_6=arch/arm/configs/cst-armadillo500_defconfig        修正

コンパクトフラッシュシステム構築

フラッシュメモリから起動する場合,RAMDISKの最大容量を変更しなくてはなりませんでした.ただ,RAMDISKの容量が増えると,カーネルおよびユーザランドの他のアプリケーションが使用できるメモリが減ってしまいます.

そこで,RAMDISKを使用しないようにコンパクトフラッシュシステムへ移行させてみます.コンパクトフラッシュシステムに移行すればフラッシュメモリが開放されるので,フラッシュメモリにはArmadillo-500のデフォルトイメージを書き込み,実際のシステムに問題が発生したりシステムを変更したりする場合などは,フラッシュメモリから起動してメンテナンスを行えるようにしましょう.

まずは,フラッシュメモリにArmadillo-500のデフォルトイメージを書き込み,コンパクトフラッシュの初期化とルートファイルシステムの構築を行います.各作業は,Armadillo-500上で行ってください.

ディスクの初期化

コンパクトフラッシュディスクにルートファイルシステムを構築するには,一度コンパクトフラッシュのデータを初期化する必要があります.初期化は,fdisk コマンドを使用してパーティションの設定を行います(図8).

●図8 コンパクトフラッシュの初期化

Armadillo-500 # fdisk /dev/hda

Command (m for help): p

Disk /dev/hda: 512 MB, 512483328 bytes
16 heads, 63 sectors/track, 993 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes

   Device Boot    Start       End    Blocks    Id System

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 1
First cylinder (1-993, default 1):
Using default value 1
Last cylinder or +size or +sizeM or +sizeK (1-993, default 993): +32M

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)
p
Partition number (1-4): 2
First cylinder (64-993, default 64):
Using default value 64
Last cylinder or +size or +sizeM or +sizeK (64-993, default 993):
Using default value 993

Command (m for help): p

Disk /dev/hda: 512 MB, 512483328 bytes
16 heads, 63 sectors/track, 993 cylinders
Units = cylinders of 1008 * 512 = 516096 bytes

   Device Boot    Start       End    Blocks   Id  System
/dev/hda1               1          63       31720+  83  Linux
/dev/hda2              64         993      468720   83  Linux

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.
 hda: hda1 hda2
 hda: hda1 hda2
Syncing disks.

初期化後,それぞれのパーティションにファイルシステム作成していきます.本章では,表1に示すように初期化を行います.

●表1 コンパクトフラッシュディスク(512M バイト)の設定例
パーティションサイズファイルシステム用途
1 32M バイトext2 カーネルイメージ用
2 480M バイトext3 ルートファイルシステム用

ファイルシステムの作成

ext2,ext3 ファイルシステムを作成するには,mke2fs コマンドを使用します.パーティション1は,ブートローダがカーネルイメージを見つけることができるように「-O none」オプションを指定します.パーティション2は,ext3ジャーナリング機能を持つように「-j」オプションを指定します(図9).

●図9 ファイルシステムの作成

Armadillo-500 # mke2fs -O none /dev/hda1
mke2fs 1.25 (20-Sep-2001)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
7936 inodes, 31720 blocks
1586 blocks (5%) reserved for the super user
First data block=1
4 block groups
8192 blocks per group, 8192 fragments per group
1984 inodes per group
Superblock backups stored on blocks:
        8193, 16385, 24577

Writing inode tables: done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 20 mounts or
180.00 days, whichever comes first.  Use tune2fs -c or -i to override.
Armadillo-500 # mke2fs -j /dev/hda2
mke2fs 1.25 (20-Sep-2001)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
117392 inodes, 468720 blocks
23436 blocks (5%) reserved for the super user
First data block=1
58 block groups
8192 blocks per group, 8192 fragments per group
2024 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409

Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 32 mounts or
180.00 days, whichever comes first.  Use tune2fs -c or -i to override.

ルートファイルシステムの構築

各パーティションにファイルシステムが作成できたので,パーティション2をマウントしてルートファイルシステムを作成します.ルートファイルシステムのベースには,フラッシュメモリ用のユーザランドイメージを使用します.ユーザランドイメージはFTPなどでArmadillo-500に転送してください.

また,作業はパーティション2上で行います.イメージファイルのサイズが大きく,RAMを大量に消費してしまうからです(図10).

●図10 ルートファイルシステムの構築

Armadillo-500 # mount /dev/hda2 /mnt
kjournald starting. Commit interval 5 seconds
EXT3 FS on hda2, internal journal
EXT3-fs: mounted filesystem with ordered data mode.
Armadillo-500 # mkdir /mnt/work
Armadillo-500 # cd /mnt/work
(/mnt/work にユーザランドイメージを転送)
Armadillo-500 # ls
romfs.img.gz
Armadillo-500 # gzip -dc romfs.img.gz > romfs.img
Armadillo-500 # mkdir romfs
Armadillo-500 # mount -t ext2 -o loop romfs.img romfs
Armadillo-500 # (cd romfs; tar cf - *) | (cd /mnt; tar xf -)
Armadillo-500 # sync
Armadillo-500 # umount romfs
Armadillo-500 # cd
Armadillo-500 # umount /mnt

カーネルイメージの配置

次に,カーネルイメージを配置します.ブートローダは,/boot/Image.gzファイルをLinux起動時にRAMへ展開することができます.Image.gzファイルは,フラッシュメモリ用のカーネルイメージと同じものです(図11).

●図11 カーネルイメージの配置

Armadillo-500 # mount /dev/hda1 /mnt
ext3: No journal on filesystem on hda1
Armadillo-500 # mkdir /mnt/boot
(/mnt/work にカーネルイメージを転送)
Armadillo-500 # cd /mnt/boot
Armadillo-500 # ls
linux.bin.gz
Armadillo-500 # mv linux.bin.gz Image.gz
Armadillo-500 # cd
Armadillo-500 # umount /mnt

起動と設定

一度再起動して,システム設定を行います.コンパクトフラッシュシステムで起動するためには,ブートローダでLinux起動オプションを設定しなければなりません.Armadillo-500のJP1をショートして電源を入れ,図12のように設定します.

●図12 Linux 起動オプションの設定

hermit> setbootdevice hda1
hermit> setenv console=ttymxc0 noinitrd root=/dev/hda2 rootdelay=2
  • setbootdevice

    Armadillo-500のブートローダは,フラッシュメモリのカーネルイメージをRAMに展開するのと同じように,コンパクトフラッシュに構築されたext2ファイルシステム中の/bootディレクトリにあるカーネルイメージ(Image.gz)をRAMへ展開することができます.

    このコマンドにより,どのデバイスのカーネルイメージをRAMへ展開するかを設定できます.ここでは「hda1」,つまりコンパクトフラッシュのパーティション1 にある/boot/Image.gz イメージをRAMに展開することを指定しています.この設定はフラッシュメモリに保存され,次回起動時にも反映されます.

  • setenv

    カーネルを起動するときの起動オプションを設定します.この設定はフラッシュメモリに保存され,次回の起動時にも反映されます.

    JP1をオープンにして再起動すると,コンパクトフラッシュから起動します.Linuxの起動途中で図13 のように停止してしまうので,ENTERを押して再開してください.

●図13 Warning による起動の停止

fsck.ext2: Bad magic number in super-block while trying to open /dev/ram0
(null):
The superblock could not be read or does not describe a correct ext2
filesystem. If the device is valid and it really contains an ext2
filesystem (and not swap or ufs or something else), then the superblock
is corrupt, and you might try running e2fsck with an alternate superblock:
    e2fsck -b 8193 <device>

WARNING: Error while checking root filesystem.
You can login as root now, the system will reboot after logout.

Give root password for system maintenance
(or type Control-D for normal startup):

/etc/fstab の修正

図13のようにWarning が出るのは,ルートファイルシステムのチェックを行おうとしたときに,/etc/fstabに記述されている情報と実際の状況が違うためです.これを改善するには/etc/fstabを修正します(リスト9).

●リスト9 /etc/fstab の修正

1: /dev/hda2     /                 ext3      defaults     0     1      修正
2: proc          /proc             proc      defaults     0     0
3: usbfs         /proc/bus/usb     usbfs     defaults     0     0
4: sysfs         /sys              sysfs     defaults     0     0

読込み専用に設定

コンパクトフラッシュシステムで稼働している場合,システムを終了せずに電源を切断するとファイルシステムが破壊される可能性があります.これを防ぐために,ルートファイルシステムを読込み専用でマウントさせておくようにします.読込み専用にするためには,各起動スクリプトの修正を行います(リスト10,11).また,不必要な起動スクリプトを外しておきます(図14).

●リスト10 /etc/init.d/rc

(略)
29: #echo -n "Remounting root rw: "                                     コメントアウト
30: #mount -n -o remount,rw /                                           コメントアウト
31: #check_status                                                       コメントアウト
32:
33: mount -n -t ramfs ramfs /var/log                                    追加
34: mount -n -t ramfs ramfs /var/run                                    追加
35: mount -n -t ramfs ramfs /tmp                                        追加
36: mount -n -t ramfs ramfs /etc/config                                 追加
37:
(略)
41: echo -n "Mounting proc: "
42: mount -n proc                                                       修正
43: check_status
44:
45: echo -n "Mounting usbfs: "
46: mount -n usbfs                                                      修正
47: check_status
48:
49: echo -n "Mounting sysfs: "
50: mount -n sysfs                                                      修正
51: check_status
(略)
74: #echo "`cat /etc/DISTNAME`" > /etc/issue                            コメントアウト
75: #echo "`cat /etc/DISTNAME`" > /etc/issue.net                        コメントアウト
76: #echo "`uname -s` `uname -r` [`uname -m` arch]" >> /etc/issue       コメントアウト
77: #echo "`uname -s` `uname -r` [`uname -m` arch]" >> /etc/issue.net   コメントアウト
78: #echo >> /etc/issue                                                 コメントアウト
79: #echo >> /etc/issue.net                                             コメントアウト
●リスト11 /etc/init.d/misc

 7: echo -n "Mounting ramfs /home/ftp/pub: "
 8: mount -n -t ramfs ramfs /home/ftp/pub                               修正
 9: chmod 0777 /home/ftp/pub
10: check_status

●図14 不必要な起動スクリプトを外す

Armadillo-500 # rm -f /etc/rc.d/S05checkroot
Armadillo-500 # rm -f /etc/rc.d/S06checkftp

これで,すべての作業が終了しました.すべてのデバイスを接続して,再起動して動作を確認してみましょう.

あとがき

本特集では,アンケートツールの構築を順を追って説明してきました.今回はArmadillo-500開発ボードをプラットフォームとして選択しましたが,インターフェースが揃っている他のボードでも実現できます.

組み込み開発は,何をどのインターフェースで実現するかを検討するところから始まります.拡張のことも考慮して組み込みボードを選択することも,組み込み開発の楽しみの1つでしょう.

今回作成したアンケートツールは,まだまだ完全なものとは言えません.組み込みシステムとしてより良いものにするためには,

  • 起動の高速化

  • 自己診断機能

  • トラブル発生時の自動復旧

などを実現させると良いでしょう.本特集の内容を参考に,読者の皆さんの思い描いているシステムを構築してみてはいかがでしょうか.

COLUMN

楽チン作業♪

この章で解説した作業を簡単に行うには,図A のようにします.なお,図A はフラッシュメモリ用のイメージを作成するところまでです.

●図A 本章の作業手順まとめ

$ cd ~/work.sd
$ wget http://download.atmark-techno.com/misc/softwaredesign_2007-11/chapter7/linux-2.6.18-12-at0_add_cst-armadillo500_defconfig.patch
$ wget http://download.atmark-techno.com/misc/softwaredesign_2007-11/chapter7/atmark-dist-20070727_add_cst-a500.patch
$ cd linux-2.6.18-12-at0
$ patch -p1 < ../linux-2.6.18-12-at0_add_cst-armadillo500_defconfig.patch
$ cd ../atmark-dist-20070727
$ patch -p1 < ../atmark-dist-20070727_add_cst-a500.patch
$ make menuconfig
*** Main Menu ***
Vendor/Product Selection  --->
        (AtmarkTechno) Vendor
        (CST.Armadillo-500) AtmarkTechno Products
Kernel/Library/Defaults Selection  --->
        (default) Cross-dev
        (None) Libc Version
        [*] Default all settings (lose changes)
        [ ] Customize Kernel Settings
        [ ] Customize Vendor/User Settings
$ make
先頭 Part 6