一步步编写操作系统 09 写个mbr

有点不好意思了,说了好久,才说到实质性的东西,好了,赶紧给客官上菜。

代码2-1(c2/a/boot/mbr.S)1 ;主引导程序2 ;------------------------------------------------------------3 SECTION MBR vstart=0x7c004 mov ax,cs5 mov ds,ax6 mov es,ax7 mov ss,ax8 mov fs,ax9 mov sp,0x7c001011 ; 清屏 利用0x06号功能,上卷全部行,则可清屏。12 ; -----------------------------------------------------------13 ;INT 0x10 功能号:0x06 功能描述:上卷窗口14 ;------------------------------------------------------15 ;输入:16 ;AH 功能号= 0x0617 ;AL = 上卷的行数(如果为0,表示全部)18 ;BH = 上卷行属性19 ;(CL,CH) = 窗口左上角的(X,Y)位置20 ;(DL,DH) = 窗口右下角的(X,Y)位置21 ;无返回值:22 mov ax, 0x60023 mov bx, 0x70024 mov cx, 0 ; 左上角: (0, 0)25 mov dx, 0x184f ; 右下角: (80,25),26 ; VGA文本模式中,一行只能容纳80个字符,共25行。27 ; 下标从0开始,所以0x18=24,0x4f=7928 int 0x10 ; int 0x102930 ;;;;;;;;; 下面这三行代码是获取光标位置 ;;;;;;;;;31 ;.get_cursor获取当前光标位置,在光标位置处打印字符.32 mov ah, 3 ; 输入: 3号子功能是获取光标位置,需要存入ah寄存器33 mov bh, 0 ; bh寄存器存储的是待获取光标的页号3435 int 0x10 ; 输出: ch=光标开始行,cl=光标结束行36 ; dh=光标所在行号,dl=光标所在列号3738 ;;;;;;;;; 获取光标位置结束 ;;;;;;;;;;;;;;;;3940 ;;;;;;;;; 打印字符串 ;;;;;;;;;;;41 ;还是用10h中断,不过这次是调用13号子功能打印字符串42 mov ax, message43 mov bp, ax ; es:bp 为串首地址, es此时同cs一致,44 ; 开头时已经为sreg初始化4546 ; 光标位置要用到dx寄存器中内容,cx中的光标位置可忽略47 mov cx, 5 ; cx 为串长度,不包括结束符0的字符个数48 mov ax, 0x1301 ;子功能号13是显示字符及属性,要存入ah寄存器,49 ; al设置写字符方式 ah=01: 显示字符串,光标跟随移动50 mov bx, 0x2 ; bh存储要显示的页号,此处是第0页,51 ; bl中是字符属性, 属性黑底绿字(bl = 02h)52 int 0x10 ; 执行BIOS 0x10 号中断53 ;;;;;;;;; 打字字符串结束 ;;;;;;;;;;;;;;;5455 jmp $ ; 使程序悬停在此5657 message db "1 MBR"58 times 510-($-$$) db 059 db 0x55,0xaa

简短说一下代码功能,在屏幕上打印字符串“1 MBR”,背景色为黑色,前景色为绿色。

由于还没有给大家讲解显卡的使用方法,故本段代码中关于“打印显示”的操作都利用bios给我们建立好的例程就好了,这里第0x10号中断便是负责有关打印的例程。

0x10中断是最为强大的bios中断了,调用的方法是把功能号送入ah寄存器,其它参数按照bios中断手册的要求放在适当的寄存器中,随后执行int 0x10即可。我们不用太细致琢磨bios功能调用了,大家可以参数代码中的注释了解下即可,毕竟咱们这里用bios中断只是临时的,以后也用不到了。第3行的“vstart=0x7c00”表示本程序在编译时,告诉编译器,把我的起始地址编译为0x7c00。第4~8行是用cs寄存器的值去初始化其它寄存器。由于bios是通过jmp 0:0x7c00跳转到MBR的,故cs此时为0。对于ds、es、fs、gs这类sreg,cpu中不能直接给它们赋值,没有从立即数到段寄存器的电路实现。只有通过其它寄存器来中转,这里我们用的是通用寄存器ax来中转。如mov ds: 0x7c00,这样就错了。

