30天自制操作系统:第二天
慢慢更新不着急哦,会越来越难,更新也会越来越慢滴。
1.将扇区加载到指定内存中。
在第一天的基础上进行代码的加工,第二天给程序中加入将引导扇区读入指定内存地址:0x7c00处,并使用软中断显示字符。
出现了一个问题,发现0扇区内出现莫名其妙的数据,经过分析,是编译器自己写入的启动数据。
优化后的代码为:
; hello-os; TAB=4ORG0x7c00; このプログラムがどこに読み込まれるのかJMPentryentry:MOVAX,0; 初始化寄存器MOVSS,AXMOVSP,0x7c00MOVDS,AXMOVES,AXMOVSI,msgputloop:MOVAL,[SI]ADDSI,1CMPAL,0JEfinMOVAH,0x0e; ?示一个文字MOVBX,15; 指定字符?色,不知道???色没?, 有知道的大?告?我下。INT0x10; ?用??bios,可以理解??用了一个接口。JMPputloopfin:HLT; ?cpu停止防止cpu空?,等待指令,只要外部?生?化,比如按下??,移?鼠?,cpu就会醒?来???行。JMPfin; 死循?。msg:DB0x0a, 0x0a; 改行を2つDB"hello, uos1"DB0x0a; 改行DB0RESB0x7dfe-$DB0x55, 0xaa; 以下はブートセクタ以外の部分の記述DB0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00RESB4600DB0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00RESB1469432
经过下面命令编译后,生成helloos.img打开后如图所示,出现了一些代码中未实现的数据。
..z_toolsask.exe helloos.nas helloos.img
后来经过屏蔽代码,显示如图。
去掉jmp后面的代码也是可以启动起来的,证明是编译器写入的初始数据。
费了好长时间再调这个问题,请大佬们不要鄙视。
为什么是0x7c00处呢,这是bios规定的。0x00007c00-0x00007dff为启动区内容的装载地址
执行结果如图:
2.完善工程架构
去掉helloos.nas中55aa后边占字符的所有代码,只留下引导扇区内容。
; hello-os; TAB=4ORG0x7c00; このプログラムがどこに読み込まれるのか; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述JMPentryDB0x90DB"HELLOIPL"; ブートセクタの名前を自由に書いてよい(8バイト)DW512; 1セクタの大きさ(512にしなければいけない)DB1; クラスタの大きさ(1セクタにしなければいけない)DW1; FATがどこから始まるか(普通は1セクタ目からにする)DB2; FATの個数(2にしなければいけない)DW224; ルートディレクトリ領域の大きさ(普通は224エントリにする)DW2880; このドライブの大きさ(2880セクタにしなければいけない)DB0xf0; メディアのタイプ(0xf0にしなければいけない)DW9; FAT領域の長さ(9セクタにしなければいけない)DW18; 1トラックにいくつのセクタがあるか(18にしなければいけない)DW2; ヘッドの数(2にしなければいけない)DD0; パーティションを使ってないのでここは必ず0DD2880; このドライブ大きさをもう一度書くDB0,0,0x29; よくわからないけどこの値にしておくといいらしいDD0xffffffff; たぶんボリュームシリアル番号DB"HELLO-OS "; ディスクの名前(11バイト)DB"FAT12 "; フォーマットの名前(8バイト)RESB18entry:MOVAX,0MOVSS,AXMOVSP,0x7c00MOVDS,AXMOVES,AXMOVSI,msgputloop:MOVAL,[SI]ADDSI,1; SIに1を足すCMPAL,0JEfinMOVAH,0x0e; 一文字表示ファンクションMOVBX,15; カラーコードINT0x10; ビデオBIOS呼び出しJMPputloopfin:HLT; 何かあるまでCPUを停止させるJMPfin; 無限ループmsg:DB0x0a, 0x0a; 改行を2つDB"hello, uos "DB0x0a; 改行DB0RESB0x7dfe-$; 0x7dfeまでを0x00で埋める命令DB0x55, 0xaa
将文件名改为ipl.nas,因为要将程序逐渐修改成一个ipl(Initial program loader)
加入makefile文件,和makefile的执行批处理文件。
Makefile: makefile的编写规则,自己学习,这是基础就不讲了。
# 默认行为default :../z_tools/make.exe img# 文件生成规则ipl.bin : ipl.nas Makefile../z_tools/nask.exe ipl.nas ipl.bin ipl.lsthelloos.img : ipl.bin Makefile../z_tools/edimg.exe imgin:../z_tools/fdimg0at.tek wbinimg src:ipl.bin len:512 from:0 to:0 imgout:helloos.img# 命令asm :../z_tools/make.exe -r ipl.binimg :../z_tools/make.exe -r helloos.imgrun :../z_tools/make.exe imgcopy helloos.img ..z_toolsqemufdimage0.bin../z_tools/make.exe -C ../z_tools/qemuinstall :../z_tools/make.exe img../z_tools/imgtol.com w a: helloos.imgclean :-del ipl.bin-del ipl.lstsrc_only :../z_tools/make.exe clean-del helloos.img
make.bat: 这是批处理文件的编写规则,和linux下的shell类似,不讲了,自己学习。
..z_toolsmake.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
使用make run编译代码,生成ipl.bin二进制文件,并生成空img,然后将ipl.bin写入空img中,最后运行。
其实只用ipl.bin放入qemu中启动也是可以的。ipl.bin只是一个启动扇区。
结果如下图所示:
遗留问题:jmp开始直接跳过那段代码,为啥还不能删除?
实验证明可以删除,只是会影响他自己写的这个程序生成img文件而已。不影响。