操作系统真象还原实验记录之实验一:第一次编写mbr

操作系统真象还原之实验一:第一次编写mbr

对应书中第2.3节:让mbr飞一会 第58页

1.相关基础知识提炼总结

1.1电脑开机前与后

操作系统真象还原实验记录之实验一:第一次编写mbr_第1张图片
在电脑未开机前,BIOS就被事先写入到内存的F0000~FFFFF中。此区域为ROM(非易失性存储器,断电仍可以保存数据。)
MBR被加载到磁盘的0盘0道1扇区(CHS方式)
CHS 方式中扇区的编号是从1开始的
当电脑按下power键后,cs:ip会被强制置为F000:FFF0 ,所以cpu会执行内存地址FFFF0处的指令。
FFFF0处的指令为跳转指令jmp far f000:e05b。(也就是BIOS区域中某个地址)
跳转后,BIOS便马不停蹄地检测内存、显卡等外设信息,当检测通过,并初始化好硬件后,开始在内存中 0x000~0x3FF处建立数据结构,中断向量表 IVT 并填写中断例程。
BIOS 最后一项工作校验启动盘中位于0盘0道1扇区的内容。
如果此扇区末尾的两个字节分别是魔数0x55和0xaa,就会把该扇区内容加载到内存地址 0x7c00处,
然后执行跳转指令jmp 0: 0x7c00

2.实验记录

2.1 实验目的

编写mbr.s程序,该程序可以在显示屏打印字段。将该程序加载到磁盘的0盘0道1扇区,使用bochs模拟,确保当计算机执行完BIOS后可以执行mbr.s,在显示屏打印字段。

2.2 实验代码

; mbr.S

; 主引导程序
; --------------------------------------------------

SECTION MBR vstart=0x7c00 ; 把起始地址编译为 0x7c00
    mov ax, cs     ; cs 代码段寄存器
    mov ds, ax     ; dx 数据段寄存器
    mov es, ax     ; es 附加段寄存器
    mov ss, ax     ; ss 堆栈段寄存器
    mov fs, ax     ; fs 80386 后添加的寄存器,无全称
    mov sp, 0x7c00 ; sp 堆栈指针寄存器

; 清屏
; --------------------------------------------------
; INT 0x10    功能号: 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 ; 右下角: (80, 25)
                   ; VGA 文本模式种,一行只能容纳 80 个字符,共 25 行
                   ; 下标从 0 开始,所以 0x18=24, 0x4f=79
        
    int 0x10       ; int 0x10

;;;;;;;;;;;;;下面这三行代码获取光标位置;;;;;;;;;;;;;;;;

; .get_cursor 获取当前光标位置,在光标处打印字符
    mov ah, 3      ; 3 号子功能
    mov bh, 0      ; 待获取光标的页号

    int 0x10       ; 输出:
                   ; ch = 光标开始行,cl = 光标结束行
                   ; dh = 光标所在行号,dl = 光标所在列号

; 打印字符串
    mov ax, message
    mov bp, ax     ; es:bp 为串首地址
    
    mov cx, 5      ; cx 为串长度,不包括结束符 '\0'
    mov ax, 0x1301 ; 13 号子功能
                   ; ah = 13
                   ; al = 01: 写字符方式,显式字符串,光标跟随移动
    mov bx, 0x2    ; bh = 0,要显示的页号
                   ; bl = 02,字符属性,黑底绿字
    
    int 0x10
;;;;;;;;;;;;;;;;;;;;;;打印字符串结束;;;;;;;;;;;;;;;;
jmp $;     程序悬停在此

message db "1 MBR"
times 510-($-$$)   db 0
db 0x55,0xaa

代码小结

这次代码为实模式下对x86架构的汇编编程,实模式下段寄存器,通用寄存器如下:
操作系统真象还原实验记录之实验一:第一次编写mbr_第2张图片
操作系统真象还原实验记录之实验一:第一次编写mbr_第3张图片
本代码使用了BIOS提供好的中断服务程序完成了在显存0页光标处打印字符串。

BIOS中断例程

每个外设,如显卡、键盘、各种控制器等,都有自己的内存(RAM+ROM),外设将自己的中断例程以及初始化例程都事先写好存储在它们的ROM中。
根据规范,该ROM的第一个存储单元内容是0x55,第二个是0xAA,第三个是该ROM以512字节为单位的代码长度,第四个开始是代码。
从1MB下的内存0xA0000到0xFFFFF这部分内存中,一部分是专门用来给外设ROM作内存映射的。
BIOS会在运行期间扫描0xC0000到0xE0000之间内容,发现某个区域前两字节是0x55和0xAA时,说明该区域有代码,在做累加和与第三个字节比较,无误则说明代码无误,就从第四个字节进入,执行外设自带的初始化例程,填写,BIOS中断向量表IVT(实模式1MB下0x000到0x400),使他们指向BIOS提供中断例程

代码功能

先调用BIOS中断的0x10号中断的0x06子功能上卷80行清屏,
在调用0x10号中断的0x03号子功能获取显存第0页的光标位置,输出到dx
最后调用13号子功能在显存第0页光标处打印字符串,且光标跟随移动。

一些汇编细节

1.使用vstart=0x7c00,则message表示的地址还要加上0x7c00才是编译后实际送入寄存器的地址。$ $$这类符号均是如此。
2.用cs、ax将段寄存器清0
3.用寄存器bp去访存获得长度为5的字符串时,实模式下访存方式为es:bp,只不过es已被ax赋值为0,所以访存的仍然是message+0x7c00(即"1 MBR"的物理地址)。

2.3实验流程

0.创建硬盘,命名Seven.img

./bximage -mode=create  -imgmode=flat -hd=60 -q Seven.img

效果图
操作系统真象还原实验记录之实验一:第一次编写mbr_第4张图片

注:此命令和书上不同,因为环境版本不同 -size会报错。
输入命令

./bximage  --help

可查看自己环境支持的命令
效果图
操作系统真象还原实验记录之实验一:第一次编写mbr_第5张图片

1.找到文件目录,点击在终端中打开,使用命令

nasm -o mbr.bin mbr.s  

将mbr.s编译成mbr.min。

2.将mbr.bin刻入磁盘第0块(LBA方式)命令为

dd if=/你的mbr.bin的路径/mbr.bin of=/你的自定义硬盘的路径/自定义硬盘名称 bs=512 count=1 seek=0 conv=notrunc

比如我自己的

dd if=/home/Seven/bochs2.68/bin/mbr.bin of=/home/Seven/bochs2.68/bin/Seven.img bs=512 count=1 seek=0 conv=notrunc

3.用bochs进行模拟

输入命令

./bochs -f bochsrc.disk  

然后输入c继续。

2.4实验结果

操作系统真象还原实验记录之实验一:第一次编写mbr_第6张图片

你可能感兴趣的:(操作系统,操作系统)