主引导记录(MBR,Master Boot Record)是采用MBR分区表的硬盘的第一个扇区,即C/H/S地址的0柱面0磁头1扇区,也叫做MBR扇区

计算机的启动过程

为什么程序要载入内存
CPU的硬件电路被设计成只能运行处于内存中的程序,一来内存比较快且容量大,二是为了方式的统一。

什么是载入内存

BIOS

从按下主机上的power键后,第一个运行的软件就是BIOS(Base Input & Output System,基本输入输出系统)

实模式下的1MB内存布局

Intel8086 有20条地址线,故其可以访问1MB的内存空间,即2的20次方=1MB,地址范围若按十六进制来表示,是0x00000-0xfffff。

0-0x9FFFF 640KB DRAM(动态随机访问内存),动态指此种存储介质由于本身电气元件的性质,需要定期地刷新(补充电,掉电后数据会消失)物理内存
0xF0000-0xFFFFF 64KB ROM 存放BIOS代码
BIOS 的主要工作是检测、初始化硬件,建立中断向量表,BIOS建立的这些功能就是对硬件的IO操作,也就是输入输出

在CPU眼里,为什么我们插在主板上的物理内存不是它眼里“全部的内存”
地址总线宽度决定了可以访问的内存空间大小,由于还有一些外设同样需要通过地址总线来访问,需要在地址总线上提前预留出一些地址空间给这些外设用。
地址总线是决定我们访问哪里、访问什么,以及访问范围的关键。CPU能够访问一个地址,这是地址总线给做的映射,相当于给该地址分配了一个存储单元,而该存储单元要么落在某个ROM中,要么落到了某个外设的内存中,要么落到了物理内存条上。

BIOS是如何苏醒的


实模式只能访问1MB空间,而地址0xFFFF0距1MB只有16字节,超过就会溢出。说明这里的代码只是各跳转指令,跳转到下一条待执行指令的地址。段基址0xf000左移4位+0xe05b,即跳向了0xfe05b处,这是BIOS代码真正开始的地方。

为什么是0x7c00

BIOS最后一项工作校验启动盘中位于0盘0道1扇区(磁盘上最开始的那个扇区)的内容。如果此扇区末尾的两个字节分别是魔数0x55和0xaa,BIOS便认为此扇区中确实存在可执行的程序,便加载到物理地址0x7c00,随后跳转到此地址,继续执行。


为什么是0盘0道1扇区的内容
这是磁盘的第一个扇区,离BIOS近,好找
为什么是物理地址0x7c00
BIOS规范
加载MBR的位置取决于操作系统本身所占内存大小和内存布局。

编写MBR

MBR的大小必须是512字节(每个扇区大小是512字节),这是为了保证0x55和0xaa这两个魔数恰好出现在该扇区的最后两个字节处,即第510字节处和511字节处,这是按起始偏移为0 算起的。由于bochs模拟的是x86平台,所以是小端字节序,故其最后两个字节内容是0xaa55。

$ , $$, section

$ 属于“隐式地”藏在本行代码前的标号,也就是编译器给当前行安排的地址。
$$指代本section的起始地址,此地址同样是编译器给安排的。
在默认情况下,它们的值是相对于本文件开头的偏移量。如果该section用来vstart=xxxx修饰, $ $的值则是此section的虚拟起始地址xxxx。 $的值是以xxxx为起始地址的顺延。如果没有定义section,nasm默认全部代码同为一个section,起始地址为0。



section是给开发人员逻辑上规划代码用的,只起到思路清晰的作用,最终还是在编译阶段由nasm在物理上的规划说了算。

NASM 简单用法

nasm的基本用法格式如下,-f是用来指定输出可执行文件的格式,-o是指定输出可执行文件的名称,nasm -hf可以查看有效格式,bin是默认输出格式(不需要用-f)



MBR

代码功能:在屏幕上打印字符串“1 MBR”,背景色为黑色,前景色为绿色

设置程序起始地址,BIOS通过跳转到地址0x7c00

SECTION MBR vstart=0x7c00

用cs寄存器的值去初始化其他寄存器,cs的值赋值给ax,ax赋值给其他寄存器(CPU不能直接给它们赋值),此时cs=0

mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax

初始化栈指针

mov sp,0x7c00

清屏。先把BIOS的输出清掉

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 ; 左上角: (0, 0)
mov dx, 0x184f ; 右下角: (80,25),
; VGA 文本模式中,一行只能容纳 80 个字符,共 25 行。
; 下标从 0 开始,所以 0x18=24,0x4f=79
int 0x10 ; int 0x10

获取光标位置,避免打印字符混乱,覆盖别人的输入

;.get_cursor 获取当前光标位置,在光标位置处打印字符。
mov ah, 3 ; 输入: 3 号子功能是获取光标位置,需要存入 ah 寄存器
mov bh, 0 ; bh 寄存器存储的是待获取光标的页号,第0页int 0x10 ; 输出: ch=光标开始行,cl=光标结束行
; dh=光标所在行号,dl=光标所在列号

