フリーの H8 用リアルタイムOS、HOS-H8 を GNU H8クロス開発環境でコンパイ ルできるように移植します。このソフトウェアは Windows 環境上で動作するイ エローソフト社のコンパイ ラ用に作られているので、これを gcc / gas 用に 変更する必要があります。 C の部分については特に手をいれる必要がありませんが、アセンブラの部分は、 「Cとアセンブラのリンケージの方法の違い」や、「アセンブラ表記の違い」が 存在するので、これらを修正する必要があります。
.bss : {
BSS_start = .;
*(.bss)
*(COMMON)
BSS_end = .;
} >ram
BSS_size_low = SIZEOF(.bss);
HOS-H8 はμITRON3.0仕様に準拠した 日立 H8/300H シリーズ用のリアルタイ ムOSです。 主に個人レベルでのホビーを目的とした物でROM化するシステムにリンクす るだけで簡単に組み込むことが出来ます。Ryuz Laboratoryにて公開さ れています。詳細やオリジナルファイルの入手に関してはこちらを御覧ください。
なお、以下の内容は Ver 0.02 のソースを元に記述してあります。
% sh $ for i in *.c; do $ ack -ezuA $i $ rm $i.bak $ done
もちろん C とアセンブラとのリンケージなどどうしても自動では対応できない 物があります。これらはそれぞれ手で対応していきます。
イエローソフトのアセンブラ表記と、gas のアセンブラ表記の違いは代表的な物 では次のようになります。
| 項目 | イエローソフト表記 | gas 表記 |
| 16進数表現 | H'1234 | 0x1234 |
| 2進数表現 | B'0101 | 0b0101 |
| 定数定義 | シンボル equ 式 | .equ シンボル 式 |
| 外部ラベル宣言 | public ラベル名 | .global ラベル名 |
| 外部ラベル参照 | .extern ラベル名 | 記述不要 |
| segment 定義 | segment セグメント名 | .section セクション名 |
| データ領域 | ds.b/ds.w/ds.l | .space 1/.space 2/.space 4 |
例えば H' -> 0x の変換を行う sed script は
例として task_dsp.asm の swc_dsp() の書き換えを以下に示します。(diff -c の出力結果です。先頭が - はオリジナルから削る部分、+ は追加する部分です。)
; -----------------------------------------------
; タスク切り替え
; H __swc_dsp(T_TCB *tcb);
; -----------------------------------------------
+;; er0 : T_TCB *tcb
+;;
.section .text
.global ___swc_dsp
___swc_dsp:
+ push.l er3
+ push.l er4
+ push.l er5
push.l er6
- mov.l @(8, er7), er0 ; 引数取得
+ ; 引数取得
subs #2, er7 ; リターンパラメータ用領域作成
mov.l @_curtcb,er1
mov.l er7,@er1 ; スタックポインタ保存
mov.l @er0, er7 ; スタックポインタ復帰
mov.l er0,@_curtcb ; 新tcb登録
pop.w r0 ; リターンパラメーター取得
pop.l er6
+ pop.l er5
+ pop.l er4
+ pop.l er3
rts
#ifdef __GNUC__ 〜 #else 〜 #endifでくくってあります。
データセグメントの初期化は DATA_rom から書かれているデータを DATA_start から DATA_size バイトコピーすることで行います。 つまり DATA_start から実際に参照するデータを DATA_rom のアドレスに出力す るように書けば良いわけです。リンカスクリプトの DATAセグメント部分は次の ようになります。
.data : AT (ADDR(.text) + SIZEOF(.text)){
DATA_rom = ADDR(.text) + SIZEOF(.text);
DATA_start = .;
*(.data)
DATA_end = .;
} > ram
DATA_size_low = SIZEOF(.data);
AT() を使います。これで解決アドレスと格納アドレスを別々にできます。
そして、スタートアップルーチンで使用するシンボルにアドレスをそれぞれ代入
します。
BSS セグメントは解決アドレスと格納アドレスは同じですので、シンボルへの代 入だけです。
.bss : {
BSS_start = .;
*(.bss)
*(COMMON)
BSS_end = .;
} >ram
BSS_size_low = SIZEOF(.bss);
更にスタートアップアドレス hos_start を ENTRY() で定義します。
ENTRY("hos_start");
$Id: porting-hos-h8.html,v 1.2 2003/06/16 16:15:48 hoso Exp $