一步步编写操作系统 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 …

【2019牛客暑期多校训练营(第三场)- B】Crazy Binary String(思维,01串,前缀和)

题干: 链接:https://ac.nowcoder.com/acm/contest/883/B 来源:牛客网 ZYB loves binary strings (strings that only contains 0 and 1). And he loves equal binary strings\textit{equal binary strings}equal binary strings more, wh…

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感知之旅——感知概况」。 传感器是一种检测装置,能感受到被测量的信息,…

一步步编写操作系统 14 CPU与外设通信——IO接口 上

介绍显卡之前,必须得和大家交待清楚,那么多的外部设备,cpu是如何与他们交流。 大家都学过微机接口技术吧?没学过也没关系,反正我也只是笼统地说说^_^,保证大家一定能看得懂。 按理说,如果硬件…

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…

【POJ - 2019】Cornfields(二维st表,模板)

题干: FJ has decided to grow his own corn hybrid in order to help the cows make the best possible milk. To that end, hes looking to build the cornfield on the flattest piece of land he can find. FJ has, at great expense, surveyed his square fa…

虚拟机安装Linux(vmware + ubuntu)

VMWare 提取码:7zph 建议官网下载比较新,还快一点 https://www.vmware.com/products/workstation-pro.htmlubantu 下载地址 安装过程都差不多可以参考 VMware下安装Ubuntu系统图文详细教程_master-CSDN博客_vmware安装ubuntu系统 出现蓝屏问题可以参考…

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命令 测试网络是否通:…

*【2019牛客暑期多校训练营(第三场)- G】Removing Stones(分治)

题干: 链接:https://ac.nowcoder.com/acm/contest/883/G 来源:牛客网 Summer vacation is coming and Mark has returned home from his university having successfully survived the exam week. Today, he is very bored. So his frien…