往光标处打印字符

;还是用 10h 中断,不过这次调用 13 号子功能打印字符串
mov ax, message
mov bp, ax ; es:bp 为串首地址,es 此时同 cs 一致,
; 开头时已经为 sreg 初始化; 光标位置要用到 dx 寄存器中内容,cx 中的光标位置可忽略
mov cx, 5 ; cx 为串长度,不包括结束符 0 的字符个数
mov ax, 0x1301 ;子功能号 13 显示字符及属性,要存入 ah 寄存器,
; al 设置写字符方式 ah=01: 显示字符串,光标跟随移动
;(1)al=0,显示字符串,并且光标返回起始位置。
;(2)al=1,显示字符串,并且光标跟随到新位置。
;(3)al=2,显示字符串及其属性,并且光标返回起始位置。
;(4)al=3,显示字符串及其属性,光标跟随到新位置。
mov bx, 0x2 ; bh 存储要显示的页号,此处是第 0 页,
; bl 中是字符属性,属性黑底绿字(bl = 02h)
int 0x10 ; 执行 BIOS 0x10 号中断

死循环。$是本行执行指令地址, $是jmp自己的地址,一直跳自己的地址,死循环

jmp $ ; 使程序悬停在此

定义打印的字符串

message db "1 MBR"

用0将本扇区剩余空间填满
$ $是指本section的起始地址, $- $ $是本行到本section的偏移量。由于MBR最后两个字节是固定内容,分别是0x55和0xaa,要预留出2个字节,故本扇区内前512-2=510字节要填满,用510字节减去上面得到的偏移量,其结果便是本扇区内的剩余量,也就是要填充的字节。

times 510-($-$$) db 0
;主引导程序
;------------------------------------------------------------
SECTION MBR vstart=0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
; 清屏利用 0x06 号功能,上卷全部行,则可清屏。
; -----------------------------------------------------------
;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 ; 左上角: (0, 0)
mov dx, 0x184f ; 右下角: (80,25),
; VGA 文本模式中,一行只能容纳 80 个字符,共 25 行。
; 下标从 0 开始,所以 0x18=24,0x4f=79
int 0x10 ; int 0x10;;;;;;;;; 下面这三行代码获取光标位置 ;;;;;;;;;
;.get_cursor 获取当前光标位置,在光标位置处打印字符。
mov ah, 3 ; 输入: 3 号子功能是获取光标位置,需要存入 ah 寄存器
mov bh, 0 ; bh 寄存器存储的是待获取光标的页号int 0x10 ; 输出: ch=光标开始行,cl=光标结束行
; dh=光标所在行号,dl=光标所在列号;;;;;;;;; 获取光标位置结束 ;;;;;;;;;;;;;;;;;;;;;;;;; 打印字符串 ;;;;;;;;;;;
;还是用 10h 中断,不过这次调用 13 号子功能打印字符串
mov ax, message
mov bp, ax ; es:bp 为串首地址,es 此时同 cs 一致,
; 开头时已经为 sreg 初始化; 光标位置要用到 dx 寄存器中内容,cx 中的光标位置可忽略
mov cx, 5 ; cx 为串长度,不包括结束符 0 的字符个数
mov ax, 0x1301 ;子功能号 13 显示字符及属性,要存入 ah 寄存器,
; al 设置写字符方式 ah=01: 显示字符串,光标跟随移动
;(1)al=0,显示字符串,并且光标返回起始位置。
;(2)al=1,显示字符串,并且光标跟随到新位置。
;(3)al=2,显示字符串及其属性,并且光标返回起始位置。
;(4)al=3,显示字符串及其属性,光标跟随到新位置。
mov bx, 0x2 ; bh 存储要显示的页号,此处是第 0 页,
; bl 中是字符属性,属性黑底绿字(bl = 02h)
int 0x10 ; 执行 BIOS 0x10 号中断
;;;;;;;;; 打字字符串结束 ;;;;;;;;;;;;;;;jmp $ ; 使程序悬停在此message db "1 MBR"
times 510-($-$$) db 0
db 0x55,0xaa

本段关于“打印显示”的操作都利用BIOS给我们建立好的例程,0x10号中断就是负责有关打印的例程。
0x10中断是最为强大的BIOS中断,调用的方法是把功能号送入ah寄存器,其他参数按照BIOS中断手册要求放在适当的寄存器中,随后执行int 0x10即可。

编译汇编代码

nasm mbr.S -ombr.bin

查看刚才编译好的mbr.bin
正好是512字节

ls -lb mbr.bin

Linux命令:dd。用于磁盘操作的命令。

将MBR文件写入0盘0道1扇区

sudo rm -f hd60M.img.lock
dd if=mbr.bin of=hd60M.img ibs=512 count=1 conv=notrunc



启动bochs

bochs -f bochsrc

第二章 编写MBR主引导记录相关推荐

  1. 《操作系统真象还原》第二章 编写MBR主引导记录,让我们开始掌权

    配合视频学习效果更好!https://www.bilibili.com/video/BV15o4y157Wm/?vd_source=701807c4f8684b13e922d0a8b116af31 仓 ...

  2. 《操作系统真象还原》第二章 ---- 编写MBR主引导记录 初尝编写的快乐 雏形已显!

    文章目录 专栏博客链接 前引 相关术语 理清操作系统启动程序运行流程(部分) 编写MBR引导内容 编译并检验mbr.bin Linux dd 磁盘操作指令与参数 模拟操作试一试 结束语 专栏博客链接 ...

  3. 《操作系统真象还原》第二章 ---- 编写MBR主引导记录 初尝编写的快乐

    书接上回安装bochs后出现No bootable device 这回我们要自己写一个MBR. 首先我们再linux系统里面需要下载一个编译器,nasm 在命令行窗口输入sudo apt-get in ...

  4. 《真象还原》读书笔记——第二章 编写 MBR 主引导记录

    2.1 计算机的启动过程 开机后运行的第一个程序是 BIOS . BIOS 搬运 MBR 并 跳转运行 MBR- 2.2 软件接力第一棒 BIOS 全名 基本输入输出系统. 2.2.1 实模式下的 1 ...

  5. 编写 MBR 主引导记录

    文章目录 前言 mbs.S代码 实验操作 前言 本博客记录<操作系统真象还原>第二章最后一节的实验操作~ 实验需要安装Bochs软件,具体可食用Bochs下载安装博客. 实验环境:ubun ...

  6. 操作系统真象还原第2章:编写MBR主引导记录

    前言 这章的内容挺少的,也很简单,如果环境没配置错的话是没啥问题的.但是这章也很精彩,把引导的过程给说了出来,我也是看了几遍把这个过程给大致看懂了. 首先计算机一开机这个时cpu会自动把cs:ip指针 ...

  7. 【收藏】FAT文件系统原理——MBR(主引导记录

    FAT文件系统原理--MBR(主引导记录) 一.硬盘的物理结构:          硬盘存储数据是根据电.磁转换原理实现的.硬盘由一个或几个表面镀有磁性物质的金属或玻璃等物质盘片以及盘片两面所安装的磁 ...

  8. MBR“主引导记录”的局限性与GPT GUID分区表的优势

    MBR"主引导记录"的局限性与GPT GUID分区表的优势 MBR的局限性 MBR的意.思是"主引导记录",最早在.1983年在IBM PC DOS2.0中提出 ...

  9. LINUX系统修复 ---- mbr主引导记录的恢复

    在系统启动的过程中,主引导记录是不可或缺的一部分,如果MBR遭受到破坏,系统便无法找到/boot分区,启动不起来了,这个时候我们应该怎么办呢???我们可以怎样恢复呢??? 磁盘引导阶段 ------- ...

最新文章

  1. 快应用开发常见问题以及解决方案【持续更新】
  2. gateway 内存溢出问题_带你学习jvm java虚拟机 arthas/性能调优/故障排除/gc回收/内存溢出等...
  3. python小白-day4递归和算法基础
  4. 理解Go语言中的方法和接收者
  5. 【集合之HashMap】HashMap实现原理及非线程安全原因
  6. 编写一个猜数字游戏程序:
  7. php面向对象链,php面向对象之链式操作
  8. linux打包解压工具,linux下的解压,打包工具
  9. 同义词转换不再有效_1秒变电脑,手机吃鸡新体验,北通E1键鼠转换器上手体验!...
  10. 网站小图标制作及配置
  11. excel同一单元格怎么换行_自动换行还是强制换行?还有一键批量换行等着你
  12. MTK Camera HAL到驱动的流程总结一
  13. 在第一列前面、中间、后面插入字符串
  14. 我喜欢的学科计算机 英文作文,我喜欢的学科写英语作文40字
  15. Hazelcast IMDGJet详解
  16. DNS服务(域名系统、过程、bind、配置文件、查看本设备dns)
  17. [RFID]IC卡克隆(四)Proxmark3全卡克隆已解密的IC卡
  18. pytcuda学习笔记(一)
  19. %@ Page% page指令属性
  20. 编译安装mysql5.5

热门文章

  1. 普元EOS7.5,finishworkitem结束工作项报java.lang.NumberFormatException异常
  2. Cmake安装以及升级(Ubuntu)
  3. 如何更改excel直线拟合有效数字的位数
  4. 【电影推荐系统】部署要点总结
  5. kettle将文件路径定义为_kettle学习笔记(三)——kettle资源库、运行方式与日志...
  6. 活着的每一天都是特别的日子
  7. 别翻了,程序员必学十大经典排序算法,看这篇就够了
  8. 《数据结构 C++ 语言描述》电子书下载 -(百度网盘 高清版PDF格式)
  9. 在Grasshopper中使用C#开发之(一)——C#调用Grasshopper中的电池
  10. lisp 河道水面线计算_天然河道水面线推求自动计算1.2