学习操作系统原理最好的方法是自己写一个简单的操作系统。


前面我们介绍过电脑的启动过程:

上电->BIOS->MBR(boot)->loader->kernel->交互界面(图形/命令行)

本讲我们要介绍的是MBR(Master Boot Record,主引导记录)。在电脑中对磁盘的读写是按扇区为基本单位的,一般每个扇区为512个字节。也就是说每读一次磁盘,读取的字节数是512字节的整数倍。同样每写一次磁盘,写入的字节数也是512字节的整数倍。MBR是磁盘的第一个扇区,又叫做主引导扇区,特点是最后2个字节的内容必须是0x55和0xAA。

下面我们来做几个实验来加深对MBR的了解。

1.不加载虚拟磁盘启动QEMU

Windows键+R键打开运行窗口,输入cmd并回车打开命令行窗口。

在命令行中输入qemu-system-i386并回车:

此时会打开QEMU窗口:

注意最后会输出一行话“No bootable device.”,意思是没有可引导启动的设备。

2.创建空虚拟硬盘

在CentOS中我们输入如下一行命令:

dd if=/dev/zero of=/media/VMShare/GrapeOS.img bs=1M count=4

dd命令简单来说是一个复制命令。参数if是指input file输入文件,参数of是指output file输出文件,意思就是将输入文件复制到输出文件中。这里的输入文件/dev/zero是Linux中的一个特殊文件,它可以提供无限的零。参数bs表示一次复制多少字节数据,也就是一个数据块的大小,count表示复制多少个块。bs乘以count表示总共复制多少数据,我们这里总共复制1M4=4M数据。运行上面这行命令的结果就是生成了一个4M大小的文件GrapeOS.img,该文件中每个字节都是0。截图如下:

由于GrapeOS.img是在Windows和CentOS的共享文件夹中,所以我们在Windows也能看到:

每个字节都是0的文件也叫空白文件,我们下面用hexdump命令来验证一下:

hexdump GrapeOS.img -C

从上面的截图可以看到GrapeOS.img这个文件中每个字节都是0。

3.加载空虚拟硬盘启动QEMU

在cmd命令行中输入如下命令:

qemu-system-i386 d:\GrapeOS\VMShare\GrapeOS.img

上面这行命令是为QEMU指定虚拟硬盘文件并启动QEMU。截图如下:

从上面截图可以看到,虽然给QEMU指定了虚拟硬盘,但最后的提示还是“No bootable device.”

4.将虚拟硬盘的第一个扇区变为MBR

我们在Lesson11文件夹下新建文件mbr.asm,并输入如下代码:

;生成一个空的MBR
times 510 db 0 ;前510个字节全为0
db 0x55,0xaa ;最后两个字节是0x55和0xaa。

在VSCode中的截图如下:

使用nasm汇编器汇编:

nasm mbr.asm -o mbr.bin

从上面的截图我们看到,生成了一个叫mbr.bin的文件,大小为512字节。下面来看一下mbr.bin文件中的数据:

hexdump mbr.bin -C

从上图可以看到mbr.bin文件中共512字节,除最后2个字节是0x55和0xaa,其它字节都是0。

下面我们将mbr.bin写入到虚拟硬盘文件的头512个字节中:

dd conv=notrunc if=mbr.bin of=/media/VMShare/GrapeOS.img

上面这里命令中多了个参数conv=notrunc,表示不截断。如果不写该参数,执行完命令,GrapeOS.img就只剩512字节了。

执行完上面这行命令,我们验证一下是否写入成功:

hexdump /media/VMShare/GrapeOS.img -C

从上面截图可以看到总共4MB的文件,其中第511个字节为0x55,第512个字节0xaa,其它字节都为0。此时虚拟硬盘GrapeOS.img中第一个扇区已经是MBR了。

5.加载带MBR的虚拟硬盘启动QEMU

在cmd命令行中输入和刚才一样的命令:

qemu-system-i386 d:\GrapeOS\VMShare\GrapeOS.img

截图如下:

从上面的截图中可以看到,在QEMU中的提示信息已经和刚才不一样了。最后一行显示的是“Booting from Hard Disk...”,意思是从硬盘启动中,也就是说程序已经从BIOS跳转到MBR了。

通过上面的实验我们证明只要磁盘第一个扇区中的最后两个字节是0x55和0xaa,BIOS就会认为该扇区是一个有效的MBR,同时认为该磁盘是一个有效的启动项。

如果大家的实验做到这里会发现CPU占用率高,如果是笔记本电脑能听到CPU风扇呼呼的转。这是因为CPU跑飞了,我们后面会解决这个问题。

本讲小结:BIOS将电脑的控制权交棒给了MBR,我们可以在MBR中写程序,MBR是我们程序的起点,之后电脑的运行都由我们来控制。


本讲对应的视频版地址:https://www.bilibili.com/video/BV1pe4y1w7Co/

GrapeOS操作系统交流QQ群:643474045