第9行是初始化栈指针,在cpu上运行的程序得遵从cpu的规则,mbr也是程序,是程序就要用到栈。目前0x7c00以下暂时是安全的区域,就用它来当做栈来用。第11~28行是清屏。因为在bios工作中,会有一些输出,如检测硬件的结果信息。为了让大家看清楚我们在MBR中的输出字符串,故先把bios的输出清掉,这里演示的是bios中断int 0x10的用法。第30~35行是做打印前的工作,先获取光标位置,目的是避免打印字符混乱,覆盖别人的输出。其实这是防君子不防小人的做法,万一别人不在光标处打印,自己打印的内容同样也会被别人覆盖。不管别人了,咱们做好自己的就行,老老实实地只在光标处打印。不知道这是否能提醒大家,字符打印的位置,不一定要在光标处,字符的位置只和显存中的地址有关,和光标是没关系的,这只是人为的加个约束,毕竟光标在视觉上告诉了我们当前字符写到哪里了,完全是为了好看,不要以为光标就是新打印字符的位置。更多细节,以后讲显卡时会提到。

这里还用到了页的概念,您看第33行,往bh寄存器中写入了0,这是告诉bios例程,我要获取第0页当前的光标。什么是页呢?显示器有很多种模式,如图形模式、文本模式等,在文本模式中,又可以工作于80*25和40*25等显示方式,默认情况下,所有个人计算机上的显卡在加电后都将自己置为80*25这种显示方式。80*25是指一屏可以显示25行、每行80列的字符,也就是2000个字符。但由于一个字符是要用两字节来表示,低字符是字符的ascii编码,高字节是字符属性,故显示一屏字符需要用4000字节(实际上,分配给一屏的容量是4KB),这一屏就称为一页,0页是默认页。

第38行~52行是往光标处打印字符。说一下第48行的mov ax,0x1301,13对应的是ah寄存器,这是调用0x13号子功能。01对应的是al寄存器,表示的是写字符方式,其低2位才有意义,各位功能描述如下:

  1. al=0,显示字符串,并且光标返回起始位置
  2. al=1,显示字符串,并且光标跟随到新位置
  3. al=2,显示字符串及其属性,并且光标返回起始位置。
  4. al=3,显示字符串及其属性,光标跟随到新位置。

第55行是执行了个死循环,$是本行指令的地址,这属于伪指令,是汇编器在编译期间分配的地址。在最终编译出来的程序中,$会被替换为指令实际所在行的地址。jmp是个近跳转,$是jmp自己的地址,于是跳到自己所在的地址再执行自己,又是跳到自己所在的地址再继续执行跳转,这样便实现了死循环。可见cpu可乖了,它只会埋头做事,并不会觉得有什么不妥,靠谱值得依赖^_^。

第57行是定义打印的字符串。第58行的$$是指本section的起始地址,上面说过了$是本行所在的地址,故$-$$是本行到本section的偏移量。由于MBR的最后两个字节是固定的内容,分别是0x55和0xaa,要预留出这2个字节,故本扇区内前512-2=510字节要填填满,那到底要用多少字节才能填满此扇区呢。用510字节减去上面通过$-$$得到的偏移量,其结果便是本扇区内的剩余量,也就是要填充的字节数。由此可见第50行的“times 510-($-$$) db 0”是在用0将本扇区剩余空间填充。

代码说完了,可还有两件大事要做,1是编译,2是如何将编译后的文件存储到0盘0道1扇区中成为MBR,以供bios大神加载之用。

前面介绍了nasm的用法,咱们马上来编译汇编代码。nasm -o mbr.bin mbr.S回车,您看,这样就编译成功了,我连-f都没有指定吧。按理说此文件大小是512字节,咱们用ls命令验证一下:ls -lb mbr.bin回车,以下是ls的输出:

-rw-rw-r--. 1 work work 512 7月 26 21:10 mbr.bin

用过linux的同学对这个输出还是很熟悉的,若头一次用linux的同学也不要慌张,这里面好多的信息并不重要,只要看看中间部分就好了,512,果然是512字节,这下心里踏实了,下一步是考虑如何将此文件写入0盘0道1扇区。

这里再给大家介绍另一个linux命令:dd。dd是用于磁盘操作的命令,功能太强大了,有如穿甲弹一样,可以深入磁盘的任何一个扇区,无坚不摧。所以,它也可以删除linux操作系统自己的文件,是把双刃剑。

还是先看帮助文件,man dd回车,为了节约大家的时间,我只把咱们今后用到的几个选项摘了出来,还是那句话,够用就行了,需要时再学。

if=FILE

read from FILE instead of stdin

此项是指定要读取的文件。

of=FILE

write to FILE instead of stdout

此项是指定把数据输出到哪个文件。

bs=BYTES

read and write BYTES bytes at a time (also see ibs=,obs=)

此项指定块的大小,dd是以块为单位来进行IO操作的,得告诉人家块是多大字节。此项是统计配置了输入块大小ibs和输出块大小obs。这两个可以单独配置。

count=BLOCKS

copy only BLOCKS input blocks

此项是指定拷贝的块数

seek=BLOCKS

skip BLOCKS obs-sized blocks at start of output

此项是指定当我们把块输出到文件时想要跳过多少个块

conv=CONVS

