Linux on CortexM3(ARMv7M)
この記事はmbed Advent Calendar 2015 - Adventarの13日目の記事です。 13日目の折り返しと言うことで気合いを入れ直す意味でガツンと記事を書かせていただこうと思います。
はじめに
先月くらいから、mbed界隈ではOSがキーワードとなっているようです。そこで本稿ではmbedなOSについて調査した結果を報告したいと思います。
mbedなOS
まずは、OSといってもいろいろありますので、何から調査すべきかを決定したいと思います。そこで、Google先生に一番有名なOSは何か聞いてみました。
Google先生曰く「OSとはLinuxのことなり!」
このことから、mbed界隈で話題のmbedなOSとやらは、mbed(Cortex-M)で動くLinuxのことだと推測されます。※Google先生調べ
Linux on Cortex-M3
Google先生の導きに従い調査したところ、ありました!
Cortex-M3(ARMv7-M & non MMU CPU)をターゲットとしたLinux2.6(uClinuxベース)のようです。これは、mbed界隈で流行っているOSの可能性大です!
build kernel
では、早速手順通りにビルドしてみましょう!
Download kernel
まずは、linux-arm.orgのgitリポジトリからソースコード一式をダウンロードします。
command line
$ git clone git://linux-arm.org/linux-2.6-stable.git $ cd linux-2.6-stable.git $ git checkout refs/tags/v2.6.33-arm1
Configure kernel
続いて、defconfig・・・ではなく、.configファイルをダウンロードするそうです。
command line
$ wget http://www.linux-arm.org/pub/LinuxKernel/LinuxM3/.config
ですが、この.configファイルではビルドが通りません。そこで、一部の設定を変更します。
command line
$ make ARCH=arm menuconfig
として、"ARM system type"を、"ARM Ltd. Microcontroller Prototyping System"に変更してください。この"Microcontroller Prototyping System(MPS)"というものが、Cortex-M3(ARMv7-M & non MMU CPU)のことのようです。
menuconfig
Syste Type->ARM system type->ARM Ltd. Microcontroller Prototyping System
Setup init RAM FS
次に、initramfsの設定をします。シェルやコマンド類はbusyboxを利用するようです。(自力ビルドの方法も書いてありますが、今回はプリビルドのものをそのまま利用します。)
command line
$ wget http://www.linux-arm.org/pub/LinuxKernel/LinuxM3/initramfs-list-min
そして、.configファイルの"CONFIG_INITRAMFS_SOURCE"に、ダウンロードした"initramfs-list-min"ファイルのフルパスを記述します。
re-write in .config
CONFIG_INITRAMFS_SOURCE="[download dir]/initramfs-list-min"
さらに、busyboxを用意します。
command line
$ wget http://www.linux-arm.org/pub/LinuxKernel/LinuxM3/busybox
busyboxをダウンロードしたら、"initramfs-list-min"ファイルの内の下記行にbusyboxのフルパスを記述します。
re-write in initramfs-list-min
file /bin/busybox [download dir]/busybox 755 0 0
Setup Toolchain
Toolchainは、手順書にあるものではなく、busyboxの自力ビルドで利用しているuClinuxのものを使ってください。
arm-2007q1-21-arm-uclinuxeabi-i686-pc-linux-gnu.tar.bz2
解凍後、bin/にpathを通しておいてください。
make kernel
これで、kernelをビルドする準備が出来ました。ビルドしちゃってください!
command line
$ make ARCH=arm CROSS_COMPILE=arm-uclinuxeabi- Image
これで、"arch/arm/boot/Image"が出来ているはずです。この中に"initramfs-list-min"ファイルに記述していたbusyboxやファイルシステムが取り込まれていますので、読み込めれば*1、Linuxが起動するはずです!!!
- 1 u-boot?知らない子ですね。
Setup to a target board???
さっそく、mbed実機に読み込ませて、mbedなOS(Linux on Cortex-M3)を堪能したいと思います。
で、そのターゲットボードですが・・・
な、、んだ?これは???こんなの、mbedじゃなぁぁぁぁぁい。しかも、最近mbed界隈で話題のはずなのにLegacy Boardの中に入っています!!!意味がわかりませんね。今、話題なのに!!!
どうもこいつは、最近mbed界隈で話題のmbedなOSでは無いようです。
俺たちのSTM32
やはり、ここはmbed Advent Calendarですので、mbed Enabledの製品でOS(Linux)したいですよね!
ということで、mbed EnabledなSTM32F7 Discoveryさんです!
最高峰Cortex-M7装備です!そして、128Mbit SDRAM(64 Mbits accessible) & 128Mbit Quad-SPI Flash memory装備*2です! そして、見よ!この燦然と輝くARMmbedのマークを!!!
EmCraft uClinux
そして、肝心のLinuxですが、なんと、EmCraft Systems社がCortex-M3/4用のuClinuxをgithub上に公開してくれています。 そこで、今回はこれをmbed EnabledなSTM32F7 Discoveryで利用しようと思います。
get Linux
上記のgithubからcloneしてもよいのですが、今回はEmCraft Systems社よりリリースされているLinux BSP for STM32F7 Discovery BoardというLinuxシステム一式を利用します。 具体的には、下記のものがワンパッケージになっています。
- u-boot
- Linux kernel
- busyboxベースのinitramfs/userland
- BSP一式
- アプリケーション開発環境
Setup Source Codes
では、ダウンロードしたソースコード一式"linux-STM32F7DISCO-1.14.2.tar.bz2"を解凍します。出来上がるのは、以下の通りです。
- u-boot/ - U-Bootのソースコード一式
- linux/ - Linux (uClinux) kernelのソースコード一式
- tools/ - 開発用ツール一式
- projects/ - サンプルプロジェクトやアプリケーション
- ACTIVATE.sh - 必要な環境変数を設定するためのシェルスクリプト。手動でやってもよい。
Setup Toolchain
しかし、"tools/"ディレクトリに、toolchainが用意されていませんので、ダウンロードし、"tools/"ディレクトリ内で解凍します。
command line
$ cd tools/ $ wget http://www.codesourcery.com/sgpp/lite/arm/portal/package6503/public/arm-uclinuxeabi/arm-2010q1-189-arm-uclinuxeabi-i686-pc-linux-gnu.tar.bz2 $ tar xvfj arm-2010q1-189-arm-uclinuxeabi-i686-pc-linux-gnu.tar.bz2
build Kernel
続いて、Linux kernelをビルドします。 このビルドにおいては、
- Linux kernel
- busybox(initramfs/userland)
- 自作アプリケーション
がビルドされて、
- [project name].uImage
の中に取り込まれます。 ビルド対象は、"projects/"ディレクトリの下に用意されています。内容は、
- hello - kernel, busybox, helloというアプリケーションというLinux起動における最低限のものしかないプロジェクト
- networking - ネットワークなどLinuxを通常使う上で必要なものがすべて組み込まれたプロジェクト
- developer - gdbなどアプリケーション開発を行う上で必要なものが組み込まれたプロジェクト
となっていますので、今回は"networking"プロジェクトを利用します。
command line
$ . ACTIVATE.sh $ cd projects/networking $ make
これで、"networking.uImage"というファイルが出来たはずです。これが、initramfs + Linux kernelが一つにまとめられたファイルです。
ちなみに、makeには下記のオプションが用意されています。
- all or linux - Linux kernel, busybox, 自作アプリケーションをビルドします。
- kclean - the Linux kernelをcleanします。
- bclean - busyboxをcleanします。
- aclean - 自作のApplicationをcleanします。
- clean - 全部をcleanします。
- kmenuconfig - Linux kernelのmake menuconfigを開きます。
- bmenuconfig - busyboxのmake menuconfigを開きます。
- clone new=newproject - いまあるプロジェクトのクローンを作ります。
make my project
もし、自分オリジナルのプロジェクトを作成したい場合は、下記のものを用意します。
- "Makefile"ファイル - プロジェクト名と独自のビルド対象アプリケーションを記述します。
- kernel用の.configファイル - "[project name].kernel.[MUC name]"という名前で用意します。
- busybox用の.configファイル - "[project name].busybox"という名前で用意します。
- initramfs用ファイル - "[project name].initramfs"という名前で用意します。
"Makefile"は下記のような感じで用意します。
Makefile
SAMPLE := networking CUSTOM_APPS := include ../Rules.make
ですが、スクラッチからすべて用意するのは大変ですので、"make clone"コマンドを利用して、既存のプロジェクトをベースに改造するのがよいでしょう。
build u-boot
これで、Linux kernelは用意できました。さっそく、実機で・・・と行きたいところですが、このままでは起動できません。なぜなら、ブートローダーがないからです。そこで、ブートローダーである"u-boot"を用意します。 そして、"u-boot"は、下記のディレクトリに用意されています
- u-boot/ - U-Bootのソースコード一式
また、"u-boot"のオプションなど変更が必要な場合は、下記の参考に適宜変更してください。
- u-boot/include/configs/stm32f746-discovery.h - U-Bootのコンフィグレーションはここに記述されています。
- u-boot/board/stm/stm32f746-discovery/board.c - board-specificな設定はここに記述され では、さっそくビルドしてみましょう。
command line
$ . ACTIVATE.sh $ cd u-boot $ make distclean $ make stm32f746-discovery_config $ make -s
これで、"u-boot.bin"が出来ているはずです。これが、ブートローダーとなります。
Setup u-boot
さっそく、実機の方にこのブートローダーをセットアップしましょう。セットアップには、STMicroelectronics社のST-linkというツールが必要ですので、ダウンロードして、インストールしてください。
Connect Cable
続いて、USBケーブルでSTM32F7 DiscoveryとPCを接続します。STM32F7 Discovery側の接続場所は、"CN14"です。※これは、ST-Link用のコネクターで、シリアルコンソールではありません。
- "ST-Link USB connector (CN14)"
そして、電源を入れてください。
Load&Write u-boot
次に、ST-linkを起動して、"u-boot.bin"を読み込みます。
- "File -> Open file ..."
そして、
- "Target -> Program & Verify ..."
で、"Start Address"を"0x08000000"として、STM32F7 Discoveryに書き込みます。
これで、"Verification...OK"と出力されれば、u-bootのセットアップが完了です。
Load Linux
続いて、シリアルコンソールを使えるようにします。設定は、下記の通りです。必要なシリアル-TTL変換器を用意してください。
- TTL 3.3V
- 115.2 Kps
- 8N1
コネクタの位置は、下記のようになっています。裏側にあるArduino互換コネクタの一部がシリアルとして利用可能です。
- CN4.1 (Arduino:D0) RXD
- CN4.2 (Arduino:D1) TXD
- CN7.7 (Arduino:GND) GND
接続後、STM32F7 Discoveryをリセットして、コンソールにu-bootの画面が出ればOKです。出ない場合は、再挑戦してください。
Load Linux
最後に、Linux kernelをSTM32F7 Discoveryに読み込みします。
- TFTP
を利用しますので、TFTPサーバアプリケーションを用意してください。 本稿では、
- TFTPサーバのIPアドレス - 192.168.1.100
- STM32F7 DiscoveryのIPアドレス - 192.168.1.150
- TFTPサーバ上にあるSTM32F7 DiscoveryのLinux Imageのパス - /networking.uImage
とします。
Setup MAC&IP Address
まず、STM32F7 Discovery上のu-bootを起動します。 続いて、TFTPに関する設定を行います。
- ethaddr - STM32F7 DiscoveryのMAC Address
- ipaddr - STM32F7 DiscoveryのIP Address
- serverip - TFTPサーバのIP Address
- saveenv - 設定の保存
u-boot command line
STM32F746-DISCO> setenv ethaddr C0:B1:3D:88:88:88 STM32F746-DISCO> setenv ipaddr 192.168.1.150 STM32F746-DISCO> setenv serverip 192.168.1.100 STM32F746-DISCO> saveenv
Setup boot parameters
TFTP経由でのブートさせるための"netboot"のパラメーターがどうなっているのかを確認します。下記のようになっていなければ、変更してください。
u-boot command line
STM32F746-DISCO> printenv netboot netboot=tftp ${image};run args addip;bootm
Setup boot parameters & Run Linux
最後に、"netboot"の"image"パラメータに"TFTPサーバ上にあるSTM32F7 DiscoveryのLinux Imageのパス"を設定して終了です。
u-boot command line
STM32F746-DISCO> set image networking.uImage STM32F746-DISCO> saveenv Saving Environment to envm...
Run Linux
ついに、実機でのLinuxのブートです!TFTP経由でLinuxを読み込んで、STM32F7 Discovery上でブートさせます。
u-boot command line
STM32F746-DISCO> run netboot Auto-negotiation...completed.
- ネットワークからのLinuxの読み込み
- Linuxのブートログ
以上で、mbed界隈ではやりのmbedなOSであるLinuxをmbed EnabledであるSTM32F7 Discovery上で動かすことが出来ました! みなさんもぜひ、"mbed界隈ではやりのmbedなOS"を楽しんでください!
エンジョイ、エェェェンベッド!リナァァァクス!
- 2 みなさん、お気づきだとは思いますが、Linuxするには、S(D)RAM:8MBytesが最低限必要です。
Please log in to post comments.