您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 Code iProcess 课程 认证 咨询 工具 火云堂 讲座吧   成长之路  
会员   
 
   
 
  
每天15篇文章
不仅获得谋生技能
更可以追随信仰
 
     
   
 订阅
  捐助
跟我一起写操作系统——10分钟写个操作系统
 
302 次浏览     评价:  
 2018-9-12
 
编辑推荐:
本文来自于csdn,本讲的代码是code/chapter1,笔者已经将上面的命令集成到Makefile中了,读者只需进入目录,按ReadMe.txt执行即可。

想动手,但不知从何入手,是学习一门新知识普遍会遇到的尴尬点。笔者喜欢边实践边学习理论,笔者的写作思路是:入门的文章要避免讲一些高深的理论,而应该先抛出demo,从研究demo入手,逐步加深demo的难度,从而学习这个过程中涉及到的理论知识。下面就让我们花10分钟写个“操作系统”。

第一节 开发环境

我们在linux下制作软盘、编译内核等,因此需要linux开发环境。如果你用windows, 那么在windows下安装VMware, 在VMware中安装ubuntu虚拟机,此ubuntu作为开发环境。

注:笔者的开发环境是windows--VMware--ubuntu14.04.

第二节 计算机启动过程

写操作系统看似是一个复杂的过程,但只要我们将过程分解,完成每一步,那么完成一个操作系统就是水到渠成的事了。好了,我们就看一下计算机的启动过程,看操作系统何时被启动的。

第一步:读取BIOS

按下电源按钮后,计算机首先读取一块ROM芯片,这块芯片里的程序是"基本输入输出系統"(Basic Input/Output System),即BIOS.

第二步:硬件自检

BIOS会检查计算机硬件是否满足运行条件,如果硬件出现问题,主板会发出不同含义的蜂鸣,启动中止。

第三步:启动顺序

硬件检查完成后,BIOS会将控制权交给下一阶段的启动程序,注意,“下一阶段的启动程序”可能存放在硬盘中,也可能存放在CD/DVD中,或者软盘中等等,可以设置BIOS选择从哪个设备启动。

第四步:主引导记录

BIOS找到了“下一阶段的启动程序”所在设备,会读取该设备的第一个扇区,即读取最前面的512字节,称为主引导记录。主引导记录会告诉计算机下一步到哪里去找操作系统。

第五步:bootloader

计算机读取"主引导记录"前面446字节的机器码之后,运行事先安装的“启动管理器”bootloader,由用户选择启动哪个操作系统。如果你安装了多个操作系统,那么就要从这步做出选择了。

第六步:加载内核

好了,选择操作系统(内核)后,会加载内核,下面就交给内核去处理了。

第三节 主引导记录

我们使用虚拟机来启动操作系统,上面的第一步和第二步我们不做,由虚拟机去完成;第三步“启动顺序”我们选择从软盘启动(我们用镜像代替,并不是真的软盘),需要对虚拟机做下设置,选择从软盘启动。下面重点来看第四步,我们写一下“主引导记录”,让BIOS读取我们写的主引导记录。

1. 主引导记录代码

; 文件名 boot.asm

org 7c00h ; BIOS读入MBR后,从0x7c00h处开始执行

; 下面部分和10h有关中断,10h中断用来显示字符
mov ax, cs
mov es, ax
mov ax, msg
mov bp, ax ; ES:BP表示显示字符串的地址
mov cx, msgLen ; CX存字符长度
mov ax, 1301h ; AH=13h表示向TTY显示字符,AL=01h表示显示方式(字符串是否包含显示属性,01h表示不包含)
mov bx, 000fh ; BH=00h表示页号,BL=0fh表示颜色
mov dl, 0 ; 列
int 10h

msg: db "hello world, welcome to OS!"
msgLen: equ $ - msg ; 字符串长度
times 510 - ($ - $$) db 0 ; 填充剩余部分
dw 0aa55h ; 魔数,必须有这两个字节BIOS才确认是MBR

2. 编译

# nasm boot.asm -o boot.bin

如果没有nasm,安装它 sudo apt-get install nasm, 执行完上述命令,会生成boot.bin文件,这就是我们的主引导记录二进制。

第四节 代码解释

我们再来看下主引导记录的汇编代码,熟悉汇编的读者可忽略本节。

1. 为什么MBR要从0x7c00h处开始执行?

ORG是伪指令,org 7c00h是告诉编译器,下面代码装入到内存的起始地址0x7c00h处。为什么呢,这是因为BIOS读取主引导记录后,会从0x7c00h处开始执行,那么BIOS为什么会从0x7c00h这个地址开始执行,而不是其他地址呢,这一切都要从大明湖畔的8086cpu说起。

