目次
ytakanoは書きました
- 「はりぼてOS」が基底となっております。
- 下記から拾っても、他の環境では動かない可能性があります。
- 実機環境は、「Pentium-133[MHz]」ですので、これ以外では動かない場合があります。
- 仮想環境は、(2011-05-26)現在Windows7上のVirtualBox4.Xです。これ以外では作業をしていません。
- 【記】http://www6.shizuokanet.ne.jp/ytakano/
PCIと機器設定
- PCI−BIOSが搭載されているのであれば何も考える必要がありませんでした。
注意する点と言えば、機器が数珠繋がりになっているので、機器ごとの割り込み処理内で、
管理下の装置が発行している要求の有無を検査しなければならないと言うことだけ。
要求していれば処理するし、していなければ何もせず割り込み処理を抜ければ良い。
ただそれだけ。
割り込み制御側のリセット(EOI)とかは、エッジセンスの時と変わりません。
最後に一回行えば良いわけです。各割り込み処理内で行ってはいけません。
むろんの事ですが、PCI対応BIOS非搭載であったり、PCI対応BIOSの設定してくれた内容
を替えたい場合は、あれやこれやとせねばならんのですが、全部お任せにしてしまえば、
後は謎の回路が始末してくれているみたいです。互換機の互換度ってすげ〜。
ちなみに、I/O APIC?難しそうなので使っていません。
堅い円盤
「HDD起動」をはりぼてOS(拙作版)用にでっち上げてみました。
ゴールはさらに遠くなり(新たな問題が・・)、山は増える一方ですが、なんとか起動できるようになりました。
- 実機にいきなりは無謀だろう
実機のハードディスクに書き込める度胸はありませんので、まずは仮想ディスクから。
ではどの型式にするかなのですが、Windows7機能として作成できるし、Virtual Boxでも使えるし、
QEMUでも(今の所)問題なく取り扱えたので、VHD型式に決定。
- [GB]サイズの取扱い。
家のハードディスクには、そんな容量余裕はないので却下。32[MB]で十分。
拡張bios呼ぶのも面倒だから嫌。
- さて、ひとまず32[MB]でも
とりあえず調査目的で総量32[MB]のディスクを<FAT>で作成してみました。
基本区画を8[MB]毎に3区画。
自動的にFAT12になったMBRの区画情報の中身は次のようになっていました。
00000000| 00 02
00000010| 03 00 01 07 06 01 80 00-00 00 00 40 00 00 00 07
00000020| 07 01 01 0C 0A 02 80 40-00 00 00 40 00 00 00 0C
00000030| 0B 02 01 11 0E 03 80 80-00 00 00 40 00 00 00 00
00000040| 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA
詳細は別に譲るとして、最初の区画が3Fhセクターではなく、80hセクター目になっていました。
- 第2区画を起動ディスクに割り当ててみる
00000000| 00 02
00000010| 03 00 01 07 06 01 80 00-00 00 00 40 00 00 80 07
00000020| 07 01 01 0C 0A 02 80 40-00 00 00 40 00 00 00 0C
00000030| 0B 02 01 11 0E 03 80 80-00 00 00 40 00 00 00 00
00000040| 00 00 00 00 00 00 00 00-00 00 00 00 00 00 55 AA
はい、ちゃんと起動フラグが立ちました。
あ、何も指定しなくても勝手にIPLを書き込んでくれるのね。
そのBPBは、次のようになっていました。
00000000| EB 3C 90 4D 53 44 4F 53-35 2E 30 00 02 04 08 00
00000010| 02 00 02 00 40 F8 0C 00-3F 00 FF 00 80 40 00 00
00000020| 00 00 00 00 80 00 29 A6-4F 4B 96 4E 4F 20 4E 41
00000030| 4D 45 20 20 20 20 46 41-54 31 32 20 20 20
ヘッドが255個もあるって言ってますね、大丈夫だろうか。
知りたかったのは、+1Ch目の値。当該IPLがどのセクターに存在するのか。
どうやって、IPLが知るんだろうと思っていたのですが、「隠しセクター項目」がそれっぽい。
- MS-DOS6.2で[format /s]
なんとなく255ヘッドが気になったので、MS-DOS6.2でFDISK。
今度は区画を32[MB]一つとしてFAT16で作成。
そうすると、区画のBPBは次のようになりました。
00000000| EB 3C 90 4D 53 44 4F 53-35 2E 30 00 02 01 02 00
00000010| 02 00 02 00 E8 F8 E7 00-3F 00 10 00 80 00 00 00
00000020| 00 00 00 00 80 00 29 FB-11 32 35 48 41 52 49 42
00000030| 4F 54 45 20 20 20 46 41-54 31 36 20 20 20
こっちは、10h面って言っていますね。
- 全部作るの?VHD
いきなりは無謀だろうと言う事で、原本を作っておいて、コピーして上書きする事に。
まぁ、そのうちVHDフッターとMBRを作って・・・・いつになるかな。
- さぁ起動だ!
MBRはコピー物。IPLもセクターが判ればなんとかなる。
という事で作ってみました。
; --------------------------------------------------
; HDD用IPLの掲載は終了します・・長いので(2012.6)
; --------------------------------------------------
- ヘッドの数について
やっぱり、ヘッドが255個もあると読めないみたいです。
あっさりエラーになってくれました。
いつもより速く動く堅い円盤(仮)
長年の目標であった、ハードディスクのDMA読み書き化にようやく到達。
同時に不具合やら、問題やらがチョモランマ。どうすべ。
- 用意するもの
- 1.PCIバスコンフィギュレーションを読み出せるコード(書いて下さい)。
- 2.PIOで読み書きできるハードディスクドライバコード(書いて下さい)。
- 3.できればFDCのDMA処理ができていると良い。
- DMA処理手順は、FDもATAも変わりません。仕組みが同じなので当たり前ですけど。
- ATAの解説では少し不明だった分
- PCIコンフィグレーション
- インテルさん家からPII-X4の仕様書を拾って来て下さい。デバイスIDとか、PCIレジスタの内容とかが記述されています。
QEMUの場合は、PII-X3みたいです。
「IDE Controller IO Space Registers」と言う項目辺りにPCIレジスタの内容が書かれています。
- 大まかな手順
- 1.PCIレジスタアドレスの取得
- PCIコンフィグレーションを検索して、(0x8086/0x7111)のデバイスを探します(PII-X4の場合)。
そのI/O空間アドレスを取り出します。
- 2.IDENTIFY DEVICE命令を発行して諸元を求めます。
- シリンダ数やらLBA数やらと、53語目の内容を取得して、88語目が有効かどうかを判断します。
88語目の上位バイトが0ですと、たぶんUDMAは使えない装置です。あきらめましょう。
- 3.UDMA処理について
- 「SET FEATURES」命令を使います。
レジスタ | バイト |
Feature | 0x03 |
Sector Count | 0x40 + 転送モード番号 |
Sector Number | 0x00 |
Cylinder Low | 0x00 |
Cylinder High | 0x00 |
Device/Head | 0xa0 |
Command | 0xef |
Sector Countレジスタへの0x40がUDMA指定で、次に続くRead/Write命令がUDMA転送である事を指示します。
「転送モード番号」はUDMA-6が6で、以下UDMA-0の0までを番号で指定します。
「Device/Head」のビット4は、デバイス選択ですが、今は使っていません。
転送処理が終了したら、Sector Countを0にした同命令を送ってPIOに戻しておきます。
- 4.処理手順です
あ、その前にチップセット仕様書で用語を調べて下さい。
PRD(Physical Region Descriptor), BMICx, BMISx, BMIDx(xは、[P:プライマリ][S:セカンダリ]が入る)とかです。
- PRDテーブルの掟
(1)PRDテーブルの先頭番地は4バイト境界でなければならない。
(2)PRDテーブルは、64[KB]境界をまたいで配置できない。
(3)転送先の先頭番地は偶数で、転送長も偶数バイトである事.
最初の4バイトが転送先の番地で、次の4バイト中下位2バイトが転送長です。
必要ならいくつか要素を持つことができます。
最後の要素の最上位ビットを1にすると、テーブルの最後となります。
- UDMA転送設定を行う
BMIDxへPRDテーブル番地を設定する。
BMICxへDMA転送方向を設定する。
BMISxのエラー[1]と割り込みビット[2]を落とす(1を書き込む)。
- ATAデバイスの転送方式設定
最初の「SET FEATURES」命令を送ります。
ステータスを見て、完了を判断します。
- 転送命令設定
read(0xc8)/write(0xca)を、セクター情報と共に書き込みます。
コマンドコード以外は、PIOの時と同じです。
- バスマスター転送開始
BMICxレジスタのビット0にstartをセットします。
- 完了割り込み
プライマリの場合は、割り込み14番に来ます。通常のエッジトリガ処理で対処できます。
BMISxエラービット[1]が立っていなければ、正常終了しています。
- 後始末
BMICxのstartビットを落とします。
「SET FEATURES」命令でPIOに戻しておきます。
ステータスを見て、完了を判断します。
- 5.忘れ物
- Device Controlレジスタ (8bit, W, 0x03f6)
bit1:nIEN 1のとき、両方のデバイスについてINTをマスク(割り込みが発生しない)
- 0x00を書き込んでおくこと。すっかり忘れて大停滞していたのは内緒です。ここ試験に出ます。
GDBと繋いで幸せにな・・れるのか?(2012.06)
拙宅環境では、過去何度試みても入らなかった「eclipse」とやらがなぜかあっさり入ってしまった(3.7版)。
調子に乗ってついでにGDBとやらを調べてみたら、どうもスタブ言うのが必要らしい。
仕方がないので、でっち上げました。→ 「http://www6.shizuokanet.ne.jp/ytakano/software/src/Haribote/haribote27f_gdb01.zip」
>gdb
GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "mingw32". ...使用中のGDBは、mingwのオマケ。
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) set remotebaud 115200 ...通信速度を115200にする命令らしいです。
(gdb) target remote com2 ...com2で通信します。
Remote debugging using com2
0x00006604 in ?? () ...break関数コールで止まるとこんな感じ。
(gdb) x/30i 0x280024 ...逆アセンブルしてみました。
0x280024: push %ebp
0x280025: mov %esp,%ebp
0x280027: push %edi
0x280028: push %esi
0x280029: push %ebx
0x28002a: lea -0x5c(%ebp),%ebx
0x28002d: sub $0x454,%esp
0x280033: movl $0xffffffff,-0x420(%ebp)
0x28003d: movl $0x0,-0x424(%ebp)
0x280047: movl $0x7fffffff,-0x428(%ebp)
0x280051: movl $0x0,-0x42c(%ebp)
・・
0x2800bf: push $0x0
0x2800c1: push %eax
0x2800c2: push $0x80
0x2800c7: push %ebx
(gdb) x/10b 0x280000 ...メモリー内容を参照してみました。
0x280000: 0x00 0x70 0x31 0x00 0x48 0x61 0x72 0x69
0x280008: 0x00 0x00
(gdb) b *0x2803e6 ...停止点設置
Breakpoint 7 at 0x2803e6
(gdb) c ...実行継続
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x000003e7 in ?? ()
(gdb) ...おぉ!なんか動いている
えぇ、これ以外はまだ未検証なんですよ。はっはっは。
ついでに、上記はVirtualBoxのゲストOSである[WindowsXP]上のコマンドプロンプトで取得したものです。
拙宅環境では、「Haribote27f」も同様にVirtualBoxのゲストOSとして動かしています。
- 大まかな手順
- 1.「http://www.gnu.org/software/gdb/」の辺りからGDBを拾って来ましょう
- 本体を再構築するわけではないので、展開したファイル群から必要なのは、
スタブ見本である「<展開先>\gdb\i386-stub.c」だけです。再構築をする場合は、適宜実施して下さい。
- 2.スタブ見本をHaribote用に修正します(修正後のはzipの中に入っています。許諾に注意して下さい)。
- 3.シリアル通信処理を記述します。「8250」か、「uart 16650」とかで検索してみて下さい。
割り込みは未使用ですので、フラグ類だけを参照すれば良いかと思います。
- 「haribote27f_gdb.zip」について
- 1.開発環境は、書籍付属のものそのままです。
- 2.書籍付属CDの「haribote27f」をハードディスク等にコピーします。
- 3.「haribote27f_gdb.zip」を適当な所へ展開したら、そのままフォルダー名に注意しながら、
2.でコピーした「はりぼてOS」に上書きすればなんとかなると思います。
- 4.QEMUでは試していません。「make full」でイメージを作成したら、VirtualBoxのフロッピーに登録して起動して下さい。
- 5.途中で止まります(bootpack.cにbreak関数記述があります)。
- 6.gdbから接続できたら、あとはよしなに。
枯れ木も山の賑わい(13.01)
枯れ木も山の賑わい(13.06)
にぎやかし其の2。!NET はりぼてフレームワーク
枯れ木も山の賑わい(14.05) ACPIシャットダウン・・だけ
枯れ木も山の賑わい(14.05) Haribote Precision Event Timer
- 前回の続きで、賑やかしに。以下は「30_day/harib27f」を元にしています。
タイマーを「HPET」で動かしたいじゃん(要VirtualBox)。
と言う事で「はりぼてタイマー」
- 仮想環境は「Windows + VirtualBox」です。実機検証はありません。Linuxの事は存知ません。
- 「はりぼて・プレシジョン・イベント・タイマー」について
ソースはここから→「http://www6.shizuokanet.ne.jp/ytakano/software/src/Haribote/harib27f_hpet_src.zip」
イメージはこの辺→「http://www6.shizuokanet.ne.jp/ytakano/software/bin/Haribote/harib27f_hpet_bin.zip」
デバッグ用の表示は整理してありませんので、よしなに。
- 割り込みが来るまで
- 「software-developers-hpet<検索↓>」
インテルさん家に「software-developers-hpet-spec-1-0a.pdf(14.05現在)」(参1)が落ちていると思われますので、拾って来ます。
- ACPIさん家(http://www.acpi.info/)から最新の仕様書(参2)を拾って来ます。
- コマンドプロンプトで「VBoxManage modifyvm 仮想名 --hpet on」を実行しておく事。
これをしておかないと、RSDT内にHPET項目が現れてくれません。
- HPETはメモリ−マップドらしいので、BIOSのメモリーマップ→RSDT→HPETテーブルと探し出します。
- 見つけ方は、(参2)§5.2.5.1にあります。自分で探せって事らしいです。
(参2)§15.1にはBIOSコールで取得する方法があります。こちらはシステムのメモリーマップが返されます。
ソースでは、asmhead.nasに関数があります。リアルモードにいる間に取得しちまえって事で。
得られるマップからACPIが使用している領域((参2)Table 15-270 Address Range Types)を選び、
そこにある"HPET"で始まるテーブルを探します。
書式は、「(参1)3.2.4 The ACPI 2.0 HPET Description Table (HPET)」にあって、
その内のBASE_ADDRESSの中身は、
「(参2)5.2.3.1 Generic Address Structure」にありまして、それのAddress項目の内容(下位32bit)がI/Oアドレスです。
- (参1)§2.3辺りにレジスタの説明があります。旧PITを代替して割り込みを入れられるとあります。
- これに従ってレジスタを設定すれば割り込みが入る・・はず。
なんですが、動いた物はなぜか仕様書と違っていたりするんですけど、なぜかな?
枯れ木も山の賑わい(14.11) LWIP再び。「!net」は、「.net」の夢を見る。
枯れ木も山の賑わい(14.12) 頁(ing無し)
毎度、枯れ木屋でございます。
枯れ木も山の賑わい(15.02) はりぼてさんは音無ぃ(SB-16)
毎度、枯れ木屋でございます。
枯れ木も山の賑わい(15.03) DynamicにLinkしてくれないLoader
毎度、枯れ木屋でございます。
枯れ木も山の賑わい(15.05) 好きに作って仲良く使おうAPI
毎度、枯れ木屋でございます。
- 仮想環境は「Windows.7 + VirtualBox」です。実機検証はありませんし、Linux(mac)の事は存知ません。
前回の続きではありませんので、注意して下さい。
- アプリケーションプログラムインターフェース
書籍ではAPIに「INT命令」を使っていますし、最近のx86ではなんやら便利な命令が用意されているようです。
INT命令の場合ですと固定番号になってしまい、動的呼び出しにするのは容易ではありません。
固定番号によるシステム機能の呼び出しを統一するには、談合が必要となります(たぶん)。
それは面倒で、時間がかかります。そこで各自が好きに作って持ち寄って、みんなで仲良く使いましょと言うのが今回の目的。
- さてどうしましょ
コールゲートを試してみましょう。
- 何それ
セグメントと、特権を超えられるcall命令の事で、こんな感じになっています。
15 14 13 1 11 08 07 06 05 04 00
┌─────────────────────────┐
+00 | セグメント内オフセット[15 - 00] | 実行関数低位番地
├─────────────────────────┤
+02 | セグメントセレクタ | はりぼてOSコードセグメント(2 * 8)
├─┬──┬─┬────┬─┬─┬─┬───────┤
+04 |P |DPL |S | 種類 |0 |0 |0 | 引数個数 |
├─┴──┴─┴────┴─┴─┴─┴───────┤
+06 | セグメント内オフセット[31 - 16] | 実行関数高位番地
└─────────────────────────┘
P : 1:セグメントがメモリ上に存在することを表す。
: 0:不在
S : 0
DPL : 呼び出し側の特権階層(ユーザーなので0x60です)
種類 : 1100b = 32bitコールゲート
引数個数: 32bit単位の引数個数を5ビットで指定する
割り込みゲートみたいですね、まぁ同じだし。
これをLDTに入れて、「call far LDT番号:0」とすると、はりぼてOS側の処理を呼び出してくれます。
- 具体的にはどうするの
API仲介処理はアセンブラ記述で、その先頭は次のようになっています
添付ソースでは「haribote/subsys/cg/asmtomo.nas」にあります。
_API関数:
jmp short 本処理 ; + 00
dw 0x0001 ; + 02 major=0 minor=1(未使用です)
dw 0x0000 ; + 04 予備
db "haribote tomo api", 0 ; + 06 任意長の識別文字列
align 4 ; 境界整合
本処理:
適当に記述した文字列でAPI処理を識別して一覧を作っておき、アプリケーションが同じ文字列で照会してきたら
そのタスクにあるLDTにゲートを構築し、番号を返すだけです。
アプリケーションは、その番号を頼りにcall farする訳です。めでたし。
- 処理速度は?
ごちゃごちゃやっている割にはINT方式とさして変わりはないようです。
tomoフォルダーのtomoコマンドで試して見て下さい。
- 防犯対策は取れていますか?
まるで考えていません。いいんです。世の中良い人ばかりです。そういう事にしておきます。
- 持ち寄ったときの機能重複は?
さぁ存じません。検出もできません。基本は放置です。
- と言う事で
fd形式は→この辺
ソースは→こちら
注)既に「harib27f」がある場合、上書きには気をつけて下さい。
- いつものお約束で、動かない場合はすっぱりあきらめて下さい。ついでにいろいろゴミが混ざっています。
- 開発環境は、書籍付属のものそのままです。projectsと同じ階層にz_toolsを置いて下さい。
- 環境設定は、お手元の環境に合わせて下さい。
コメント欄
- 謎の新回路はチップセット内に存在し、IRQ番号ごとにレベルにするかエッジにするかを選択できます。しかし実際の設定方法は僕にも分かっていません。 -- K 2009-09-24 (木) 01:56:04
- PCIデバイスは今自分がIRQ要求を出しているかどうかを検出する方法が必ず用意されています(ステータスのビットなどで)。したがって、割り込みが起きた場合は、それをすべてチェックして、割り込みを起こしたデバイスがどれなのか調べます。複数あるかもしれないので、一つ見つけたからといって安心しないで最後までチェックします。見つけ次第割り込み処理をしていって、IRQ要求を下げさせていきます。全部終わったらPICに終了コードを送ります。 -- K 2009-09-24 (木) 01:59:00
- あらま、これは初めまして。ν8259の外付けレジスタですが(0x4d0-4d1)、PCI-BIOSを作るでもしない限りは超法規的措置で良いと思われます。PCI機器に資源を割り当てる際に、空いている割込番号にレベル用のビットを立てているだけみたいです。実際は互換を維持するために結構面倒な事をしているのでしょうが、中の素子さんは見えませんから、問題が出るまで気にしない事にしました。 -- ytakano 2009-09-24 (木)
- 相変わらず、面白そうなことをやっていますねー。どうもありがとうございます! -- K 2012-03-28 (水) 11:25:28
- すごい・・・ -- K 2014-07-18 (金) 20:12:30
- すげぇ...... -- 名無しさん 2020-08-01 (土) 09:32:07