advance/hddboot
の編集
http://hrb.osask.jp/wiki/?advance/hddboot
[
リロード
|
差分
|
単語検索
|
一覧
] [
編集
|
バックアップ
|
添付
]
-- 雛形とするページ --
A
Akkie
Athlon64X2
Clover
DAsoran
Falcon
FormatRule
FrontPage
Genesis
Help
I
InterWikiName
InterWikiSandBox
InterWikiテクニカル
Jormungand
K
Kebo
Kor_Lee_Hee_Rak
Leaf
Linux
Linux/wako_memo
MOIZ99
MW
MenuBar
OSC
PG_MANA
ReadersOS
RecentDeleted
SKYDASH
SandBox
Sero
Sigle
Source
Triangle_Ld.
Zxcvbnm
advance
advance/CPU
advance/FDC
advance/FPU
advance/NotHariMain
advance/QEMUVGA
advance/RTC
advance/blike
advance/cpu_reset
advance/driver
advance/driver/01
advance/driver/02
advance/families
advance/filesystem
advance/fwrite
advance/hddboot
advance/he86
advance/hints
advance/ipl
advance/kernel
advance/keycode
advance/osselect
advance/smaller1
advance/startup
advnace/smaller2
anzy
aotatsu
banbi-
bluedwarf
bo
bugs
challengers
cybozulabsyouth11
deskmanta
esb02b
faq
faq/advance
faq/asm
faq/c00-03
faq/c04-07
faq/c08-15
faq/c16-23
faq/c24-31
faq/make
faq/others
faq/qemu
guide
guide03
guide05
guide07
hikarupsp
imp_log/0000
imp_log/0001
imp_log/0002
imp_log/0003
impressions
index
k
killer_elf
kota
lea
lea/10_memory
lea/4_color
lea/idea
lea/terms
links
logs
logs/osa_hrb/comments0000
logs/osa_hrb/rumors0000
masa
members
message
mistakes
moge32
moppoi5168
notice
osdevjp
populars
prog_index
projects
q_and_a
q_and_a_2
qa_log/0000
qa_log/0001
qa_log/0002
qa_log/0003
qa_log/0004
qa_log/0005
qa_log/0006
qa_log/0007
qa_log/0008
qa_log/0009
quark
rankings
rule
sakamoto
sasaki
spc09
spcc_30min_os
tatsu
tools
tools/bim2hrb
tools/bin2obj
tools/cc1
tools/edimg
tools/gas2nask
tools/makefont
tools/nask
tools/obj2bim
tools/sjisconv
uchan
uho
updates
violations
wako
white
win64-bit
x
ytakano
ヘルプ
リックス
質問します
整形ルール
本は買ったぞ!持ってるぞ!
練習用ページ
* HDD系デバイスから起動しよう -(by [[K]], 2009.04.01) -発展課題のページ(全部読む前にここを読むのは混乱するのでおすすめじゃないです) ---- -原理的にはここで紹介する方法で、内蔵・外付けHDD、USBメモリ、USB接続のカードリーダ、(最近のパソコンによく付いている)メモリカード端子などから起動できます。これらはBIOSからは同じように扱われているためです。ただしこの通りの対応ではない機種も存在し、その場合はこの方法ではうまく行かないかもしれません。 *** 注意 -COLOR(#FF0000){このページは未完成で、ツール群も準備できていないままです。このページは参考のために残しますが、質問は一切受け付けません。すみません。} *** まえがき -筆者は先日、ASUSのEeePC-900-XというネットブックPCを買いました。それでいろいろ遊んでいるうちに、このパソコンでも「はりぼてOS」で遊んでみたいと思いました。もちろんUSB-FDDをつければ起動はしますが、当然ながらかなり時間がかかります。またUSB-CDドライブをつければCDから起動もできますが、そういうかさばるものをつけるのはなんか気乗りがしません。・・・そしてこのPCにはSDカードスロットが標準で付いています。だからここにSDを入れて、そのSDから「はりぼてOS」が起動したらかっこいいだろうなあと思いました。ということで数日ほど試行錯誤したら結構簡単にできるようになったので、紹介しようと思います。 --ちなみに電源ボタンを押してから11秒で起動するようになりました。WindowsXPの3倍は速いです(笑)。 *** 方法 -普通HDD系デバイスにOSをインストールさせるには、以下の手順を踏みます。 --パーティションを準備して、そこから起動できるように設定する。 --パーティションのフォーマットを考える。 --パーティションの中にどうにかしてOSに必要なファイルを書き込む。 --パーティションがHDD内のどこに確保されるのかを前もって決めておくことはできないので(強引に決めておくこともできるけど、そうするとそのHDDを他のOSと共存させるのは難しくなる)、IPL等のプログラムは複雑になる。もしくはインストーラが複雑になる。 -はっきりいって、これは全部面倒です。いきなりこういうのをやると理解できなくなるのは間違いないので、最初は簡単な構成を考えようと思います。最近すっかり安くなったUSBメモリやSDカードなどは、実はHDDと同じフォーマットをすることになっています。だからこれらを「容量が小さくて、万一失敗しても大損害にはならずに済んで、しかもパーティションが一つしかない(=パーティションで悩む必要のない)特別なHDD」だと思うことにしましょう。 -FDからの起動を思い出してほしいのですが、結局CYLSは最大でも33くらいにしかできませんでした。つまりどんなに容量があっても当面は600KBくらいしか利用できないのです(将来的にはこの問題もクリアするとしても)。だから4GBとか32GBとかそんな大容量のものは全くいりません(とりあえず2MBくらいあれば十分です)。アクセススピードもBIOSを経由して起動する今回の方法では、あまり速くはならないみたいです(これも将来的には解決するかもしれないけど)。だからとにかく安物を準備しましょう。いきなりいいものを買ってきて失敗したらどうしますか。まずは練習用・実験用にできるだけ安いものを使いましょう。 -以下ではUSBメモリとして書きますが、実際はどのデバイスでも同じです。 -ちなみにSDカードなどを扱う場合にカードリーダを買うことがあるかもしれません。その場合カードリーダは端子がたくさんある30in1みたいなタイプよりは、端子が一つしかなくてせいぜい2〜3種類くらいのメモリカードにしか対応していないようなカードリーダのほうが、今回の目的に限っては扱いやすいです(複数の端子を制御するタイプは、BIOSも扱いに苦労して、うまく行かないものがあったので・・・筆者の経験でしかないですが)。 ---- -USBメモリにはたいていFAT16かFAT32のフォーマットがかかっています。そしてここにOSやアプリケーションのファイルをポンポンいれておいて、あとはIPLががんばってそれらのファイルを見つけ出して起動するというのが普通です。しかしこれはとんでもなく大変です。IPLは基本的にはアセンブラで書かないといけないですし、しかも512バイトしかありません。そんな容量でFAT16かFAT32かも分からないフォーマットを自動判別し、クラスタサイズも512とは限らないので自動で判別するようなものを書けるでしょうか。いやまあ普通のOSではそれを何とかしてやっているわけですが、それは「入門」レベルをはるかに超えています。説明だけでやる気がなくなること請け合いです。 -ということで、今回はもっと簡単な方法を考えました。まず今までどおりの方法でFD用のディスクイメージを作ります(余談ですがFDは容量が1440KBと決まっているので、説明するのがとても簡単だったのです)。そしてその1440KBのファイルを、たとえば64MBのUSBメモリがあったとして、その中にコピーします。これはimgtolとかを使うことなく、普通にコピーしてかまいません。・・・というのは、FDドライブであるA:に対してimgtolを使うことはできるのですが、それ以外のドライブに対してimgtolやその他のディスクイメージツールを使おうとすると、Windowsがエラーを出して妨害してしまうのです。だから結局入門用としては普通のファイルコピーをするしかない、というのが筆者の結論なのです。 -これでとにかくUSBメモリのどこかにFDのときと同じ1440KBが書き込まれたはずです。あとはIPLでこの1440KBの先頭だけを探し出して、そしてその中を今までと同じ方法で読めばいいわけです。やったー、頭いい! --とまあそういう方法なので、この1440KBが連続したセクタに並んでいないと困ります。ファイルを書いたり消去したりを繰り返した状態だと、ファイルの断片化というのがおきて、もしかしたら1440KBが連続したセクタに書かれていないかもしれません(飛び飛びになっていて、どこに続きがあるのかはFATをたどらないと分からない)。そういうのは困ります。これを防ぐ一番簡単な方法は、一度USBメモリをフォーマットしなおすことです。これで全部のファイルが消えるので、ここに1440KBのファイルをコピーすれば、もちろんファイル領域の先頭から連続してきれいに書かれます。 --とにかくこの1440KBさえ連続していればいいので、このファイルをコピーした後は、残った容量を好きなことに使ってかまいません。64MBのUSBメモリなら60MBくらいは残るでしょうから、そこに好きなファイルを入れてもいいわけです。 ---- -さて1440KBの先頭を探し出す方法ですが、これもものすごく簡単な方法を取ります。・・・普通は、MBRのパーティションテーブルがどうのこうので、そこからパーティションを見つけて、そして今度はそのパーティションのフォーマットがどうなっているか調べて、ファイル名情報がどこにあるかを探して・・・みたいな話になるのですが、こんなのができるのなら、今回の入門仕様にする必要が無いじゃないですか。 -そうじゃなくて、1440KBの中に見つけやすい(そして誤解しにくい)シグネチャを書いておいて、USBメモリの中からそのシグネチャを探すんです。これはもちろんそれなりに時間がかかります。10秒とか20秒とかかかるかもしれません。でもその代わり、将来USBメモリがどんなフォーマットになってもこの手法は有効です。毎回起動するたびに探すのは起動時間がもったいないので、ディスク内でのFDイメージの位置が変わったときにだけやることにしましょう。だから起動時には探しません。探しておいた場所をいきなり読むのです。 --余談ですが、筆者はかつてこれとは違うアプローチを試みたことがあります。つまりUSBメモリのフォーマットがFAT12だったりFAT16だったりFAT32だったりしたのに腹を立てて、単純で統一的な一種類のフォーマットにそろえようとしたのです(SF16という名前にしました)。そうすればこの中にファイルを置いてもFDのときのように比較的簡単にアクセスできるわけです。・・・これはうまく行きましたが、今回の方法よりは複雑なので、ここではやっていません。 *** MBRのプログラム -USBメモリの場合、シリンダ番号0、ヘッド番号0、セクタ番号1のセクタのことを、ブートセクタとは言いません。IPLとも言いません。MBR(マスターブートレコード)といいます。なぜこんな風に言うのか、それは今は気にしないことにします。そして言い方は違うものの、結局この部分が起動時に0x7c00番地に読み込まれるということに変わりはありません。 -MBRの場合も0x7dfeに 55 aa があります(これがないと起動しない)。しかもその上、0x7dbeから0x7dfdまでも使用禁止です。ここにはパーティション情報が書かれるためです。その代わり、FAT12とかディスクの名前とかを書かなくていいので、最初にジャンプ命令を書く必要はありません。いきなりプログラムを書けます。 -また以下のプログラムでは、USBメモリを読み込むときに、シリンダやヘッド番号などを指定してはいません。基本的にFDDと同じようにもできるのですが、それをやるにはBIOSに最大シリンダ番号や最大ヘッド番号などを問い合わせなければいけません(USBメモリにはそもそもシリンダもヘッドもないのですが)。どうしてかというと、容量や製造会社によって、総シリンダ数などが違うせいです(FDDのときは80シリンダ・2ヘッド・18セクタと決まっていたのでとても簡単でした)。そしてどうにかして最大シリンダやなどを取得したとしても、実はその方法でアクセスできるのはUSBメモリの先頭から8GBまでで、残りの領域にはアクセスできません。・・・そこでこのプログラムではFDDの時とは異なるBIOSの機能番号を使ってアクセスしています。これはシリンダやヘッドは全部無視して、先頭から何番目かのセクタなのかだけを指定します。これをLBA(ロジカルブロックアドレス)方式といいます。この方法の場合、8796093022208GBまで指定できます。 --参考: OS-wikiのINT(0x13);のAH=0x42; [INSTRSET "i486p"] ORG 0x7c00 STI ; BIOSがSTIし忘れていても大丈夫なために ; MBR全体を0x0600〜0x07ffへコピー MOV AX,0 MOV SS,AX MOV SP,0x7c00 MOV DS,AX MOV SI,SP MOV DI,0x600 MOV CX,512/2 copyloop: MOV AX,[SI] ADD SI,2 MOV [DI],AX ADD DI,2 SUB CX,1 JNZ copyloop JMP 0x0060:0x0027 ; コピーが終わったら、コピー先へジャンプ(0x0629) ORG 0x0027 ; LBA方式が使えるかどうかの確認 PUSH CS POP DS PUSH CS POP ES MOV [drv],DL ; 起動ドライブ番号がDLに入っている(BIOSがDLに入れてからMBRを起動するので) CMP DL,0x80 JB error ; HDD系デバイスでなければエラー MOV AH,0x41 MOV BX,0x55aa INT 0x13 JC error CMP BX,0xaa55 JNE error TEST CL,0x01 JZ error ; あらかじめ探しておいたIPLを読み込んで実行 MOV SP,0x0640 MOV DI,load_LBA MOV CX,[load_secs] MOV BX,[load_addr] CALL 0x60:0x01b0 JC error1 JMP FAR WORD [farjmp_vector] error: MOV SI,msg putloop: MOV AL,[SI] ADD SI,1 CMP AL,0 JZ fin MOV AH,0x0e MOV BX,15 INT 0x10 ; putc JMP putloop fin: HLT JMP fin error1: MOV SI,msg1 JMP putloop read_LBA: ; [ES:DI]からの8バイトに相対LBA, CXにセクタ数, BXにセグメント PUSH DS PUSHAD MOV AX,0x4200 rw_LBA: PUSH CS POP DS MOV SI,param MOV [SI+6],BX MOV EBP,[ES:DI+0] MOV EDX,[ES:DI+4] ADD EBP,[LBA0+0] ADC EDX,[LBA0+4] ; ADCは直前の計算の繰り上がりも含めて足す命令 MOV [SI+8],EBP MOV [SI+12],EDX .readloop: MOV DL,[drv] PUSH CX PUSH AX INT 0x13 POP AX POP CX JC .error ADD WORD [SI+6],0x20 ADD DWORD [SI+8],1 ADC DWORD [SI+12],0 SUB CX,1 ; CF == 0 JNZ .readloop .error: POPAD POP DS RETF write_LBA: ; [ES:DI]からの8バイトに相対LBA, CXにセクタ数, BXにセグメント PUSH DS PUSHAD MOV AX,0x4300 JMP rw_LBA drv: DB 0x80 msg: DB "ExtINT13H not ready",0x0d,0x0a,0 msg1: DB "Load error",0x0d,0x0a,0 RESB 0x0188-$ load_secs: DW 0 ; IPLのセクタ数(1より大きくてもよい、pcctolで自動設定) load_addr: DW 0 ; IPLのロード番地(0x07c0以外でもよい、ppctolで自動設定) farjmp_vector: DW 0,0 ; IPLの実行開始位置(0:0x7c00以外でもよい、pcctolで自動設定) param: DW 0x10,1,0,0 DD 0,0 load_LBA: DD 0,0 ; IPLの相対LBA(0以外でもよい、pcctolで自動設定) LBA0: DD 0,0 ; ディスクイメージ開始のLBA(pcctolで自動設定) RESB 0x01b0-$ JMP read_LBA RESB 0x01b4-$ JMP write_LBA RESB 0x01b8-$ DB "KHBH",0,0 -説明: -このMBRではIPLがディスクイメージの先頭から始まっているとは決めていません。ディスクイメージのどこから始まっていてもいいのです。またIPLが512バイト(1セクタ)だとも決めていません。5KB(10セクタ)でも50KB(100セクタ)でもいいのです。読み込む番地も0x7c00とは決めていません。どこだっていいのです。 -なんでこうしたのかといえば、IPLが512バイト以下でなければいけないとか、先頭に書かなくてはいけないとか、0x7c00に読み込まれるとか決まっているせいで、OSを書くのが大変になったからです(みなさんもそう思いますよね?ね?)。IBMのおじさん(おばさん?)たちが勝手に決めた不便なルールを引き継ぐ必要はないわけです。だから自由にできるようにしました。 -最初にMBRを0x0600〜0x07ffへ転送しているのは、0x00800〜0x9ffffを全部あきにするためです。こうすれば、きっとOSは使いやすいでしょう。 -(つづく:個人的に忙しいので続きは数週間後?) *** 関連リンク -このページを作るまでの試行錯誤: --http://wiki.osask.jp/?KHBIOS.memo001 --試行錯誤を見たらかえって混乱するかもしれないので、お勧めはしません。 --とりあえず「はりぼてOS」とOSAkkieの起動には完全に成功しています(起動だけではなく、アプリももちろん使えています。2009.04.01時点で)。 * こめんと欄 -USB メモリーは起動が可能なことではなければならないし, BIOS 設定を別にすると起動が可能だと聞いたが他の方法でも USB メモリーに起動することができるんですか? -- ''Kor_Lee_Hee_Rak'' SIZE(10){2009-04-03 (金) 23:58:54} -できるかどうかは試してみないと分かりません。 -- [[K]] SIZE(10){2009-04-05 (日) 00:16:10} -pcctolってなんですか? -- ''イシハラシュウイチ'' SIZE(10){2018-03-07 (水) 02:27:24} #comment
タイムスタンプを変更しない
* HDD系デバイスから起動しよう -(by [[K]], 2009.04.01) -発展課題のページ(全部読む前にここを読むのは混乱するのでおすすめじゃないです) ---- -原理的にはここで紹介する方法で、内蔵・外付けHDD、USBメモリ、USB接続のカードリーダ、(最近のパソコンによく付いている)メモリカード端子などから起動できます。これらはBIOSからは同じように扱われているためです。ただしこの通りの対応ではない機種も存在し、その場合はこの方法ではうまく行かないかもしれません。 *** 注意 -COLOR(#FF0000){このページは未完成で、ツール群も準備できていないままです。このページは参考のために残しますが、質問は一切受け付けません。すみません。} *** まえがき -筆者は先日、ASUSのEeePC-900-XというネットブックPCを買いました。それでいろいろ遊んでいるうちに、このパソコンでも「はりぼてOS」で遊んでみたいと思いました。もちろんUSB-FDDをつければ起動はしますが、当然ながらかなり時間がかかります。またUSB-CDドライブをつければCDから起動もできますが、そういうかさばるものをつけるのはなんか気乗りがしません。・・・そしてこのPCにはSDカードスロットが標準で付いています。だからここにSDを入れて、そのSDから「はりぼてOS」が起動したらかっこいいだろうなあと思いました。ということで数日ほど試行錯誤したら結構簡単にできるようになったので、紹介しようと思います。 --ちなみに電源ボタンを押してから11秒で起動するようになりました。WindowsXPの3倍は速いです(笑)。 *** 方法 -普通HDD系デバイスにOSをインストールさせるには、以下の手順を踏みます。 --パーティションを準備して、そこから起動できるように設定する。 --パーティションのフォーマットを考える。 --パーティションの中にどうにかしてOSに必要なファイルを書き込む。 --パーティションがHDD内のどこに確保されるのかを前もって決めておくことはできないので(強引に決めておくこともできるけど、そうするとそのHDDを他のOSと共存させるのは難しくなる)、IPL等のプログラムは複雑になる。もしくはインストーラが複雑になる。 -はっきりいって、これは全部面倒です。いきなりこういうのをやると理解できなくなるのは間違いないので、最初は簡単な構成を考えようと思います。最近すっかり安くなったUSBメモリやSDカードなどは、実はHDDと同じフォーマットをすることになっています。だからこれらを「容量が小さくて、万一失敗しても大損害にはならずに済んで、しかもパーティションが一つしかない(=パーティションで悩む必要のない)特別なHDD」だと思うことにしましょう。 -FDからの起動を思い出してほしいのですが、結局CYLSは最大でも33くらいにしかできませんでした。つまりどんなに容量があっても当面は600KBくらいしか利用できないのです(将来的にはこの問題もクリアするとしても)。だから4GBとか32GBとかそんな大容量のものは全くいりません(とりあえず2MBくらいあれば十分です)。アクセススピードもBIOSを経由して起動する今回の方法では、あまり速くはならないみたいです(これも将来的には解決するかもしれないけど)。だからとにかく安物を準備しましょう。いきなりいいものを買ってきて失敗したらどうしますか。まずは練習用・実験用にできるだけ安いものを使いましょう。 -以下ではUSBメモリとして書きますが、実際はどのデバイスでも同じです。 -ちなみにSDカードなどを扱う場合にカードリーダを買うことがあるかもしれません。その場合カードリーダは端子がたくさんある30in1みたいなタイプよりは、端子が一つしかなくてせいぜい2〜3種類くらいのメモリカードにしか対応していないようなカードリーダのほうが、今回の目的に限っては扱いやすいです(複数の端子を制御するタイプは、BIOSも扱いに苦労して、うまく行かないものがあったので・・・筆者の経験でしかないですが)。 ---- -USBメモリにはたいていFAT16かFAT32のフォーマットがかかっています。そしてここにOSやアプリケーションのファイルをポンポンいれておいて、あとはIPLががんばってそれらのファイルを見つけ出して起動するというのが普通です。しかしこれはとんでもなく大変です。IPLは基本的にはアセンブラで書かないといけないですし、しかも512バイトしかありません。そんな容量でFAT16かFAT32かも分からないフォーマットを自動判別し、クラスタサイズも512とは限らないので自動で判別するようなものを書けるでしょうか。いやまあ普通のOSではそれを何とかしてやっているわけですが、それは「入門」レベルをはるかに超えています。説明だけでやる気がなくなること請け合いです。 -ということで、今回はもっと簡単な方法を考えました。まず今までどおりの方法でFD用のディスクイメージを作ります(余談ですがFDは容量が1440KBと決まっているので、説明するのがとても簡単だったのです)。そしてその1440KBのファイルを、たとえば64MBのUSBメモリがあったとして、その中にコピーします。これはimgtolとかを使うことなく、普通にコピーしてかまいません。・・・というのは、FDドライブであるA:に対してimgtolを使うことはできるのですが、それ以外のドライブに対してimgtolやその他のディスクイメージツールを使おうとすると、Windowsがエラーを出して妨害してしまうのです。だから結局入門用としては普通のファイルコピーをするしかない、というのが筆者の結論なのです。 -これでとにかくUSBメモリのどこかにFDのときと同じ1440KBが書き込まれたはずです。あとはIPLでこの1440KBの先頭だけを探し出して、そしてその中を今までと同じ方法で読めばいいわけです。やったー、頭いい! --とまあそういう方法なので、この1440KBが連続したセクタに並んでいないと困ります。ファイルを書いたり消去したりを繰り返した状態だと、ファイルの断片化というのがおきて、もしかしたら1440KBが連続したセクタに書かれていないかもしれません(飛び飛びになっていて、どこに続きがあるのかはFATをたどらないと分からない)。そういうのは困ります。これを防ぐ一番簡単な方法は、一度USBメモリをフォーマットしなおすことです。これで全部のファイルが消えるので、ここに1440KBのファイルをコピーすれば、もちろんファイル領域の先頭から連続してきれいに書かれます。 --とにかくこの1440KBさえ連続していればいいので、このファイルをコピーした後は、残った容量を好きなことに使ってかまいません。64MBのUSBメモリなら60MBくらいは残るでしょうから、そこに好きなファイルを入れてもいいわけです。 ---- -さて1440KBの先頭を探し出す方法ですが、これもものすごく簡単な方法を取ります。・・・普通は、MBRのパーティションテーブルがどうのこうので、そこからパーティションを見つけて、そして今度はそのパーティションのフォーマットがどうなっているか調べて、ファイル名情報がどこにあるかを探して・・・みたいな話になるのですが、こんなのができるのなら、今回の入門仕様にする必要が無いじゃないですか。 -そうじゃなくて、1440KBの中に見つけやすい(そして誤解しにくい)シグネチャを書いておいて、USBメモリの中からそのシグネチャを探すんです。これはもちろんそれなりに時間がかかります。10秒とか20秒とかかかるかもしれません。でもその代わり、将来USBメモリがどんなフォーマットになってもこの手法は有効です。毎回起動するたびに探すのは起動時間がもったいないので、ディスク内でのFDイメージの位置が変わったときにだけやることにしましょう。だから起動時には探しません。探しておいた場所をいきなり読むのです。 --余談ですが、筆者はかつてこれとは違うアプローチを試みたことがあります。つまりUSBメモリのフォーマットがFAT12だったりFAT16だったりFAT32だったりしたのに腹を立てて、単純で統一的な一種類のフォーマットにそろえようとしたのです(SF16という名前にしました)。そうすればこの中にファイルを置いてもFDのときのように比較的簡単にアクセスできるわけです。・・・これはうまく行きましたが、今回の方法よりは複雑なので、ここではやっていません。 *** MBRのプログラム -USBメモリの場合、シリンダ番号0、ヘッド番号0、セクタ番号1のセクタのことを、ブートセクタとは言いません。IPLとも言いません。MBR(マスターブートレコード)といいます。なぜこんな風に言うのか、それは今は気にしないことにします。そして言い方は違うものの、結局この部分が起動時に0x7c00番地に読み込まれるということに変わりはありません。 -MBRの場合も0x7dfeに 55 aa があります(これがないと起動しない)。しかもその上、0x7dbeから0x7dfdまでも使用禁止です。ここにはパーティション情報が書かれるためです。その代わり、FAT12とかディスクの名前とかを書かなくていいので、最初にジャンプ命令を書く必要はありません。いきなりプログラムを書けます。 -また以下のプログラムでは、USBメモリを読み込むときに、シリンダやヘッド番号などを指定してはいません。基本的にFDDと同じようにもできるのですが、それをやるにはBIOSに最大シリンダ番号や最大ヘッド番号などを問い合わせなければいけません(USBメモリにはそもそもシリンダもヘッドもないのですが)。どうしてかというと、容量や製造会社によって、総シリンダ数などが違うせいです(FDDのときは80シリンダ・2ヘッド・18セクタと決まっていたのでとても簡単でした)。そしてどうにかして最大シリンダやなどを取得したとしても、実はその方法でアクセスできるのはUSBメモリの先頭から8GBまでで、残りの領域にはアクセスできません。・・・そこでこのプログラムではFDDの時とは異なるBIOSの機能番号を使ってアクセスしています。これはシリンダやヘッドは全部無視して、先頭から何番目かのセクタなのかだけを指定します。これをLBA(ロジカルブロックアドレス)方式といいます。この方法の場合、8796093022208GBまで指定できます。 --参考: OS-wikiのINT(0x13);のAH=0x42; [INSTRSET "i486p"] ORG 0x7c00 STI ; BIOSがSTIし忘れていても大丈夫なために ; MBR全体を0x0600〜0x07ffへコピー MOV AX,0 MOV SS,AX MOV SP,0x7c00 MOV DS,AX MOV SI,SP MOV DI,0x600 MOV CX,512/2 copyloop: MOV AX,[SI] ADD SI,2 MOV [DI],AX ADD DI,2 SUB CX,1 JNZ copyloop JMP 0x0060:0x0027 ; コピーが終わったら、コピー先へジャンプ(0x0629) ORG 0x0027 ; LBA方式が使えるかどうかの確認 PUSH CS POP DS PUSH CS POP ES MOV [drv],DL ; 起動ドライブ番号がDLに入っている(BIOSがDLに入れてからMBRを起動するので) CMP DL,0x80 JB error ; HDD系デバイスでなければエラー MOV AH,0x41 MOV BX,0x55aa INT 0x13 JC error CMP BX,0xaa55 JNE error TEST CL,0x01 JZ error ; あらかじめ探しておいたIPLを読み込んで実行 MOV SP,0x0640 MOV DI,load_LBA MOV CX,[load_secs] MOV BX,[load_addr] CALL 0x60:0x01b0 JC error1 JMP FAR WORD [farjmp_vector] error: MOV SI,msg putloop: MOV AL,[SI] ADD SI,1 CMP AL,0 JZ fin MOV AH,0x0e MOV BX,15 INT 0x10 ; putc JMP putloop fin: HLT JMP fin error1: MOV SI,msg1 JMP putloop read_LBA: ; [ES:DI]からの8バイトに相対LBA, CXにセクタ数, BXにセグメント PUSH DS PUSHAD MOV AX,0x4200 rw_LBA: PUSH CS POP DS MOV SI,param MOV [SI+6],BX MOV EBP,[ES:DI+0] MOV EDX,[ES:DI+4] ADD EBP,[LBA0+0] ADC EDX,[LBA0+4] ; ADCは直前の計算の繰り上がりも含めて足す命令 MOV [SI+8],EBP MOV [SI+12],EDX .readloop: MOV DL,[drv] PUSH CX PUSH AX INT 0x13 POP AX POP CX JC .error ADD WORD [SI+6],0x20 ADD DWORD [SI+8],1 ADC DWORD [SI+12],0 SUB CX,1 ; CF == 0 JNZ .readloop .error: POPAD POP DS RETF write_LBA: ; [ES:DI]からの8バイトに相対LBA, CXにセクタ数, BXにセグメント PUSH DS PUSHAD MOV AX,0x4300 JMP rw_LBA drv: DB 0x80 msg: DB "ExtINT13H not ready",0x0d,0x0a,0 msg1: DB "Load error",0x0d,0x0a,0 RESB 0x0188-$ load_secs: DW 0 ; IPLのセクタ数(1より大きくてもよい、pcctolで自動設定) load_addr: DW 0 ; IPLのロード番地(0x07c0以外でもよい、ppctolで自動設定) farjmp_vector: DW 0,0 ; IPLの実行開始位置(0:0x7c00以外でもよい、pcctolで自動設定) param: DW 0x10,1,0,0 DD 0,0 load_LBA: DD 0,0 ; IPLの相対LBA(0以外でもよい、pcctolで自動設定) LBA0: DD 0,0 ; ディスクイメージ開始のLBA(pcctolで自動設定) RESB 0x01b0-$ JMP read_LBA RESB 0x01b4-$ JMP write_LBA RESB 0x01b8-$ DB "KHBH",0,0 -説明: -このMBRではIPLがディスクイメージの先頭から始まっているとは決めていません。ディスクイメージのどこから始まっていてもいいのです。またIPLが512バイト(1セクタ)だとも決めていません。5KB(10セクタ)でも50KB(100セクタ)でもいいのです。読み込む番地も0x7c00とは決めていません。どこだっていいのです。 -なんでこうしたのかといえば、IPLが512バイト以下でなければいけないとか、先頭に書かなくてはいけないとか、0x7c00に読み込まれるとか決まっているせいで、OSを書くのが大変になったからです(みなさんもそう思いますよね?ね?)。IBMのおじさん(おばさん?)たちが勝手に決めた不便なルールを引き継ぐ必要はないわけです。だから自由にできるようにしました。 -最初にMBRを0x0600〜0x07ffへ転送しているのは、0x00800〜0x9ffffを全部あきにするためです。こうすれば、きっとOSは使いやすいでしょう。 -(つづく:個人的に忙しいので続きは数週間後?) *** 関連リンク -このページを作るまでの試行錯誤: --http://wiki.osask.jp/?KHBIOS.memo001 --試行錯誤を見たらかえって混乱するかもしれないので、お勧めはしません。 --とりあえず「はりぼてOS」とOSAkkieの起動には完全に成功しています(起動だけではなく、アプリももちろん使えています。2009.04.01時点で)。 * こめんと欄 -USB メモリーは起動が可能なことではなければならないし, BIOS 設定を別にすると起動が可能だと聞いたが他の方法でも USB メモリーに起動することができるんですか? -- ''Kor_Lee_Hee_Rak'' SIZE(10){2009-04-03 (金) 23:58:54} -できるかどうかは試してみないと分かりません。 -- [[K]] SIZE(10){2009-04-05 (日) 00:16:10} -pcctolってなんですか? -- ''イシハラシュウイチ'' SIZE(10){2018-03-07 (水) 02:27:24} #comment
テキスト整形のルールを表示する