自己动手从零写桌面操作系统GrapeOS系列教程——11.MBR介绍的更多相关文章

  1. 《一步一步写嵌入式操作系统》读书笔记1—Skyeye介绍、安装和HelloWorld

    2013-11-14 最近在看<一步一步写嵌入式操作系统>,感觉此书甚好,许多地方讲得很清楚.可操作性强,计划边读边实践边写笔记,希望能够逐步熟悉嵌入式操作系统底层的东西,最终剪裁出一套实 ...

  2. 别人写的一个Bootstrap系列教程

    http://www.cnblogs.com/lansy/category/659061.html

  3. 一个人写的操作系统 - Sparrow OS

    一个人写的操作系统 - Sparrow OS 自己写一个操作系统,这是在过去的几年里我一直为之努力的目标,现在终于完成了. 缘起 自己动手写操作系统的动机最初来自于学习Linux遇到的困难. 我是一个 ...

  4. 自制 os 极简教程1:写一个操作系统有多难

    为什么叫极简教程呢?听我慢慢说 不知道正在阅读本文的你,是否是因为想自己动手写一个操作系统.我觉得可能每个程序员都有个操作系统梦,或许是想亲自动手写出来一个,或许是想彻底吃透操作系统的知识.不论是为了 ...

  5. 【操作系统】关于Linux桌面操作系统

    以前是Win+Ubuntu+黑苹果,周末想体验一下deepin,于是简单安装了一下,安装过程很简单,这里不再描述.安装之后,第一次打开系统,确实很惊艳,赏心悦目的操作系统. 之前用Ubuntu时候,C ...

  6. 盘点|2021年最受欢迎Linux桌面操作系统前十名

    镜像下载.域名解析.时间同步请点击 阿里云开源镜像站 阿里云开源镜像站利用云服务上的优势,提供快速.稳定的镜像分发服务.和免费的CDN加速服务.更新频率高,基本上一天一更新,对于Centos/Ubun ...

  7. 手把手教你从零写一个简单的 VUE

    本系列是一个教程,下面贴下目录~1.手把手教你从零写一个简单的 VUE2.手把手教你从零写一个简单的 VUE--模板篇 今天给大家带来的是实现一个简单的类似 VUE 一样的前端框架,VUE 框架现在应 ...

  8. Python之美[从菜鸟到高手]--一步一步动手给Python写扩展(异常处理和引用计数)

    我们将继续一步一步动手给Python写扩展,通过上一篇我们学习了如何写扩展,本篇将介绍一些高级话题,如异常,引用计数问题等.强烈建议先看上一篇,Python之美[从菜鸟到高手]--一步一步动手给Pyt ...

  9. Zedboard学习(一):移植Ubuntu桌面操作系统 标签: ubuntu移植zedboardFPGA 2017-07-04 21:53 26人阅读

    环境准备: 首先,需要的肯定是Ubuntu操作系统.可以在自己的电脑上安装物理机,也可以是虚拟机下运行的.我的是在Vmware下运行的Ubuntu14.04 32位操作系统. 由于zedboard上的 ...

  10. 27、从零写UVC驱动之分析数据传输(设置ubuntu通过串口打印,指定打印到文件,ubuntu切换root用户)

    A. 设置ubuntu让它从串口0输出printk信息a. 设置vmware添加serial port, 使用文件作为串口(在vmware中设置,文件是保存在windows中)b. 启动ubuntu, ...

随机推荐

  1. 2022-4-7内部群每日三题-清辉PMP

    1.公司聘用一名项目经理来协调一个期限紧迫的敏捷项目,项目经理和敏捷团队都由一位项目组合经理管理,该项目组合经理倾向于根据需要将开发人员重新分配给其他紧急事项,当项目经理与其接洽时,项目组合经理坚持认 ...

  2. kubernetes中 flannel网络组件

    Flannel 软件包地址:https://github.com/coreos/flannel Flannel是CoreOS开源的CNI网络插件,下图flannel官网提供的一个数据包经过封包.传输以 ...

  3. docker 搭建mysql主从复制环境(一主两从)

    一主多从配置 服务器规划:使用docker方式创建,主从服务器IP一致,端口号不一致 主服务器:容器名docker-mysql-master,端口3306 从服务器:容器名docker-mysql-s ...

  4. Flink配置详解及实践

    #jobManager的IP地址jobmanager.rpc.address: localhost #JobManager的端口号jobmanager.rpc.port: 6123 # JobMana ...

  5. 「SOL」序列 (LOJ/NOI2019)

    准备写新博客的时候发现自己草稿箱里还有一篇咕了十几天的题解 思路挂在了费用流之前-- 题面 > Link LOJ #3158 解析 这道题的本质是一个二分图带权匹配的问题,一个经典的做法是直接做 ...

  6. Delphi线程中使用waitfor返回值

    使用waitfor的时候就不要再设置Freeonterminated属性了,否则会提示线程句柄错误.主要是里面使用了ExitThread方法,当线程方法执行完毕后会自动释放线程的.不过记得要重写Des ...

  7. 网络IO模型_01

    4种情况: 1.输入操作:等待数据到达套接字接收缓冲区: 2.输出操作:等待套接字发送缓冲区有足够的空间容纳将要发送的数据: 3.服务器接收连接请求:等待新的客户端连接请求的到来: 4.客户端发送连接 ...

  8. 基于python-nmap的扫描代码

    本次代码只利于人员进行分析,没有啥用,小学期作业,被迫工作. 1 import tkinter 2 from tkinter import * 3 import time 4 import nmap ...

  9. html 手机端适配不同手机高度 ,把内容居中显示

    手机端适配不同手机高度 ,把内容居中显示,可以将div.img.section.span.p等等元素,设置 top:50%; margin-top:xxvw; 这样可以保证主题内容居中显示.

  10. Debug --> python list.sort()食用方法

    list.sort(key=lambda x:x[1] , reverse=True) 参数 key 指明按照什么进行排序.lambda是匿名函数,参数的第一个x表示列表的第一个元素,如表示列表中的元 ...