因为正在全力把操作系统安装到真机上,所以这两天没有进一步阅读。喜大普奔,已经可以使用usb真机上直接运行我们的操作系统了。 以下视频纯属装逼,可以略过。
为了能够把系统写到USB中,同时又不破坏U盘数据格式,真的是历经磨难啊。
FAT32 格式信息写入启动扇区
作者使用软盘FAT 12格式,我们需要使用U盘FAT 32格式。
首先,需要改动的就是我们的引导扇区代码,把原有FAT 12格式描述,改为FAT 32描述。
DB "MSDOS5.0" ;OEM
DW 0x200 ;Bytes_per_sector
DB 8 ;Sectors_per_cluster
DW 0x8F8 ;Reserved_sectors (2 - 2296可以使用)
DB 2 ;Number_of_FATs
DW 0 ;Root_entries
DW 0 ;Sectors_small
DB 0XF8 ;Media_descriptor
DW 0 ;Number_of_FATs16
DW 0x003F ;Sectors per track
DW 255 ;Heads
DD 0 ;Hidden sectors
DD 0xEE8C00 ;Sectors total 32
;FAT32 SECTION
DD 0x00003B84 ;Number of fat32
DW 0 ;mirror flag
DW 0 ;version
DD 2 ;offclus_root
DW 1 ;fsinfo
DW 6 ;mbr backup
RESB 12 ;fat32 reserverd
DB 0x80 ;usb flag
DB 0 ;fat16 reserverd
DB 0x29 ;boot_sign
DD 0x08F85C97 ;Volume id
DB "NO NAME " ;Volume label
DB "FAT32 " ;File system
上面的代码是关于FAT32引导扇区的格式,具体含义看英文备注即可。具体数值是用WinHex读我的U盘确定的,如果你要自己做实验,注意有一小部分数值和你的U盘并不匹配。
然后呢,作者说软盘的第一个文件会4200地址处,也就是第33扇区,那我们也可以把haribote.sys直接写到U盘第33扇区。不过为了方便,我把haribote.sys文件写入到U盘的第3扇区,我试过写到第2扇区,无法启动系统。开始以为是程序bug,后来发现除了第二扇区其它的保留扇区(测试3,5,10,100)都可以。(目前怀疑是我的U盘第2扇区可能有坏点,或者另有什么原因,如果您知道原因万望留言告知于我)。总之不会影响U盘正常使用,因为2296个保留扇区就是提供我们无偿使用的。万分感谢~
获取USB柱面,磁头,扇区信息
剩下的关键问题就是如何读取USB了,方法和读取软盘很像。只不过软盘的柱面,磁头,扇区是已知的,我们USB还不知道。那么如果能够获取到USB信息,一切问题就迎刃而解了。
usbid:
DB 0
maxhead:
DB 0
maxsector:
DB 0
maxcylinder:
DW 0
getusb:
MOV SI,usbid
MOV [SI],DL
MOV AH, 8
INT 0x13
MOV SI,maxhead
MOV [SI],DH
MOV SI,maxsector
MOV DL,CL
AND CL,0x3F
MOV [SI],CL
AND DL,0xC0
MOV SI,maxcylinder
MOV [SI],CH
ROR DL,6
MOV [SI+1],DL
从bios选择usb启动时,dl值已经被正确设置。通过设置AH=8,调用INT 0x13,就可以获取柱面,磁头,扇区这些信息。具体细节可参考这篇文章。
https://blog.csdn.net/cherishsir/article/details/27517621blog.csdn.net读取USB第三扇区,直接写入C200处,然后JMP到C200
这样很方便和后面的作者的程序兼容到一起,而且不会有什么问题。读取的代码就不展示了,书上有。读软盘和USB流程是一模一样的。作者读取了180KB,但我只读了32KB,因为180KB里面只有30KB是有用数据。
covert:
MOV AL, [maxsector]
MOV BL, [maxhead]
MUL BL
MOV [headmulsector],AX
MOV AX,2 ;将扇区数(以0开始)转化为柱面,磁头,扇区(以1开始)
MOV DX,0
MOV CX,[headmulsector]
DIV CX
MOV [startcylinder],AX
MOV AX,DX
MOV BL,[maxsector]
DIV BL
MOV [starthead],AL
ADD AH,1
MOV [startsector],AH
MOV AX,0x0C20 ; 加载至C200处
MOV ES,AX
MOV CH,[startcylinder] ; 柱面x
MOV DH,[starthead] ; 磁头y
MOV CL,[startsector] ; 扇区z
提供一个将扇区号,转为USB柱面,磁头,扇区的以小段汇编算法。注意第五行MOV AX,2,写入不同数值,就会直接从该扇区进行读取。
打包整理Makefile
usb.nas是我自定义的loader,我这里usb.nas先编译为usb.bin,且正好是1KB两个扇区。
haribote.img : ipl10.bin usb.bin haribote.sys Makefile
$(EDIMG) imgin:../z_tools/fdimg0at.tek
wbinimg src:ipl10.bin len:512 from:0 to:0
copy from:haribote.sys to:@:
imgout:haribote.img
copy /B usb.bin+haribote.sys usbos.bin
像这样usb.bin和haribote.sys直接二进制连接即可,然后用ultraiso或dd把usbos.bin写入USB即可。
真机测试问题总结(更新)
1,将haribote.sys写入第二扇区,无法加载系统,USB问题,更换usb解决。
2,真机测试,同时使用鼠标和键盘,键盘会收到多余的中断信息,查阅英文文献得知需要特别处理。
3,有些电脑不能运行该系统,怀疑缺少部分芯片,或有其他不兼容,原来我们直接写引导扇区到usb属于USB-FDD模式,有些主板并不支持该模式,改用USB-HDD模式后成功运行系统了。开始怀疑是UEFI和legacy boot问题,设置之后还是没有办法启动,都快要绝望了,看了一下《一个64位操作系统的设计与实现》感觉有可能是USB的模式问题,果然。