優先度スケジューリング実装完了 - 12ステップ本を試す その3

1/10に12ステップ本の著者の坂井さんが開催した第2回12ステップ本もくもく会に参加して依頼、あまり作業を進められていませんでした。先日の休みに数時間作業ができ、9章の優先度スケジューリングの実装まで終わったのでメモを残しておきます。

12ステップで作る組込みOS自作入門

12ステップで作る組込みOS自作入門

まず、8章。
この章ではスレッドの実装を行いますが、私の環境ではなぜかkz_thread構造体利用箇所で「kozos.c:(.text+0x173): undefined reference to `___mulsi3'
」というエラーがでてしまい、kz_thread構造体のパディングを行う必要がありました。
具体的には

typedef struct _kz_thread {
  struct _kz_thread *next;
  
  (省略)

  kz_context context;
  char dummy[16]; /* ←ここにpaddingを追加 */
} kz_thread;

こんな風にしました。

次に9章ですが、kz_thread構造体のサイズが変わったのでパディングのサイズも変える必要がありました。
下記のようにしています。

typedef struct _kz_thread {
  struct _kz_thread *next;
  
  (省略)

  kz_context context;
  char dummy[8]; /* ←9章ではpaddingは8に */
} kz_thread;

また9章ではOSをxmodemでロードするときに、OSのELFファイルの受信が「58ブロック/7K」で止まってしまうということが発生しました。
このサイズで受信が止まる、という症状だったのですぐに気づいたのですが、私は個人的にメッセージ出力を楽に書けるようにlib.cに独自にputmsg()という関数を書いたりするなど、いろいろ余計なものをkozosに追加していたためか、kozos.elfの大きさが8KBより少し大きくなってしまい、リンカ・スクリプトで当初用意していた受信バッファのサイズでは領域が足らなくなったのが原因でした。(→後日訂正追記:*1 )

これに対応するためにリンカスクリプト(ld.scr)でバッファのサイズを変更しました。バッファをメモリの前方方向に領域を広げるようリンカスクリプトを変更しています。
修正内容は下記の通りです。

  • 変更前
MEMORY
{
	(省略)
	buffer(rwx)	: o = 0xffdf20, l = 0x001d00
	(省略)
}
  • 変更後
MEMORY
{
	(省略)
	buffer(rwx)	: o = 0xffd280, l = 0x0029a0
	(省略)
}

bufferのオリジンは使われていない領域を確認して設定しました。
kozos.elfをreadelfコマンドで見てみると、プログラムヘッダが下記のようになっていたため、それに合わせてオリジンを調整しています。

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00ffbf8c 0x00ffbf8c 0x00e2e 0x00e2e R E 0x1
  LOAD           0x000e30 0x00ffcdbc 0x00ffcdbc 0x002a3 0x002a3 R   0x1
  LOAD           0x0010d4 0x00ffd060 0x00ffd060 0x00004 0x00220 RW  0x1

これをみるとkozosの使うメモリ領域の末尾が0xffd280番地(0x00ffd060 + 0x00220)なので、その直後からbufferが開始されるように設定しました。
bufferの末尾は以前のままになるようbufferの長さも0x002910に変更しました。


あと残り3章でこの本での組み込みOS開発の学習も終わりです。
次の休みに終わるよう頑張ろう。

*1:バッファの容量が不足していたのはstripコマンドを通していないkozos.elfを転送していたからでした。stripコマンドを通してシンボルテーブルを消したkozosファイルであれば6KBバッファ使用量はくらいで済みました

ブートローダの作成が完了 - 12ステップ本を試す その2

年末年始の空き時間に12ステップ本にしたがって作業を進めていましたが、7章まで完了することができました。
これでブートローダの作成が一段落ついた感じです。

12ステップで作る組込みOS自作入門

12ステップで作る組込みOS自作入門

ELFファイルを転送するにあたって、試しに使ってみていたminicomでの作業だとファイル転送の実行の操作が面倒でしたので、結局Macにデフォルトでインストールされているcuコマンドでh8ボードにシリアル接続して作業するようになりました。

また、xmodemプロトコルでのファイル転送につかったのはlsxコマンドですが、これについてもMacにはデフォルトでは入っていないコマンドなので、次のようにhomebrewからのインストールを行いました。

lsxコマンドのインストール

sudo brew install lrzsz

これでlsxなどのコマンドが使えるようになります。

ELFファイルのシリアル転送の実行

12ステップ本ではcuコマンド実行中に"~C"を入力してlsxコマンドを実行するように書いてありますが、Macのcuの場合は"~+"を入力してコマンドを実行すると、シリアルからの入力がコマンドへの入力になり、コマンドの入力がシリアルへの出力になります。

実際にこれまで作成したものを実行してみた所です。

% sudo cu -l /dev/cu.PL2303-00004006 
Connected.

kzload> 
boot loader started.
kzload> load
~+ lsx kozos.elf
Sending kozos.elf, 27 blocks: Give your local XMODEM receive command now.
Bytes Sent:   3584   BPS:196                             

Transfer complete
load succeeded.
kzload> run
magic      : 7f454c46
Class      : 01
Byte order : 02
Version    : 01
OS/ABI     : 00
ABI ver.   : 00
type       : 0002
arch       : 002e
version    : 00000001
entry point: 00ffc020
program hdr: 00000034
section hdr: 00000608
flags      : 00810000
hdr_size   : 0034
program_hdr_size : 0020
program_hdr_num  : 0002
section_hdr_size : 0028
section_hdr_num  : 0008
section_str_table: 0005
type     offset   vaddr    paddr    file-sz  mem-sz
-------- -------- -------- -------- -------- --------
00000001 00000000 00ffbfac 00ffbfac 000004ba 000004ba
00000001 000004bc 00ffc468 00ffc468 00000100 00000100
starting from entry point... : 00ffc020

os started.
kozos> echo Hello, world!
 Hello, world!
kozos>

runコマンドの処理ではELFファイルの情報を出力したあとkozos側に制御が移るようにしています。


ということで、12ステップ本にそって組込みOSを作ってみているところですが、12ステップ本は素晴らしい本だと思います。

  • 説明が入門者にもやさしく丁寧にかいてあること
  • CDROMメディアの普及などで最近の書籍ではあまり見かけなくなってしまった「このリストを全部打ち込もう。そうすれば動くようになるよ」という書き方
  • 最初は単純なものをつくり、徐々にステップアップしていくという達成感が得られやすくモチベーションも続きやすい進め方

といった点は、学習者にとってはとてもうれしいものです。

  • ブートローダ作りたい。ELFファイルのロードを学習したい。
  • OSを作ってみたい。OSの基本機能を学習したい。

という人はぜひ最初にこの本を手にしてみるとよいと思います。

MacでH8開発環境構築 - 12ステップ本を試す

仕事でやっていたプロジェクトがやっと片付いたので、先日からやろうと思っていたH8のプログラム作成を12ステップ本にそって試しました。

12ステップで作る組込みOS自作入門

12ステップで作る組込みOS自作入門

私が個人で使っているPCは半年くらい前からMacBook Proなのですが、12ステップ本では開発環境としてFreeBSD,Fedora,Ubuntu,Windowsは紹介されているものの、Macの記述がありません。
googleで検索してみても、情報が少ないようなので私が環境構築を行ったときの内容をまとめようと思います。

USBシリアル変換ケーブルとシリアルの延長ケーブルは、秋月で以前購入していたAKI−PICプログラマー用電源・USBシリアル(グレー)・ケーブルセットのものを使いました。持っていない人は秋月のUSB・シリアル変換ケーブル(延長ケーブル付)あたりを購入するといいと思います。

USBシリアルドライバは、最初ProlificのサイトのPL-2303 Software and Driversのページから最新のドライバmd_PL2303_MacOSX10.6_dmg_v1.4.0.zipをダウンロードしてインストールしてみましたが、h8writeで書き込む時に、応答がもどってこない状態になり書き込みできませんでした。AppleのサイトのドライバダウンロードページにあるPL2303 USB to Serial Driver 0.3.1だとちゃんと書き込めるようです。

以下が環境構築手順です。

H8用gcc, binutils, などをダウンロード

cd ~/Downloads/src
curl -O http://www.ring.gr.jp/archives/GNU/binutils/binutils-2.21.tar.bz2
curl -O http://www.ring.gr.jp/archives/GNU/gcc/gcc-4.5.2/gcc-4.5.2.tar.bz2
curl -O http://www.ring.gr.jp/archives/GNU/gmp/gmp-4.3.2.tar.bz2
curl -O http://www.ring.gr.jp/archives/GNU/mpfr/mpfr-2.4.2.tar.bz2
curl -O http://www.multiprecision.org/mpc/download/mpc-0.8.2.tar.gz

gcc, binutilsなどのインストール

binutils, gccのインストール先は12ステップ本とは少し変えて、/usr/local/h8-elfにインストールすることにしました。(このインストール場所でインストールして12ステップ本を試す場合、12ステップ本に書かれたMakefileは若干変更する必要があります)
gccのインストールに必要なライブラリ(gmp, mpfr, mpc)についても/usr/localの下に個別にディレクトリを作って、そこにインストールすることにします。

bintutils
tar jxvf binutils/binutils-2.21.tar.bz2
cd binutils-2.21
./configure --target=h8300-elf --disable-nls --prefix=/usr/local/h8-elf
make
sudo make install
gmpライブラリ
cd ~/Downloads/src
tar jxvf gmp-4.3.2.tar.bz2
cd gmp-4.3.2 
./configure --prefix=/usr/local/gmp
make
make check
sudo make install
mpfrライブラリ
cd ~/Downloads/src
tar jxvf mpfr-2.4.2.tar.bz2
cd mpfr-2.4.2
./configure --prefix=/usr/local/mpfr --with-gmp=/usr/local/gmp
make
make check
sudo make install
mpcライブラリ
cd ~/Downloads/src
tar zxvf mpc-0.8.2.tar.gz
cd mpc-0.8.2
./configure --prefix=/usr/local/mpc \
  --with-gmp=/usr/local/gmp \
  --with-mpfr=/usr/local/mpfr \
make
make check
sudo make install
gcc
cd ~/Downloads/src
tar jxvf gcc-4.5.2.tar.bz2
mkdir build # gcc 4.5はソースディレクトリ内でビルドするとエラーになるため
cd build
../gcc-4.5.2/configure \
  --target=h8300-elf \
  --disable-nls \
  --disable-threads \
  --disable-shared \
  --disable-libssp \
  --enable-languages=c \
  --with-gmp=/usr/local/gmp \
  --with-mpfr=/usr/local/mpfr \
  --with-mpc=/usr/local/mpc \
  --prefix=/usr/local/h8-elf
make
sudo make install

USBシリアルドライバの動作確認

AppleのPL2303 USB to Serial Driver 0.3.1ダウンロードページからドライバをダウンロードしてインストールしたあと、USBシリアル変換ケーブルをMacにさして/devを確認します。

% ls -l /dev/cu*            
crw-rw-rw-  1 root  wheel   11,   3 12 25 23:24 /dev/cu.Bluetooth-Modem
crw-rw-rw-  1 root  wheel   11,   5 12 25 23:24 /dev/cu.Bluetooth-PDA-Sync
crw-rw-rw-  1 root  wheel   11,  33 12 26 20:23 /dev/cu.PL2303-00004006

USBシリアル変換ケーブルを取り付けると/dev/cu.PL2303-00004006というデバイスが表示されるようになります。
/dev/cu.PL2303-XXXXXXXのXXXXXXXの部分はUSBシリアル変換ケーブルを抜き差しすると数字が変わるようです。接続するUSBインターフェースをごとに違う番号になるようです。
そのため、h8writeでプログラムを書き込む時はUSBシリアル変換ケーブルを抜き差しするたびに/devを確認しないといけないようです。

h8writeインストール

これは普通にソースをダウンロードしてコンパイルするだけです。

curl -O http://mes.sourceforge.jp/h8/h8write.c
gcc -Wall -o h8write h8write.c

minicomインストール

macにデフォルトでインストールされているcuコマンドやscreenコマンドでもシリアル接続できますが、12ステップ本にminicomが紹介されていたのでそちらを使ってみます。
インストールはhomebrewを使いました。

brew install minicom

minicomの設定

12ステップ本どおりに設定します。

minicom -sで起動して下記の設定を行います。
表示されるメニューで「Serial port setup」を選択し、下記のようになるよう設定しました。

    +-----------------------------------------------------------------------+
    | A -    Serial Device      : /dev/cu.PL2303-00001004                   |
    | B - Lockfile Location     : /usr/local/Cellar/minicom/2.4/var         |
    | C -   Callin Program      :                                           |
    | D -  Callout Program      :                                           |
    | E -    Bps/Par/Bits       : 9600 8N1                                  |
    | F - Hardware Flow Control : No                                        |
    | G - Software Flow Control : No                                        |
    |                                                                       |
    |    Change which setting?                                              |
    +-----------------------------------------------------------------------+

ファーム書き込みと動作確認

あとは12ステップ本どおりにソースコードをうって、動作確認するだけです。

上記画面は12ステップ本のステップ1の実行結果です。実行できました。

はじめて読む486 再読

OS周辺をしっかり理解するために、「はじめて読む486」を再読中。10年ぶりくらいに読み直している。
「5. セグメント」を読んできて気づいたが、152ページのリスト5-7の

/* Descriptor Type 32 */
#define BigSeg 0x80

この部分、0x40が正いのではないかと。

cronの設定で標準出力のリダイレクトの記述の有無によってプロセスの起動の仕方が変わる

今まで気付かなかった。

標準出力をリダイレクトしない下記のような設定をした場合

たとえばperlスクリプトをcronに登録するときに、このようにcrontabにリダイレクトを書かないと

[foo@sv01 ~]$ crontab -l
* * * * * /home/foo/bar.pl

crontabに設定したコマンドがcrondの子プロセスとして起動される。

[foo@sv01 ~]$ ps -ef
foo      23250  2413  0 11:25 ?        00:00:00 crond
foo      23253 23250  0 11:25 ?        00:00:00 /usr/bin/perl /home/foo/bar.pl
foo      23278 23159  0 11:25 pts/2    00:00:00 grep 23250
(他省略)
標準出力のリダイレクトを書いた場合

crontabにリダイレクトを書くと

[foo@sv01 ~]$ crontab -l
* * * * * /home/foo/bar.pl > /dev/null 2>&1

shのプロセスがcrondの子プロセスになり、crontabに設定したコマンドはそのshプロセスの子プロセスになる。

[foo@sv01 ~]$ ps -ef
foo      23570  2413  0 11:34 ?        00:00:00 crond
foo      23571 23570  0 11:34 ?        00:00:00 /bin/sh -c /home/foo/bar.pl > /dev/null 2>&1
foo      23572 23571  0 11:34 ?        00:00:00 /usr/bin/perl /home/foo/bar.pl
(他省略)


確認した環境:CentOS(4.4 x86-64/5.3 x86-64)

なぜか今年はコンパイラ本がたくさん出版されてる


コンパイラの本なんか、そうそう出版されるものでもないのに今年2009年はたくさんコンパイラの本がでたなー。


名著も新しい版がでたし。



これとか。買った。

コンパイラ―原理・技法・ツール (Information & Computing)

コンパイラ―原理・技法・ツール (Information & Computing)

これも。邦訳されたと知って昨日注文した。

最新コンパイラ構成技法

最新コンパイラ構成技法

これも。第2版がでてるの発見して、昨日注文した。

コンパイラの構成と最適化

コンパイラの構成と最適化


名著ではなく初心者むけのコンパイラの作り方作成本も今年何冊もでてる。

これは買った。

ふつうのコンパイラをつくろう

ふつうのコンパイラをつくろう

このシリーズも今年出版。

やさしいインタープリタの作り方入門―オリジナルなインタープリタを作成する

やさしいインタープリタの作り方入門―オリジナルなインタープリタを作成する

やさしいコンパイラの作り方入門―オリジナルなコンパイラを作成する

やさしいコンパイラの作り方入門―オリジナルなコンパイラを作成する

これも今年出版。書店で目立つように並べられてたなー。

プログラミング言語を作る

プログラミング言語を作る



コンパイラが今熱いんだろうか。

「コンパイラ[第2版]」〜 原理・技法・ツール 〜

メモ:
購入する
http://www.saiensu.co.jp/?page=book_details&ISBN=ISBN978-4-7819-1229-5&YEAR=2009

予価:8,800円
発行:サイエンス社
発売予定:2009-05 中〜下旬
ISBN 978-4-7819-1229-5 / A5判/約1120頁