作者是在2006年发布此书的(翻译版是在2012年在中国发售),当时可能还能找到带有软驱的计算机。但是时过境迁,现在已经不存在这种老古董东西了。
简单总结一下学习到第三天的一些更变。
书籍里用的是nask这款作者自制的汇编语言编译器,ReactOS的实模式部分是用nasm写的,还是用nasm改造一下好。
已经有文章阐述如何把简单的代码改为nasm格式,《nask与nasm代码差异》这位朋友写的非常清晰,可以直接用于day02的代码上。
; hello-os
; TAB=4
ORG 0x7c00 ;
JMP SHORT entry
DB 0x90
DB "HELLOIPL" ;
DW 512 ;
DB 1 ;
DW 1 ;
DB 2 ;
DW 224 ;
DW 2880 ;
DB 0xf0 ;
DW 9 ;
DW 18 ;
DW 2 ;
DD 0 ;
DD 2880 ;
DB 0,0,0x29 ;
DD 0xffffffff ;
DB "HELLO-OS" ;
DB "FAT12" ;
TIMES 18 DB 0 ;
;
entry:
MOV AX,0 ; 儗僕僗僞弶婜壔
MOV SS,AX
MOV SP,0x7c00
MOV DS,AX
MOV ES,AX
MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI,1 ; SI偵1傪懌偡
CMP AL,0
JE fin
MOV AH,0x0e ;
MOV BX,15 ;
INT 0x10 ;
JMP putloop
fin:
HLT ;
JMP fin ;
msg:
DB 0x0a, 0x0a ;
DB "hello, world"
DB 0x0a ;
DB 0
TIMES 0x1fe-($ - $$) DB 0
DB 0x55, 0xaa
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
TIMES 4600 DB 0
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
TIMES 1469432 DB 0
由于下载的源码是Shift_JIS编码的,懒得转换就直接把注释那部分乱码部分删除了。
nasm helloos.nas
这样就可以在当前目录生成helloos的bin文件。
估计不少朋友都是在虚拟机上虚拟一个软驱来进行实验。由于我个人不喜欢虚拟机,一般都拿真机实验。没有软驱也不可能买到软盘的这个时代,打算用U盘取代这个实验。
原文作者是把bin生成image后写入软盘,但是我们实际上不用生成image。只要把引导扇区写入U盘就可以了。这里有两种方式:
1. 通过dd工具写入U盘:自己动手写操作系统 将引导程序成功写入优盘启动电脑
这种方式每次写入U盘都要先格式化U盘,不然会报另一个进程正在使用该分区(暂时没有找到原因)。
2. 直接通过CreateFile接口,通过符号链接方式打开磁盘分区:打造操作系统(1.3)如何写入引导扇区
然后WriteFile写入就可以了。
格式化U盘写入image后,有时候想再写入,会提示:“另一个程序正在使用此文件,进程无法访问”,的IO错误。
这时候用“资源监视器”可以轻松看到谁占用了U盘:
这里可以看到有时候资源管理器确实会占用着U盘,这时候把explorer.exe结束掉后(此时文件夹浏览以及底部Windows窗体栏会消失),用Alt+Tab切换一下到命令行,执行dd命令把image写入U盘即可,省去每次写入还要格式化的弊端。
无论哪种方式,写完后可以看到U盘的数据实际上已经被破坏,例如原本16GB的U盘现在就只有大小13MB还剩1MB。不用理会,因为引导分区覆盖了文件系统描述符。插入计算机后选择USB引导系统,启动系统即可。
以下截取自《30天自制操作系统》:
INT 0x13 BIOS说明关于DL的驱动器号,书本上写的是0x00,表示A驱动器。但是实际上我们用的是U盘。所以直接执行day03里的harib00a肯定会输出Load error的失败消息。
在《Windows内核设计思想》25页里恰好有如下内容:
于是把DL设置从0x80开始尝试读取,就快成功了。
由于插入的U盘应该不会是第一块磁盘,我实验到的是0x82的时候,读取成功了。在想BIOS是否暂时无法读取到非引导的硬盘,后面再来补充这点(2019-03-14)。
最初我参考了这位朋友的信息:汇编--INT 13h功能,里面有记载着0x13/AH=48h的简单用法以及返回buffer的结构解析,还引用了Windows 7调用这个BIOS功能的x86汇编代码,参考价值不小。
在Google里也可以搜索到相关的更加详细的资料:点我跳转
找了一下好像BIOS只有输出字符到屏幕的功能,没有类似C语言的printf()可以输出整型的相关调用。于是自己写了一个。
由于不可能真的每次调试的时候都刷入U盘启动计算机去看看输出是否正确,所以编写过程还是比较坎坷的。
在一台内置机械硬盘为500GB,U盘(启动盘)为16GB的笔记本电脑上测试的结果。
最开始一直搞错,是因为结构体的偏移老写错,搞到读取到磁盘的大小大的匪夷所思。