Last active
November 23, 2019 14:21
-
-
Save beiweiqiang/fdfb810c46efe0c091a09e7e6dd26ccb to your computer and use it in GitHub Desktop.
在 initial program loader 中, 读取 10柱面 * 2磁头 * 18扇区 字节, 每个扇区重试 5 次, 否则跳转 error
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; hello-os | |
; TAB=4 | |
CYLS equ 10 | |
org 0x7c00 ; 指明程序装载地址, 因为前面的内存地址已经被占用了 | |
jmp entry | |
db 0x90 | |
db "helloipl" ; 启动区的名称 8字节 | |
dw 512 ; 每个扇区的大小 512 字节 | |
db 1 ; cluster 的大小 (1个扇区) | |
dw 1 ; FAT 的起始位置 (第 1 个扇区开始) | |
db 2 ; FAT 的个数 (2 个) | |
dw 224 ; 根目录的大小 (224项) | |
dw 2880 ; 磁盘大小 (2880 扇区 = 80柱面 * 18扇区 * 2磁头) | |
db 0xf0 ; 磁盘种类 | |
dw 9 ; FAT 长度 (9 扇区) | |
dw 18 ; 一个磁道多少个扇区 (18) | |
dw 2 ; 磁头数量 | |
dd 0 ; 不使用分区 | |
dd 2880 ; 磁盘大小 | |
db 0,0,0x29 | |
dd 0xffffffff | |
db "hello-osiii" ; 磁盘名称 (11字节) | |
db "FAT12 " ; 磁盘格式名称 (8字节) | |
times 18 db 0 ; 空出 18 字节 | |
entry: | |
mov ax, 0 | |
mov ss, ax | |
mov sp, 0x7c00 | |
mov ds, ax | |
mov es, ax | |
mov ax, 0x0820 ; 放入 es 的 ax, 会自动 * 16, 即 ES:BX = ES * 16 + BX 的内存, 前面的 0x1ff 是给启动区的 | |
mov es, ax | |
mov ch, 0 ; 柱面 0, 柱面范围: 0 ~ 79 | |
mov dh, 0 ; 磁头 0, 磁头范围: 0 ~ 1 | |
mov cl, 2 ; 扇区 2, 扇区范围: 1 ~ 18, 表示即将读取第 2 个扇区, 现在第 2 个扇区没东西, 直接跑这个 asm 会 error | |
readloop: | |
mov si, 0 ; 记录失败次数, 感觉 si 经常用来做累加判断 | |
retry: | |
mov ah, 0x02 ; ah = 0x02, 表示读盘 | |
mov al, 1 ; 1 个扇区, 表示处理对象的扇区数量 | |
mov bx, 0 | |
mov dl, 0x00 ; A 驱动器 | |
int 0x13 ; 磁盘读, 写, 扇区校验, 寻道. 调用磁盘 BIOS | |
jnc next ; 进位标志位为 0, 即没有错误, 跳转 next, 准备读取下一个扇面 | |
add si, 1 | |
cmp si, 5 | |
jae error ; >= 5 次, 跳转 error | |
mov ah, 0x00 ; 准备重置 | |
mov dl, 0x00 | |
int 0x13 ; 重置驱动器 | |
jmp retry | |
next: | |
mov ax, es | |
add ax, 0x0020 ; 把内存地址后移 0x200 (因为 es 会 * 16) | |
mov es, ax ; 因为没有 add es, 0x20 指令 | |
add cl, 1 ; 下一个扇面 | |
cmp cl, 18 | |
jbe readloop ; 如果 cl <= 18, 继续读取, 扇面编号为 1 ~ 18 | |
mov cl, 1 ; 遍历顺序: 扇区 1~18 -> 磁头 0~1 -> 柱面 0~79 | |
add dh, 1 | |
cmp dh, 2 | |
jb readloop ; 如果 dh (磁头) < 2, 跳转到 readloop | |
mov dh, 0 | |
add ch, 1 ; 柱面 + 1 | |
cmp ch, CYLS | |
jb readloop | |
fin: | |
hlt ; 使 cpu 停止动作 | |
jmp fin ; 无脑跳 fin | |
; 下面这是一套展示字符串的逻辑 | |
error: | |
mov si, msg | |
putloop: | |
mov ah, 0x0e ; 为了显示字符, 需要将 AX 高位置为 0e | |
mov al, [si] ; 把内存 [si] 的内容搬到 al 里 | |
mov bx, 15 ; 颜色 (但是没有效果) | |
add si, 1 | |
cmp al, 0 ; 如果 al 为 0, 证明内存 [si] 字符串已经结束 | |
je fin ; 如果 al 为 0, 跳转到 fin | |
int 0x10 | |
jmp putloop | |
msg: | |
db "error" | |
TIMES 0x1fe-($-$$) DB 0 ; 1fe = 510, 还差 2 字节到 512字节 一个扇区 | |
db 0x55, 0xaa ; 这是第 1 个扇区的最后 2 个字节, 55 aa 决定该扇区的开头是启动程序 | |
; 剩余磁盘内容 | |
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/bash | |
nasm my.asm -o tos.img | |
qemu-system-i386 -fda tos.img -boot a |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment