Linux on CortexM3(ARMv7M)

この記事はmbed Advent Calendar 2015 - Adventarの13日目の記事です。 13日目の折り返しと言うことで気合いを入れ直す意味でガツンと記事を書かせていただこうと思います。

はじめに

先月くらいから、mbed界隈ではOSがキーワードとなっているようです。そこで本稿ではmbedOSについて調査した結果を報告したいと思います。

mbedなOS

まずは、OSといってもいろいろありますので、何から調査すべきかを決定したいと思います。そこで、Google先生に一番有名なOSは何か聞いてみました。

Google先生曰く「OSとはLinuxのことなり!」

/media/uploads/noritsuna/advent_2015_mfos.png

このことから、mbed界隈で話題のmbedなOSとやらは、mbed(Cortex-M)で動くLinuxのことだと推測されます。※Google先生調べ

Linux on Cortex-M3

Google先生の導きに従い調査したところ、ありました!

Linux on Cortex-M3

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)を堪能したいと思います。

で、そのターゲットボードですが・・・

RealView EB(ARM926EJ-S)

/media/uploads/noritsuna/advent_2015_arm926ej.jpg

な、、んだ?これは???こんなの、mbedじゃなぁぁぁぁぁい。しかも、最近mbed界隈で話題のはずなのにLegacy Boardの中に入っています!!!意味がわかりませんね。今、話題なのに!!!

どうもこいつは、最近mbed界隈で話題のmbedなOSでは無いようです。

俺たちのSTM32

やはり、ここはmbed Advent Calendarですので、mbed Enabledの製品でOS(Linux)したいですよね!

ということで、mbed EnabledなSTM32F7 Discoveryさんです!

http://www.st.com/st-web-ui/static/active/en/fragment/product_related/rpn_information/board_photo/stm32f746g-disco.jpg

/media/uploads/noritsuna/advent_2015_stm32f2disc.jpg

最高峰Cortex-M7装備です!そして、128Mbit SDRAM(64 Mbits accessible) & 128Mbit Quad-SPI Flash memory装備*2です! そして、見よ!この燦然と輝くARMmbedのマークを!!!

/media/uploads/noritsuna/advent_2015_armmbed.jpg

EmCraft uClinux

そして、肝心のLinuxですが、なんと、EmCraft Systems社がCortex-M3/4用のuClinuxをgithub上に公開してくれています。 そこで、今回はこれをmbed EnabledなSTM32F7 Discoveryで利用しようと思います。

EmCraft uClinux

EmCraft u-boot

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に書き込みます。

/media/uploads/noritsuna/advent_2015_start_address_u-boot.png

これで、"Verification...OK"と出力されれば、u-bootのセットアップが完了です。

/media/uploads/noritsuna/advent_2015_write_u-boot.png

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

/media/uploads/noritsuna/advent_2015_serialpins1.jpg

/media/uploads/noritsuna/advent_2015_serialpins2.jpg

接続後、STM32F7 Discoveryをリセットして、コンソールにu-bootの画面が出ればOKです。出ない場合は、再挑戦してください。

/media/uploads/noritsuna/advent_2015_u-boot.png

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の読み込み

/media/uploads/noritsuna/advent_2015_load_linux.png

  • Linuxのブートログ

/media/uploads/noritsuna/advent_2015_boot_linux.png

以上で、mbed界隈ではやりのmbedなOSであるLinuxをmbed EnabledであるSTM32F7 Discovery上で動かすことが出来ました! みなさんもぜひ、"mbed界隈ではやりのmbedなOS"を楽しんでください!

エンジョイ、エェェェンベッド!リナァァァクス!

  • 2 みなさん、お気づきだとは思いますが、Linuxするには、S(D)RAM:8MBytesが最低限必要です。


Please log in to post comments.