admin管理员组

文章数量:1559120

背景

作者是在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盘启动盘

估计不少朋友都是在虚拟机上虚拟一个软驱来进行实验。由于我个人不喜欢虚拟机,一般都拿真机实验。没有软驱也不可能买到软盘的这个时代,打算用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引导系统,启动系统即可。

int 0x13/ah=2h读取数据

以下截取自《30天自制操作系统》:

int 0x13 bios说明

关于dl的驱动器号,书本上写的是0x00,表示a驱动器。但是实际上我们用的是u盘。所以直接执行day03里的harib00a肯定会输出load error的失败消息。

在《windows内核设计思想》25页里恰好有如下内容:

于是把dl设置从0x80开始尝试读取,就快成功了。

由于插入的u盘应该不会是第一块磁盘,我实验到的是0x82的时候,读取成功了。在想bios是否暂时无法读取到非引导的硬盘,后面再来补充这点(2019-03-14)。

int 0x13/ah=48h获取磁盘信息

最初我参考了这位朋友的信息:汇编--int 13h功能,里面有记载着0x13/ah=48h的简单用法以及返回buffer的结构解析,还引用了windows 7调用这个bios功能的x86汇编代码,参考价值不小。

在google里也可以搜索到相关的更加详细的资料:点我跳转

编码int 0x13/ah=48h并把关键信息输出到屏幕

找了一下好像bios只有输出字符到屏幕的功能,没有类似c语言的printf()可以输出整型的相关调用。于是自己写了一个。

由于不可能真的每次调试的时候都刷入u盘启动计算机去看看输出是否正确,所以编写过程还是比较坎坷的。

  1. 首先我再vs2015上用x86内联汇编尽量靠近16位汇编写了一段关于数字转字符串的函数
  2. 再用dosbox使用masm 5.0编译出16位汇编程序,在dos模式下测试并调试
  3. 以上没有问题后,最终才转向mbr引导

在一台内置机械硬盘为500gb,u盘(启动盘)为16gb的笔记本电脑上测试的结果。

最开始一直搞错,是因为结构体的偏移老写错,搞到读取到磁盘的大小大的匪夷所思。

源码

  1. 这里把修改后的day03的harib00a的ipl.nas修改了一下保存成ipl-u.nas。里面还保存了ipl.nas作为对比,各位可以参照一下:代码下载点我
  2. int 0x13/ah=48h测试代码,包括:
    1. x86:vs2015上编写内联汇编实现字节转字符串并输出的代码
    2. dos:基于上面1在dosbox上用masm 5.0编写16位汇编代码
    3. mbr:最终跑在笔记本电脑上的mbr代码

本文标签: