[自制操作系统] 第02回 初识MBR
一、前景回顾
上回说到,开机的启动过程就是当时Intel和BIOS等硬件厂商所制定的规则,现在我们来回顾一下有如下三点:
1、按下开机键后,CPU将cs:ip寄存器初始化为0xf000:0xfff0,这个位置是BIOS程序的入口处,这个位置存放的代码是jmp far f000:e05b,通过这行代码CPU又将cs:ip寄存器初始化为0xf000:0xe05b,这里才是BIOS真正开始执行的地方。
2、BIOS执行了一系列的硬件检测工作和创建中断向量表IVT后,将MBR(主引导记录)加载到内存0x7c00处,并且跳转到该位置,也就是将cs:ip寄存器初始化为0x0000:0x7c00。
3、MBR的工作是加载操作系统内核,最后跳转到操作系统内核中,随后便是熟悉的启动动画,也就完成了开机过程。
二、写一个粗略的MBR
新建一个mbr.S的文件,键入如下代码:
1 SECTION MBR vstart=0x7c00
2 mov ax,cs
3 mov ds,ax
4 mov es,ax
5 mov ss,ax
6 mov fs,ax
7 mov sp,0x7c00
8 mov ax,0xb800
9 mov gs,ax
10
11 ;利用int 0x10 的0x06号功能实现清屏
12 mov ax,0x600
13 mov bx,0x700
14 mov cx,0
15 mov dx,0x184f
16
17 int 0x10
18
19 ;获取当前光标位置
20 mov ah,3
21 mov bh,0
22
23 int 0x10
24 ;输出字符串“HELLO MBR”
25 mov ax, message
26 mov bp, ax
27 mov cx, 9
28 mov ax, 0x1301
29 mov bx, 0x2
30 int 0x10
31
32 jmp $ ;使CPU悬停在此
33
34 message db "HELLO MBR"
35 times 510-($-$$) db 0
36 db 0x55,0xaa
mbr.S
第1行的“vstart = 0x7c00”表示该程序在编译的时候,告诉编译器将我的起始地址编译为0x7c00。
第2~6行,因为BIOS是通过jmp 0:0x7c00的方式跳转到MBR中的,所以此时cs为0。而CPU中的段寄存器不能通过立即数来对它们赋值,因此只能通过其他寄存器来对它们初始化,这里先将cs寄存器的值赋给ax,再使用ax来初始化其他段寄存器。
MBR也是程序,是程序就需要栈,而我们的程序被加载到0x7c00处,0x7c00以下的区域暂时没被使用,所以先将栈顶设为0x7c00。
第11~30行中的代码便是清屏和打印字符,这里只是为了测试使用,没有什么实际意义。
第32行,我们通过jmp $指令让CPU一直跳转执行该行,也就是c语言中的“while(1);”作用,因为后面的区域没有可供CPU执行的代码,所以为了避免CPU跑偏,现在先让它一直在此死循环。
第34~36行,我们现在构建的MBR,最终的目的是希望被BIOS访问并且加载到地址0x7c00处。因此回顾前面的内容,要想让BIOS相信这就是它苦苦寻找的东西,那我们就要让我们的MBR符合要求,也就是代码最后两个字节是0x55和0xaa,并且整个MBR的大小必须是512字节。所以这里使用“times 510 - ($ - $$)db 0”来将前510个地址中为空的地址处全部填为0,随后再单独给最后的两个字节设置为0x55和0xaa。
一切就绪工作完成后,使用nasm来编译汇编代码,输入如下代码,便可以在当前目录下得到mbr.bin文件。
nasm mbr.S -o mbr.bin
使用ls命令来查看一下生成的bin文件的大小。
ls -lb mbr.bin
结果如下:
可以看到mbr.bin的大小的确是512字节,那么接下来就通过dd命令来将mbr.bin文件写入到我们前面创建的磁盘hd60M.img中:
dd if=./mbr.bin of=./hd60M.img bs=512 count=1 conv=notrunc
写入成功后会有如下输出:
这一步过后,我们便可以开始准备运行测试。
三、运行测试
启动bochs测试一下,我是在bochs的安装目录下启动的,输入 ./bin/bochs -f bochsrc.disk 回车,默认[6]开始模拟,再按回车。随后在出现的控制台中按下c,bochs便开始运行起来了。
当MBR成功被加载并且运行起来后,在屏幕上我们会看到预先设置的字符串“HELLO MBR”在不停的闪烁,到此也就说明我们编写的MBR没有问题。
现在我们已经初步实现了一个简单的MBR,只不过这个MBR没有什么实质性作用。下面我们将会完善这个MBR,只是在完善MBR之前,我们还需要做一件更重要的事。欲知后事如何,请看下回分解。
[自制操作系统] 第02回 初识MBR的更多相关文章
- [自制操作系统] 第04回 完善MBR
目录 一.前景回顾 二.改写MBR 三.实现loader 一.前景回顾 在之前我们说到,MBR的作用便是加载操作系统内核到指定位置.而MBR需要通过读取硬盘来获得操作系统内核.在上一回我们已经讲解了硬 ...
- [自制操作系统] 第05回 CPU的三种模式
目录 一.前景回顾 二.实模式和保护模式 一.前景回顾 在之前我们说到,loader的作用才是读取加载操作系统内核,那么我们的重心就应该是loader.S文件,其实我们接下来也的确是会往loader. ...
- 《30天自制操作系统》笔记(02)——导入C语言
<30天自制操作系统>笔记(02)——导入C语言 进度回顾 在上一篇,记录了计算机开机时加载IPL程序(initial program loader,一个nas汇编程序)的情况,包括IPL ...
- 【自制操作系统06】终于开始用 C 语言了,第一行内核代码!
一.整理下到目前为止的流程图 写到这,终于才把一些苦力活都干完了,也终于到了我们的内核代码部分,也终于开始第一次用 c 语言写代码了!为了这个阶段性的胜利,以及更好地进入内核部分,下图贴一张到目前为止 ...
- 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!
<30天自制操作系统>笔记(01)——hello bitzhuwei's OS! 最初的OS代码 ; hello-os ; TAB=4 ORG 0x7c00 ; 指明程序的装载地址 ; 以 ...
- 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!【转】
转自:http://www.cnblogs.com/bitzhuwei/p/OS-in-30-days-01-hello-bitzhuwei-OS.html 阅读目录(Content) 最初的OS代码 ...
- 30天自制操作系统-day1
30天自制操作系统(linux环境)--第一天 我是在CentOS的环境上面实现的,使用ubuntu的环境也是类似的 第一步:因为要对二进制文件进行编辑,所以安装二进制编辑器hexedit(当然其他的 ...
- 《30天自制操作系统》笔记(06)——CPU的32位模式
<30天自制操作系统>笔记(06)——CPU的32位模式 进度回顾 上一篇中实现了启用鼠标.键盘的功能.屏幕上会显示出用户按键.点击鼠标的情况.这是通过设置硬件的中断函数实现的,可以说硬件 ...
- 《30天自制操作系统》笔记(03)——使用Vmware
<30天自制操作系统>笔记(03)——使用Vmware 进度回顾 在上一篇,实现了用IPL加载OS程序到内存,然后JMP到OS程序这一功能:并且总结出下一步的OS开发结构.但是遇到了真机测 ...
随机推荐
- spring-bean依赖注入-03
set注入:set注入地址 通过构造方法进行注入 1.创建UserDao接口以及UserDaoImpl实现类(接口代码省略) public class UserDaoImpl implements U ...
- zabbix自定义自动发现模板
需求: 自定义发现磁盘io,并实现监控.其他的业务组件自动发现监控其实也和这个大同小异,自动发现主要逻辑就是你要根据组件规则自动匹配出需要监控的所有组件,再通过传参的方式获取对应组件数据. 自动发现无 ...
- MySQL 的发展历史和版本分支
时间和里程碑 想查看之前的版本可以从这里找到mysql4,5,8等版本http://mirrors.sohu.com/mysql/下面简单回顾下相关的一些版本信息1996 年 MySQL 1.0 发布 ...
- mybatis在if标签里判断字符串相等
https://www.cnblogs.com/westward/p/6910856.html
- 5.Java程序运行机制
一.编译型和解释型语言区别 计算机是不能理解高级语言的,更不能直接执行高级语言,它只能直接理解机器语言,所以任何的高级语言编写的程序都必须转换成计算机语言,也就是机器码.而这种转换的方式有两种: 编译 ...
- insert语句生成的存储过程
问题: 1.如何配置数据库数据: 方式一:图形界面点击输入数据,导出成sql. 缺点:表多,数据多的时候非常繁琐,字段含义需要另外开窗口对照. 方式二:徒手写或者修改已有语句:insert table ...
- 2022年最新Cloudflare免费自选IP教程(非Partner)
写在开头 众所周知,CF在去年底大规模禁用Host API key,使得Partner自选法失效.但最近,Cloudflare为所有计划添加了100个SaaS域免费额度(以前$2一个). 经过一番摸索 ...
- [题解] 序列(sequence)
题目大意 给定一个长度为 \(N\) 的非负整数序列 \(A_1,A_2, \ldots ,A_N\),和一个正整数 \(M\).序列 \(A\) 满足 \(\forall 1 \le i \ ...
- Unreal 输入系统 解析
前言 输入系统,输入某个键,响应到GamePlay层做对应的事.例如 点击鼠标,前进还是开枪之类,是如何响应的.这里只说应用层逻辑,硬件层逻辑不讲述. 详解 1.问题来源 先看下面一个例子:跳跃的事件 ...
- 交换机POE技术知识大全
公众号关注 「开源Linux」 回复「学习」,有我为您特别筛选的学习资料~ 一个典型的以太网供电系统,在配线柜里保留以太网交换机设备,用一个带电源供电集线器(Midspan HUB)给局域网的双绞线提 ...