convert the file as per the comma separated symbol list

此项是指定如何转换文件

append append mode (makes sense only for output; conv=notrunc suggested)

这句话建议在追加数据时,conv最好用notrunc方式,也就是不打断文件。

齐了,dd的介绍就到这了,赶紧试验一下这个神奇的工具吧。

dd if=/your_path/mbr.bin of=/your_path/bochs/hd60M.img bs=512 count=1 conv=notrunc

各位看官,请将上面命令行中的your_path替换为您自己的实际路径。

输入文件是刚刚编译出来的mbr.bin,输出是我们虚拟出来的硬盘hd60M.img,块大小指定为512字节,只操作1块,即总共1*512=512字节。由于想写入第0块,所以没用seek指定跳过的块数。执行上面的命令后,会有如下输出:

记录了1+0 的读入

记录了1+0 的写出

512字节(512 B)已复制,0.313312 秒,1.6 kB/秒

这就说明命令执行成功了,mbr.bin已经写进hd60M.img的第0块了。借鉴美国宇航员阿姆斯特朗的一句话:虽然这只是简单的一小步,但却是实现我们自己系统的一大步。记得当初我可是非常激动呢。

启动bochs测试一下,我习惯到bochs安装目录下启动它,bin/bochs –f bochsrc.disk回车,接着会显示如图:

 

默认是[6],开始模拟啦。回车

由于咱们编译的是可调试的版本,所以会停下来,bochs等待咱们键入下一步的命令。见图:

 

大家看到,这一下弹出了两个界面,前面的那个是bochs所模拟的机器,可以认为它就是台电脑了,不仅仅是电脑的显示器。后面的界面是bochs的控制台,咱们控制bochs运行就要在这里输入命令。现在击活后面的bochs控制台,输入字符c后,回车,bochs所模拟的机器就开始运行了。这里键入的c是continue,调试方法同gdb类似,详细的bochs操作方法咱们会在下一章中介绍。

MBR跑起来后,就会出现下面的效果,如图

 

Mbr跑起来了,这可是脱离操作系统的程序哟,写操作系统我们迈出了第一步,加油。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439910.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【2019牛客暑期多校训练营(第二场)- F】Partition problem(dfs,均摊时间优化)

题干: 链接:https://ac.nowcoder.com/acm/contest/882/F 来源:牛客网 Given 2N people, you need to assign each of them into either red team or white team such that each team consists of exactly N people and the total competi…

Apollo进阶课程 ⑮丨Apollo自动定位技术详解—百度无人车定位技术

目录 1.百度无人车定位进化历程 2.百度自动驾驶应用的定位技术 2.1GNSS定位技术 2.2载波定位技术 2.3激光点云定位技术 2.4视觉定位技术 原文链接:进阶课程 ⑮丨Apollo自动定位技术详解—百度无人车定位技术 定位的目的是让自动驾驶汽车找到自身确切位置的方法…

一步步编写操作系统 10 cpu的实模式

cpu的实模式 由于mbr在实模式下工作……什么?什么是实模式?这时候有同学打断了我。我心想,这下好办了……哈哈,没有啦,开个玩笑而已。我们这里所说的实模式其实就是8086 cpu的工作环境、工作方式、工作状态&#xff0…

Ubuntu系统中使用搜狗输入法

今天介绍如何在Ubuntu中使用搜狗输入法。(Ubuntu版本为16.04) 1)登陆搜狗官网选择对应系统的搜狗输入法:http://pinyin.sogou.com/linux。 2)打开下载目录,命令行输入以下命令: sudo dpkg -i …

2.1)深度学习笔记:深度学习的实践层面

