简介
实验:编写 mbr,读取0盘0道2扇区的内容写入内存,然后跳转执行写好的loader.s
代码
boot/mbr.s
; boot/mbr.s
; 功能:读取磁盘,加载loader到内存并跳转到loader
%include "boot.inc"
SECTION MBR vstart=0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
mov ax, 0xb800
mov gs,ax
; 清屏利用0x06号功能,上卷全部行,则可清屏。
; 输入:
; AH 功能号=0x06
; AL = 上卷的行数(如果为0,表示全部)
; BH = 上卷行属性
; (CL,CH) = 窗口的左上角的(X,Y)位置
; (DL,DH) = 窗口的右上角的(X,Y)位置
; 无返回值:
mov ax,0x600
mov bx,0x700
mov cx,0
mov dx,0x184f
int 0x10
mov eax,LOADER_START_SECTOR
mov bx,LOADER_BASE_ADDR
mov cx,1
call rd_disk_m_16
jmp LOADER_BASE_ADDR
; 读取硬盘n个扇区
; eax = LBA扇区号
; bx = 将数据写入的内存地址
; cx=读入的扇区数
rd_disk_m_16:
; 备份
mov esi,eax
mov di,cx
; 设置要读取的扇区数
mov cl,0x8
mov dx,0x1f2
mov al,cl
out dx,al
mov eax,esi
; 设置要读取的地址
mov dx,0x1f3 ; 写入0-7位
out dx,al
mov cl,0x8
shr eax,cl
mov dx,0x1f4 ; 写入8-15位
out dx,al
shr eax,cl
mov dx,0x1f5 ; 写入16-23位
out dx,al
shr eax,cl
and al,0x0f ; 24~27位
or al,0xe0 ; 设置7~4位为1110,表示lba模式
mov dx,0x1f6
out dx,al
; 写入读命令
mov dx,0x1f7
mov al,0x20
out dx,al
; 检测硬盘状态
.not_ready:
nop
in al,dx
and al,0x88
cmp al,0x08
jnz .not_ready
; 读数据
mov ax,di
mov dx,256
mul dx
mov cx,ax
mov dx,0x1f0
.go_on_read:
in ax,dx
mov [bx],ax
add bx,2
loop .go_on_read
ret
times 510-($-$$) db 0
db 0x55,0xaa
boot/loader.s
; boot/loader.s
; 功能:在屏幕显示字符
%include "boot.inc"
SECTION MBR vstart=LOADER_BASE_ADDR
mov byte [gs:0x00],'2'
mov byte [gs:0x01],0xA4
mov byte [gs:0x02],' '
mov byte [gs:0x03],0xA4
mov byte [gs:0x04],'L'
mov byte [gs:0x05],0xA4
mov byte [gs:0x06],'O'
mov byte [gs:0x07],0xA4
mov byte [gs:0x08],'A'
mov byte [gs:0x09],0xA4
mov byte [gs:0x0a],'D'
mov byte [gs:0x0b],0xA4
mov byte [gs:0x0c],'E'
mov byte [gs:0x0d],0xA4
mov byte [gs:0x0e],'R'
mov byte [gs:0x0f],0xA4
jmp $
编译
Makefile
BUILD_DIR = ./build
.PHONY : mk_dir bootloader clean all
mk_dir: #创建build目录
if [ ! -d $(BUILD_DIR) ]; then mkdir $(BUILD_DIR); fi
bootloader: #编译启动内核的文件 bootloader
nasm -I include/ -o $(BUILD_DIR)/mbr.bin boot/mbr.s
nasm -I include/ -o $(BUILD_DIR)/loader.bin boot/loader.s
dd if=/home/c/tityos/build/mbr.bin of=/home/c/tityos/hd60M.img bs=512 count=1 conv=notrunc
dd if=/home/c/tityos/build/loader.bin of=/home/c/tityos/hd60M.img bs=512 count=1 seek=2 conv=notrunc
clean: #删除build目录里的全部文件
cd $(BUILD_DIR) && rm -f ./*
# 创建build目录。编译启动内核的文件。
all: mk_dir bootloader
运行
start.sh
# !/bin/bash
# 功能:启动bochs
bin/bochs -f bochsrc.disk