DIY操作系统(一)
先说几句题外话:
回想第一次看到《30天自制操作系统》这本书时,就被这快餐般的标题深深吸引了,我无法想象如此复杂有内涵的内容能在30天就弄出来,直到我花了一个多月看到这本书的第9天时,我放弃了。
然而这次。
对不起,我是认真的!
以下开始正文,都是个人浅见,如有错误,欢迎斧正。
操作系统如何自己运行起来?
首先,机器自动读取磁盘的第一个扇区(512字节),并载入到内存的0x7c00位置,然后执行第一个扇区的代码,这段代码会读取磁盘后续的扇区到内存,接着跳转到引导文件,由引导文件继续启动操作系统。
这里有几点说明,并不是所有的第一个扇区都是引导扇区,因为他有个特殊的标记,以0x55aa结尾,为什么是0x55aa?还是让我们先看下为什么要载入到内存的0x7c00位置,因为答案都是一样的,龟腚!
下面是《30天自制操作系统》引导扇区的代码,略作修改,并且加了大量注释,让我们RTFSC!
CYLS EQU ; 定义变量,将要读取的柱面数量 ORG 0x7c00 ; 指明程序载入到内存的地址,7c00是魔法数字,人为规定的,没什么道理好讲 ; 以下这段是标准的FAT12格式软盘用的代码 JMP entry ; 跳到下面执行入口entry
DB 0x90 ; 写一个字节,DW是写2个字节,DD是写4个字节
DB "HARIBOTE" ; 启动区的名称,必须8字节
DW ; 每个扇区的大小,必须512字节
DB ; 簇的大小,必须1个扇区
DW ; FAT的起始位置,通常从第一个扇区开始
DB ; FAT的个数,必须为2
DW ; 根目录大小,通常为224
DW ; 该磁盘的大小,必须为2880扇区
DB 0xf0 ; 磁盘的种类,必须是0Xf0
DW ; FAT的长度,必须是9扇区
DW ; 一个磁道有几个扇区,必须是18
DW ; 磁头数,必须是2
DD ; 不使用分区,必须是0
DD ; 重写一次磁盘大小
DB ,,0x29 ; 意义不明
DD 0xffffffff ; 可能是卷标号码
DB "HARIBOTEOS " ; 磁盘的名字(必须11字节)
DB "FAT12 " ; 格式化格式的名字(8字节)
RESB ; 将后面的18个字节置空 ; 程序核心 entry:
MOV AX, ; 将0赋值给AX寄存器,目的其实是初始化后面的SS和DS寄存器
; 为什么要初始化DS寄存器?因为使用内存时默认都要使用DS段寄存器作为基址,比如MOV AX,[0xFF](表示将内存地址0xFF存储的数据赋值给AX)实际是MOV AX,[DS:0xFF],DS默认省略了。
; [DS:0xFF]表示DS*16+0xFF所指地址存储的数据
; 段寄存器不能通过MOV DS, 0这种形式(没有这种机器码),为了初始化段寄存器,不得不通过AX间接来初始化,以后赋值也必须通过寄存器间接赋值
MOV SS,AX ; 初始化SS寄存器
MOV SP,0x7c00 ; 栈指针初始化为与内存起始位置一致,为什么?我也不知道。
MOV DS,AX ; 初始化DS寄存器 ; 下面这段的功能是读磁盘,读磁盘需要调用BIOS的中断来实现,中断相当于一个系列的函数,都是围绕某个功能,比如下面这个13中断,都是与磁盘相关,具体是度还是写,就要看传什么参数。
; BIOS的中断的调用方式跟函数相似,传参数,调用,取返回值。中断的参数和返回值一般都放在特定寄存器中,所以调用中断之前,先要向特定寄存器传递值。
; 下面要用到INT13中断,这个中断的说明如下: ; 直接磁盘服务(Direct Disk Service——INT 13H) ; 功能00H
; 功能描述:磁盘系统复位
; 入口参数:AH=00H
; DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
; 出口参数:CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明 ; 功能02H
; 功能描述:读扇区
; 入口参数:AH=02H
; AL=扇区数
; CH=柱面
; CL=扇区
; DH=磁头
; DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
; ES:BX=缓冲区(内存)的地址
; 出口参数:CF=0——操作成功,AH=00H,AL=传输的扇区数,否则,AH=状态代码, ; 初始化BIOS的参数
MOV AX,0x0800
MOV ES,AX ; 初始化ES段为0800,而作为基址ES要*16,所以实际上0x0800*16=0x8000,为什么要放到内存0x8000的位置?因为这段是空的。。
MOV CH, ; 柱面从0开始读
MOV DH, ; 磁头从0开始读
MOV CL, ; 扇区从1开始读。。。因为第一个就是1而不是0
readloop:
MOV SI, ; 初始化SI,SI用作记录失败次数
retry:
MOV AH,0x02 ; AH=0x02 : AH设置为0x02表示读取磁盘
MOV AL, ; 要读取的扇区数
MOV BX, ; ES:BX表示读到内存的地址 0x0800*16 + 0 = 0x8000
MOV DL,0x00 ; 驱动器号,0表示第一个软盘,是的,软盘。。
INT 0x13 ; 调用BIOS 13号中断,磁盘相关功能
JNC next ; 未出错则跳转到next,出错的话则会使EFLAGS寄存器的CF位置1
ADD SI, ; SI加1,表示出错次数加1
CMP SI, ; SI与5比较
JAE error ; SI >= 5 则跳转到error
MOV AH,0x00 ; AH=0x00 表示磁盘系统复位
MOV DL,0x00 ; 复位第一个软盘,我们也就一块软盘
INT 0x13 ; 调用BIOS 13号中断,磁盘相关功能
JMP retry
next:
MOV AX,ES
ADD AX,0x0020
MOV ES,AX ; 上面三个指令的目的就是 ADD ES,0x020,但是没有这种指令,所以只能通过AX间接操作
; ES+0x020 那么ES:BX=ES*16+BX=0x020*16+BX=0X200+BX=512+BX 相当于放到内存的位置往后移了一个扇区的大小 ADD CL, ; 扇区位置加1
CMP CL, ; 与18比较,意思就是读到第18个扇区,为什么是18个扇区?请看图JBE readloop ; CL <= 18 跳到readloop
MOV CL, ; 重读第一个扇区
ADD DH, ; 磁头加1,表示读完第一个磁头的18个扇区读第二个磁头的18个扇区
CMP DH,
JB readloop ;
MOV DH, ; 重读第一个磁头
ADD CH, ; 柱面加1
CMP CH,CYLS ; 按照读完扇面换磁头,读完磁头再换柱面的顺序循环读取
JB readloop ; ; MOV [0x0ff0],CH ; 将读取的柱面数保存到内存地址0x0ff0处
JMP 0xc200 ; 跳转到内存的0xc200,0xc200是从哪来的?0xc200是0x8000+0x4200,0x8000是软盘读取到内存的起始地址,那么0x4200就是指软盘的0x4200位置
; 因为软盘是FAT12格式,通过找资料,知道软盘中保存的第一个文件的起始地址(也就是数据区)的位置
; 是隐藏扇区+保留扇区+FAT表数*FAT表所占扇区+根目录所占扇区=0+1+2*9+14=33,每个扇区是512字节,33*512=16896,换算成16进制正好是0x4200。
; 所以这里的跳转就是跳到软盘里保存的第一个文件的位置。 ; 下面这段是用来在屏幕上显示错误信息的
; 显示服务(Video Service——INT 10H) ; 功能0EH
; 功能描述:在Teletype模式下显示字符
; 入口参数:AH=0EH
; AL=字符
; BH=页码
; BL=前景色(图形模式)
; 出口参数:无 error:
MOV SI,msg ; 将错误信息地址赋值给SI寄存器
putloop:
MOV AL,[SI] ; 根据地址取出一个字节数据
ADD SI, ; SI加1
CMP AL, ; 如果数据为0则结束
JE fin
MOV AH,0x0e ;
MOV BX, ; 设置颜色
INT 0x10 ; 上面三行为调用BIOS第10号中断,AH为0x0e时为显示字符功能,BH为页码,BL为前景色
JMP putloop
fin:
HLT ; CPU待机
JMP fin ; 无限循环
msg:
DB 0x0a, 0x0a ; 换两行
DB "load error"
DB 0x0a ; 换行
DB RESB 0x7dfe-$ ; 0x7dfe 是0x7c00+510
DB 0x55, 0xaa ; 最后两位55aa表示这个扇区是启动区
DIY操作系统(一)的更多相关文章
- DIY操作系统(引文)
构想根据<30天自制操作系统>以及<ORANGE’S:一个操作系统的实现>初步实现一个操作系统. 先开个头,以后的棋一步一步下.
- diy操作系统 0:万事开头难
许久之前就有写一个tiny的操作系统的打算,但时间和精力关系,想法一直没有成为最终的代码.操作系统的构建本身是个系统工程,门槛较高,需要多方面的知识,往往几行代码背后是厚厚的几本书才能说清 ...
- diy操作系统 附录:常用命令
ld -m elf_i386 as --32 gcc -m 16 o
- diy操作系统 附录:gcc栈帧开启与关闭
在gcc命令行参数中可以使用-fno-omit-frame-pointer来开启栈帧的使用,或者使用-fomit-frame-pointer选项来关闭. 然而,也可以针对某一个函数进行配置方法如下,这 ...
- debian 学习记录-4 -关于linux -2
来源:<Debian标准教程>王旭 著 Slackware.Debian.RedHat.SuSE 这4种发布版是当今大部分发布版的前去,虽然SuSE衍生自Slackware,但由于其技术变 ...
- 热烈庆祝国产编程语言R++1.8研发成功
R++是专为懒人设计的国产编程语言.支持无操作系统裸奔.编译成机器码.android.cocos2dx绑定.中文编程.闭包.惰性求值.JSON.Lisp的S表达式.内联汇编.伪代码.模板.宏.多重继承 ...
- DIY微型操作系统(1)—— 开发的准备
这个连载是根据<30天自制操作系统>这本书所写 只是类似于补充之类的东西,要详细的讲解,还请参照书上的内容 所以,首先我们要感谢作者川合秀实先生!(鞠躬) 为什么我想写这么一个补充的? 因 ...
- 写在连载之前——DIY微型操作系统篇
这个博客开了这么久都没写过什么东西.可能是因为我想写的东西在网上都能找得到,所以自己也懒得去写了. 但是这次当我在看<30天自制操作系统>这本书的时候发现,如果不用作者原版的光盘软件,要自 ...
- DIY微型操作系统(2)—— 寄存器赋值
书上已经为我们提供了最简单的“hello world”程序了 相信大家玩的也挺欢乐的,不过这只是引导扇区的雏形 而且如果找不到完整的光盘上的源代码,新手估计很难学的下去 所以之后文中也会尽量贴出代码 ...
随机推荐
- Erlang 从入门到精通(三) 改变工作目录
对于初学者来书,经常会碰到下面的错误: no such file or directoryerror 提示找不到文件,这时候就需要将文件放到工作目录下,或者直接修改工作目录到文件所在位置. 右键ERl ...
- IT青年深圳销售求职经历
今年五月份,辞掉了一份月薪5k ,没有加班,双休,福利不错的IT工作,我始终觉得这样的工作太过平稳,没有任何激情,虽然没想好接下来的路怎么走,但是最终我还是选择了裸辞.在所在的城市玩了半个月,算是作最 ...
- (转载)IE6支持透明PNG图片解决方案:DD_belatedPNG.js
DD_belatedPNG.js 是一个能是IE6支持p显示ng透明图片,而且还支持背景循环(background-repeat)和定位(backgrond-position) ,支持focus,Ho ...
- iOS中UITableView使用总结
链接:http://www.open-open.com/lib/view/open1430008922468.html
- JQuery源码解析--callbacks
(function (global, factory) { factory(global); })(this, function (window, noGlobal) { var rootjQuery ...
- centos文件误删除恢复
Centos 文件误删除 当意识到误删除文件后,切忌千万不要再频繁写入了,否则 你的数据恢复的数量将会很少. 而我们要做的是,第一时间把服务器上的服务全部停掉,直接killall 进程名 或者 kil ...
- C#读取Excel的三种方式以及比较
(1)OleDB方式 优点:将Excel直接当做数据源处理,通过SQL直接读取内容,读取速度较快. 缺点:读取数据方式不够灵活,无法直接读取某一个单元格,只有将整个Sheet页读取出来后(结果为Dat ...
- 分析‖为什么越来越多厂商开始发力VR一体机?
2015年下半年,国内VR头显市场的主旋律还是PC头显和手机盒子.到了2016年上半年,一体机逐渐上位,成为发布会上的主角. 近期IDEALENS启视在北京召开发布会,发布会的主角K2和K2Pro正是 ...
- 让Asp.net mvc WebAPI 支持OData协议进行分页查询操作
这是我在用Asp.net mvc WebAPI 支持 OData协议 做分页查询服务时的 个人拙笔. 代码已经开发到oschina上.有兴趣的朋友可以看看,欢迎大家指出不足之处. 看过了园子里的几篇关 ...
- 微信公众平台创建自定义菜单中文编码导致system error
创建包含了中文的自定义菜单时总是返回{"errcode":-1,"errmsg":"system error"},要将编码方式设置为UTF- ...