背景

基本上,每个硬盘除了每扇(Sector)大小依旧是512字节外,柱面(Cylinder)数、磁头(Header)数都不一致。

用磁盘来取代原作者的软盘后,沿用原来的INT 0x13/AH=2h读磁盘的话会非常蹩脚并且非常不方便。参考Windows 7也是用INT 0x13/AH=0x42h读磁盘。用该方法读磁盘只需要关注到扇区即可,不需要关注到柱面跟磁头数,很直观。

调试

Bochs

这次采用了bochs2.6.9来支持。这虚拟机对编写操作系统的人来说非常有帮助!贴出本次用到的配置文件如下。对应目录则对应修改成本地的,这里不在另外赘述。

###############################################################
# Configuration file for Bochs
###############################################################

# how much memory the emulated machine will have
megs: 32

# 对应真实机器的BIOS和VGA BIOS
romimage: file="C:\Program Files (x86)\Bochs-2.6.9\BIOS-bochs-latest"
vgaromimage: file="C:\Program Files (x86)\Bochs-2.6.9\VGABIOS-lgpl-latest"

# 设置bochs使用的磁盘,软盘使用关键字floppya,硬盘使用disk
# 若有多个软盘,可写floppya,floppyb
#floppya: 1_44=a.img, status=inserted

# choose the boot disk.
# 默认是软盘,注释掉,改为disk
#boot: floppy
boot: disk
# where do we send log messages?
log: D:\Documents\bochs\bochsout.txt
# disable the mouse
mouse: enabled=0

# enable key mapping, using US layout as default.
keyboard: keymap="C:\Program Files (x86)\Bochs-2.6.9\keymaps\x11-pc-us.map"

ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14

#这一句是根据bximage生成的,后面会解释。
ata0-master: type=disk, path="D:\Documents\bochs\c.img", mode=flat, cylinders=20, heads=16, spt=63

magic_break: enabled=1

通过以下命令进行调试。bochsdbg.exe可以进行调试,但是bochs.exe则不行,需要注意。

bochsdbg -f "D:\Documents\bochs\bochs.disk"

magic_break开启后,虚拟机会把

XCHG    BX, BX

当成断点停下来,方便调试。

错误

如果INT 0x13/AH=0x42h调用时用了错误的参数,除了CF位一定会置1外,还可能会

  • AH=42h
  • AH=1h

我在真机上试验到是AH莫名其妙还是42h,在bochs的虚拟机里则是1h。所以基本上不要真的把AH当成错误号来查询,你基本上是查不到什么有效信息的。只要LBA测试到是支持,那么INT 0x13/AH=0x42h肯定是支持的,如果还调用错误,那肯定是参数设置不对,需要仔细排查一下。

方案

是否支持

并非所有BIOS都支持INT 0x13/AH=0x42h,但是基本上目前绝大多数都支持。但是为了兼容性,还是最好判断一下。

MOV        BX, 0x55AA
        MOV        AH, 0x41
        INT        0x13
        JC        _10_stand_bios
        CMP        BX, 0xAA55
        JNE        _10_stand_bios
        TEST    CL, 1        
        JZ        _10_stand_bios

可以通过以上方法简单判断到是否支持LBA。

如果不幸BIOS不支持,可以考虑回归之前的读取方式。不过我没做兼容。

修改点

由于我改写的ipl10.nas只支持nasm编译,所以在对应代码层级的Makefile文件里,需要做出一些变更。替换原来ipl10.bin为以下编译方式(自行设定好nasm的所在目录):

ipl10.bin : ipl10.nas Makefile
    nasm ipl10.nas
    ren ipl10 ipl10.bin

另外,由于没有采用原书代码里把最后读到的柱面数写入:

MOV        [0x0ff0],CH

所以在asmhead.nas里相应的要自己填上大致读到的Sector数。由于不断深入开发,haribote.sys的大小必定越来越大,所以镜像生成后要多关注一下0x4200开始haribote.sys的内容到哪里结束。假设到0x6200结束,那么大致读上来的扇区数目就是:

0x6200 / 512

在asmhead.nas相应修改如下:

; 残り全部

MOV        ESI,DSKCAC0+512    ; 転送元
        MOV        EDI,DSKCAC+512    ; 転送先
        ;MOV        ECX,0
        MOV        ECX, 512 * 50 / 4 ; read by INT 0x13/AH = 42h
        ;MOV        CL,BYTE [CYLS]
        ;IMUL    ECX,512*18*2/4    ; シリンダ数からバイト数/4に変換
        ;SUB        ECX,512/4        ; IPLの分だけ差し引く
        CALL    memcpy

由于没有做太多的测试,重新编译的时候可能还是需要手动把ipl10.bin删除,各位可以自己修改一下对应的命令。

LoadSectors: ; buffer = EBX, size = ECX, begin sector = EDI
        PUSH     EBP
        MOV        EBP, ESP
        SUB        ESP, 0x10              ; size of DAP
        MOV        AX, 0x4200            ; reads sectors into memory
        MOV        EDX, ECX
        SAR        ECX, 6                ; / 64
        AND        EDX, 0x8000003F      ; % 64
        MOV        BYTE[ESP], 0x10        ; size of DAP
        MOV        BYTE[ESP + 1], 0    ; reserved for 0
        MOV        WORD[ESP + 2], 64   ; 64 sectors
        MOV        DWORD[ESP + 12], 0  ; always 0
        MOV        ESI, ESP            ; DAP addr
        PUSH      EDX
        MOV        DL, 0x80            ; drive number
