佐须之男的博客

技术需要沉淀,成长需要痛苦,成功需要坚持,敬仰需要奉献

30天自制操作系统之磁盘引导篇

    由于<30天自制操作系统>这本书是在06年于日本出版的,10年后的今天很多资料都遗失了,所以开发过程中还真不顺利。辛亏网上有很多例子可以参考,比如:https://blog.slinuxer.com


    磁盘引导需要使用一个新的中断 Int 0x13,下面是代码。

// ip.asm

    ORG    0x7c00

; FAT12 磁盘相关参数
    JMP    entry
    DB    0xeb, 0x4e, 0x90
    DB     "12345678"
    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    "0123456789A"
    DB    "FAT12   "
    RESB    18


entry:
    MOV    AX, 0    ; 寄存器初始化
    MOV    SS, AX    ; SS:[SP]
    MOV     SP, 0x7c00
    MOV    DS, AX    ; DS:[SI]
    MOV     ES, AX    ; ES:[DI]

    MOV    SI,msg

putloop:
    MOV     AL,[SI]
    ADD    SI,1    ; 给SI加1
    CMP    AL,0
    JE    rddisk    
    MOV    AH,0x0e    ; 显示一个文字
    MOV    BX,15    ; 指定字符颜色
    INT    0x10    ; 调用显卡BIOS
    JMP    putloop


; 读取磁盘 int 0x13     
rddisk:
    MOV    AX, 0x0820
    MOV     ES, AX
    MOV    CH, 0     ; 0 柱面 0 磁头 2 扇区 
    MOV     DH, 0
    MOV     CL, 2
    
    MOV     AH, 0x02    ; 读磁盘    
    MOV     AL, 1    ; 连续读取扇区1
    MOV     BX, 0
    MOV    DL, 0x00    ; 软盘A
    INT    0x13

    JMP     0x8200

fin:
    HLT 
    JMP    fin
msg:
    DB    0x0a, 0x0a
    DB    "read disk..."
    DB    0x0a
    DB    0

error:
    DB    0x0a, 0x0a
    DB    "read disk error!"
    DB    0x0a
    DB    0

    RESB    0x1fe-($-$$)
    DB    0x55, 0xaa
    
// hello.asm

    ORG        0x8200
; 0x8200

        MOV             AX,0                    ; 初始化寄存器
        MOV             SS,AX
        MOV             SP,0x8200
        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                    ; 调用显卡BIOS
        JMP             putloop
fin:
        HLT                                             ; 让CPU停止,等待指令
        JMP             fin                             ; 无限循环

msg:
        DB              0x0a, 0x0a              ; 换行两次
        DB              "boot success"
        DB              0x0a                    ; 换行
        DB              0

    代码的原理是:ipl.asm的前512 byte会自动被bios复制到0x7c00并执行。但是由于512 byte空间并不足以放下一个系统,所以需要在0x7c00里实现一个简单的loader把磁盘里的程序拷贝到0x8200的位置。难点是int 0x13的寄存器意义。



版权所有: http://forgotfun.org/2016/09/30%E5%A4%A9%E8%87%AA%E5%88%B6%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E4%B9%8B%E7%A3%81%E7%9B%98%E5%BC%95%E5%AF%BC%E7%AF%87.html 作者: 佐须之男 未经允许请勿转载

© 2016 佐须之男版权所有 | 联系方式 forgotfun@qq.com | 业务合作 181-1435-4589 (陆工)