目录 1)Train/Dev/Test sets 2)Bias/Variance 3)Regularization(重点) 4)Why regularization reduces overfitting(理解) 5)Dropout Regularization(重点…

一步步编写操作系统 12 代码段、数据段、栈和cpu寄存器的关系

先说下什么是寄存器。 寄存器是一种物理存储元件,只不过它是比一般的存储介质要快,能够跟上cpu的步伐,所以在cpu内部有好多这样的寄存器用来给cpu存取数据。 先简短说这一两句,暂时离开一下主题,咱们先看看相对熟悉一…

【2019牛客暑期多校训练营(第三场)- F】Planting Trees(单调队列,尺取)

题干: 链接:https://ac.nowcoder.com/acm/contest/883/F 来源:牛客网 The semester is finally over and the summer holiday is coming. However, as part of your universitys graduation requirement, you have to take part in some …

Apollo进阶课程⑯丨Apollo感知之旅——感知概貌

原文链接:进阶课程⑯丨Apollo感知之旅——感知概貌 上周阿波君为大家详细介绍了「进阶课程⑮| Apollo无人车自定位技术入门」。 我们人类天生就配备多种传感器,眼睛可以看到周围的环境,耳朵可以用来听,鼻子可以用来嗅,…

一步步编写操作系统 13 栈

栈到底是什么玩意 cpu中有栈段SS寄存器和栈指针SP寄存器,它们是用来指定当前使用的栈的物理地址。换句话说,要想让cpu运行,必须得有栈。栈是什么?干吗用的?本节将给大家一个交待。 还记得数据结构中的栈吗?那是逻辑…

【2019牛客暑期多校训练营(第二场)- E】MAZE(线段树优化dp,dp转矩阵乘法,线段树维护矩阵乘法)

题干: 链接:https://ac.nowcoder.com/acm/contest/882/E?&headNavacm 来源:牛客网 Given a maze with N rows and M columns, where bijb_{ij}bij​ represents the cell on the i-row, j-th column. If bi,j"1"b_{i, j} …

Apollo进阶课程⑰丨Apollo感知之旅——传感器选择和安装

目录 1.激光雷达 2.相机 3.Radar毫米波 4.安装传感器 原文链接:进阶课程⑰丨Apollo感知之旅——传感器选择和安装 上周阿波君为大家详细介绍了「进阶课程⑯ Apollo感知之旅——感知概况」。 传感器是一种检测装置,能感受到被测量的信息,…

2.2)深度学习笔记:优化算法

目录 1)Mini-batch gradient descent(重点) 2)Understanding mini-batch gradient descent 3)Exponentially weighted averages 4)Understanding exponetially weighted averages 5)Bias c…

Apollo进阶课程⑱丨Apollo感知之旅——传感器标定

目录 传感器标定 标定的目的 传感器标定算法 标定案例解析 3D标定间制作 Cmaera-to-Camera外参标定 Lidar-to-Camera外参标定 Lidar-to-Lidar外参标定 Lidar内参标定 Lidar-to-GPS外参标定 自然场景的Lidar-to-Camera外参标定 自然场景的Bifocal Camera外参标定 C…

一步步编写操作系统 15 CPU与外设通信——IO接口,下

既然都说到IO接口了,不知道各位有没有疑问,cpu是怎样访问到IO接口呢?肯定得有个链路吧?什么?有隐约听到有同学开玩笑说:cpu用无线访问其它设备。哈哈,不知道各位听说过没有,无线的终…

Telnet端口连接Linux服务器失败

在ubuntu写了个服务器端口号是666 ,ip地址是192.168.96.129 在windows用telnet无法连接上 首先检查windows telnet服务是否打开 Windows 10操作系统上使用telnet命令(图文)_时间-CSDN博客_windows使用telnet命令 测试网络是否通:…

重磅 | 完备的 AI 学习路线,最详细的资源整理!

本文转自微信公众号:Datawhale(强烈推荐) 原创: AIUnion Datawhale 今天 【导读】 本文由知名开源平台,AI技术平台以及领域专家:Datawhale,ApacheCN,AI有道和黄海广博士联合整理贡献…

Windows/Linux 下使用telnet发送消息

Windows下使用telnet 1.首先打开cmd命令行连接上服务器端口 连不上可以参考这篇 Telnet端口连接Linux服务器失败_m0_46480482的博客-CSDN博客 telnnt <ip地址> <端口号> 2. 连接成功后&#xff0c;会发现是一片黑的 按住 ctrl ] 可以招出提示 输入 &#x…

Apollo进阶课程⑲丨Apollo感知之旅——感知算法

目录 点云感知 启发式方法&#xff1a;NCut 深度学习方法&#xff1a;CNNSeg 视觉感知 CNN检测 CNN分割 后处理 红绿灯感知 基于深度学习的红绿灯感知模块 Radar感知 超声波感知 原文链接&#xff1a;进阶课程⑲丨Apollo感知之旅——感知算法 感知是自动驾驶的第一环…

动手学PaddlePaddle(0):新版本PaddlePaddle安装

目录 0.引言 1.环境 2.Windows下安装 安装Python 安装PaddlePaddle 0.引言 今天介绍如何安装新版本的PaddlePaddle&#xff0c;现在最新版的PaddlePaddle是指Fluid版&#xff0c;Fluid可以让用户像Pytorch和TensorFlow Eager Execution一样执行程序&#xff0c;也就是说P…

一步步编写操作系统 18 操作显卡,显存,显示器 下

接上回&#xff0c;大家看下显卡各种模式的内存分布。 各外部设备都是通过软件指令的形式与上层接口通信的&#xff0c;显卡&#xff08;显示适配器&#xff09;也不例外&#xff0c;所以它也有自己的bios。位置是0xC0000到0xC7FFF。显卡支持三种模式&#xff0c;文本模式、黑白…