_8_loop:
        PUSH    ECX
        MOV        ECX, EBX
        AND        CX, 0xF
        MOV        WORD[EBP - 0x10 + 4], CX    ; offset
        MOV        ECX, EBX
        SHR        ECX, 4
        MOV        WORD[EBP - 0x10 + 6], CX  ; segment
        POP        ECX
        MOV        DWORD[EBP - 0x10 + 8], EDI ; begin sector
        CMP        ECX, 0
        JLE        _6_left
        INT        0x13
        JC        _9_error        
        ADD        EDI, 64                ; sector
        ADD        EBX, 512 * 64        ; bytes
        DEC        ECX
        JMP        _8_loop
_6_left:
        POP        EDX
        CMP        EDX, 0
        JLE        _7_leave
        MOV        WORD[ESP + 2], DX   ; left sectors
        MOV        DL, 0x80
        INT      0x13
        JC        _9_error        
        JMP        _7_leave
_9_error:
        MOV        AL, 0
        PUSH    AX
        MOV        CX, 2
        MOV        SI, SP
        CALL    print_byte_str
        ;PUSH    0
        ;PUSH    'rr'
        ;PUSH    're'               ; error
        ;MOV        SI, SP
        ;CALL    print_string        
_7_leave:
        MOV        ESP, EBP
        POP        EBP
        RET

下载

几乎把对应源码改了个遍,基本上找不到太多原来ipl10.nas的影子了。

里面LoadSectors是本篇的核心:ipl10.rar

30天自制操作系统 - 用INT 0x13/AH=0x42h读磁盘相关推荐

  1. 30天自制操作系统 - 取代软盘,用U盘写入引导扇区

    背景 作者是在2006年发布此书的(翻译版是在2012年在中国发售),当时可能还能找到带有软驱的计算机.但是时过境迁,现在已经不存在这种老古董东西了. 简单总结一下学习到第三天的一些更变. 更变 书籍 ...

  2. 《30天自制操作系统》笔记(04)——显示器256色

    <30天自制操作系统>笔记(04)--显示器256色 进度回顾 从最开始的(01)篇到上一篇为止,已经解决了开发环境问题和OS项目的顶层设计问题. 本篇做一个小练习:设置显卡显示256色. ...

  3. 30天自制操作系统第三天

    操作系统实验日志3 学号 201708010402 姓名 徐冰娜 专业年级班级 实验日期 2019.9.28 实验项目 第3天:进入32位模式并导入C语言 智能1701 30天自制操作系统第三天 操作 ...

  4. 《30天自制操作系统》-day3(MAC)

    第3天 进入32位模式并导入C语言 基本配置 汇编语言内容 文件 hanbote.nas ipl.nas Makefile 原因 用法 基本配置 设备:Macbookpro(13-inch,2018) ...

  5. 《30天自制操作系统》U盘启动,真机运行(16天)

    首先说一下到目前为止U盘启动遇到的问题,首先的一个问题是"system volume information",目前尚未解决,这个问题可能导致U盘启动失败,我猜测可能是由于每一次重 ...

  6. 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!

    <30天自制操作系统>笔记(01)--hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的 ...

  7. 30天自制操作系统——第二天

    30天自制操作系统--第二天 今天是该系列的第二天,继续昨天的开发,今天的任务主要有以下几项: 1.进一步的加工一下汇编程序(去除昨天的二进制代码) 2.对启动区进行制作 3.利用makefile简化 ...

  8. 30天自制操作系统——第二十三天窗口操作

    窗口及输入切换 我们先来实现用键盘切换窗口,按下F11键,将最下面的窗口移动到最上面,这里F11按键的编码为0x57. bootpack.c节选: void HariMain(void) {(略)fo ...

  9. 30天自制操作系统——第五天

    第五天 参考<30天自制操作系统>GDT&IDT - 谷月轩 - 博客 梳理一下文件 现在我们拥有这么9个文件: ipl10.nas InitialProgramLoader, 占 ...

最新文章

  1. JMS配置说明-----activeMQ-5.6
  2. 【读书笔记】MongoDB管理与开发精要(1)
  3. 2015 ICPC 上海
  4. JDK8 Stream 效率如何?
  5. C++ 类的抽象初练
  6. 垃圾回收GC Roots
  7. IDEA连接Git后类的颜色含义
  8. pyspark对应的scala代码PythonRDD对象
  9. 【Codeforces #228】Solutions
  10. 张宇八套卷(一)复盘
  11. imx8 uuu烧录
  12. NoSQL03 - 主从复制、RDB/AOF持久化 数据类型
  13. linux mint运行速度,Linux Mint 19 Tara Cinnamon启动应用速度将会更快
  14. 定时任务管理系统 gocron
  15. android scheme 参数解析,Android 利用scheme协议进行跳转
  16. Cb Vc 经典大讨论(很长的一篇文章!)?
  17. Wampserver 80端口被占用
  18. iOS 上传头像 裁剪
  19. Unity3D引擎各大插件免费下载地址
  20. android 简易我的积分页面、答题页面的设计

热门文章

  1. java 为什么使用接口_为什么要使用类接口
  2. es5新增循环 数组方法
  3. 实战真实网站的SQL注入
  4. Simple Run Blocker:程序运行拦截器 阻止程序运行
  5. libiconv移植到android
  6. Mac OS下安装Vue完整步骤
  7. CSDN学霸课表——微信公众号开发全部流程
  8. 华为鸿蒙系统是手机系统吗_华为鸿蒙系统什么时候上市?答案来了
  9. 首次“盈利”的荔枝:营收规模保持增长,付费用户却减少1.6万
  10. 使用Python基于VGG/CTPN/CRNN的自然场景文字方向检测/区域检测/不定长OCR识别