时光飞逝,容颜易老,8086却还是那个样子,如图所示:

图 8086实物图

图 8086引脚图

正如图中所示,8086cpu的地址总线宽度为20(AD0-AD19),可以传送220的地址信息,即可以定位220(1M)的内存地址空间,那么这1M的内存地址空间是如何分配的呢,见下图所示(图是386的,我们目前只关心实模式即1M内存地址空间分配):

图 实模式内存地址空间分布

看到0x7c00h了吗?0x0000h--0x7c00h这一段存的是BIOS中断向量和一些BIOS数据等,至于到底为什么以0x7c00h为界,本文不做讨论,有兴趣看这里http://www.glamenv-septzen.net/en/view/6。

2. int 10h是干嘛的?

当出现int 10h中断时,表示要操作显示器了,此时AH寄存器表示如何显示,代码中的AH为13h,表示要在TTY(伪终端)显示字符,此时其他几个寄存器都有一定的含义,如下所示:

当出现int 10h中断时,表示要操作显示器了,此时AH寄存器表示如何显示,代码中的AH为13h,表示要在TTY(伪终端)显示字符,此时其他几个寄存器都有一定的含义,如下所示:

ES:BP -- 显示字符串的地址    CX -- 显示字符串的长度

BH -- 页码     BL -- 属性(若AL=00H或 01H)

DH -- 行              DL -- 列

AL -- 显示输出方式

下面一段代码也就不难理解了:


mov ax, cs
mov es, ax
mov ax, msg
mov bp, ax ; ES:BP表示显示字符串的地址
mov cx, msgLen ; CX存字符长度
mov ax, 1301h ; AH=13h表示向TTY显示字符,AL=01h表示显示方式(字符串是否包含显示属性,01h表示不包含)
mov bx, 000fh ; BH=00h表示页号,BL=0fh表示颜色
mov dl, 0 ; 列
int 10h

3. $和$$是什么意思?

$ 是当前位置
$$ 是段开始位置

下面两句就不难理解了:
msgLen: equ $ - msg ; 字符串长度
times 510 - ($ - $$) db 0 ; 填充剩余部分

4. 为什么要有0xaa55h魔数?

BIOS检查完硬件后,会寻找下一个设备来启动计算机,BIOS找到一个设备后,会读取该设备的第一个扇区,也就是读取最前面的512个字节。如果这512个字节的最后两个字节是0x55和0xAA,表明这个设备可以用于启动;如果不是,表明设备不能用于启动,控制权于是被转交给"启动顺序"中的下一个设备。

第五节 制作软盘镜像,加入主引导记录 

如何用dd命令制作软盘,自行google之。

1. 首先,我们制作一个空的软盘镜像empty.img:  

# dd if=/dev/zero of=empty.img bs=512 count=2880

2. 之后,我们制作一个包含主引导记录boot.bin的镜像文件lucasOS.img:

# dd if=boot.bin of=lucasOS.img bs=512 count=1

3. 然后,将empty.img中1个扇区后的数据拷贝到lucasOS.img的后:

# dd if=empty.img of=lucasOS.img skip=1 seek=1 bs=512 count=2879

这样就做成了一个大小为1.44Mb的包含主引导记录的软盘镜像文件lucasOS.img。

4. 将虚拟机ubuntu中的文件lucasOS.img拷贝到windows下(鼠标直接拖拽,如果不行google之)。

第六节 用软盘镜像lucasOS.img启动一个空的虚拟机

1. VMware创建空的虚拟机,去掉开机从CD/DVD启动选项。  

2. 网络选择host-only模式。

3. 选择从软盘驱动,路径选择上一节已经拷贝到windows下的镜像lucasOS.img.

4. 开启虚拟机电源,看到如下画面,恭喜你,成功了。

好了,至此,我们完成了主引导记录,后续会讨论载入内核,并进一步讨论进程管理、内存管理、文件系统和中断等等。

代码获取

本系列GitHub地址 https://github.com/lucasysfeng/lucasOS.git

获取代码:

# git clone https://github.com/lucasysfeng/lucasOS.git

本讲的代码是code/chapter1,笔者已经将上面的命令集成到Makefile中了,读者只需进入目录,按ReadMe.txt执行即可。有问题请留言。

 

   
302 次浏览  评价: 差  订阅 捐助
 
相关文章

云计算的架构
对云计算服务模型
云计算核心技术剖析
了解云计算的漏洞
 
相关文档

云计算简介
云计算简介与云安全
下一代网络计算--云计算
软浅析云计算
 
相关课程

云计算原理与应用
云计算应用与开发
CMMI体系与实践
基于CMMI标准的软件质量保证
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
 
 

关于我们 | 联系我们 | 京ICP备10020922号 京公海网安备110108001071号