os引导程序boot 在根目录区寻找os加载程序文件loader 对应的根目录条目
【0】README
- 0.0) source code from orange’s implemention of a os and for complete code , please visit https://github.com/pacosonTang/Orange-s-OS/blob/master/boot.asm
- 0.1)本代码仅用于在 根目录区条目中寻找 与 boot代码定义的LoaderFileName 相同文件名 的 条目,仅此而已,该文件名是loader.bin,需要加载入内存继续运行的代码文件;(因为找到该文件后, 最后一句指令执行了 jmp $,所以处理器执行后就停在那里不动,所以这里没有给出运行结果示意图)
- 0.2) 就本os而言,即orange’s os ,”在根目录区寻找某文件对应的根目录条目“这个任务 是在 引导扇区中的引导程序boot 中完成的,而且 boot 后面还要完成 ”把 os 的 加载程序loader copy 到 0x09000:0100处“的任务,注意这与linux 是不同的;
- 0.3)即是说,orange’s os 中的启动程序boot 执行了两个任务: os引导程序boot 在根目录区寻找os加载程序文件loader 对应的根目录条目 + os引导程序boot 从扇区拷贝os加载程序loader文件到内存(boot copy kernel to mem in the same method)
【1】Source Code
;—————————————————————————-
; 函数名: ReadSector
;—————————————————————————-
; 作用:
; 从第 ax 个 Sector 开始, 将 cl 个 Sector 读入 es:bx 中, ax初始值=19
ReadSector:
; ———————————————————————–
; 怎样由扇区号求扇区在磁盘中的位置 (扇区号 -> 磁道=柱面号, 起始扇区, 磁头号=磁面)
; 注意扇区号和起始扇区号不同;扇区号对于整个磁盘的全局索引值,而起始扇区号是本磁道的扇区索引值
; ———————————————————————–
; 设扇区号为 x
; ┌ 柱面号 = y >> 1
; x ┌ 商 y ┤
; ————– => ┤ └ 磁头号 = y & 1
; 每磁道扇区数 │
; └ 余 z => 起始扇区号 = z + 1
push bpmov bp, spsub esp, 2 ; 辟出两个字节的堆栈区域保存要读的扇区数: byte [bp-2]mov byte [bp-2], cl ; 在调用者中, cl 被赋值为1, mov cl, 1push bx ; 保存 bxmov bl, [BPB_SecPerTrk] ; bl: 除数 , BPB_SecPerTrk DW 18 ; 每磁道扇区数div ; y 在 al 中, z 在 ah 中 , div 被除数A 默认存放在AX中(16位以内) 或 AX 和 DX中(32位,DX存放高16位,AX存放低16位)inc ah ; z ++mov cl, ah ; cl <- 起始扇区号mov dh, al ; dh <- yshr al, 1 ; y >> 1 (y/BPB_NumHeads)mov ch, al ; ch <- 柱面号and dh, 1 ; dh & 1 = 磁头号pop bx ; 恢复 bx; 至此, "柱面号, 起始扇区, 磁头号" 全部得到mov dl, [BS_DrvNum] ; 驱动器号 (0 表示 A 盘) ,BS_DrvNum DB 0; 中断 13 的驱动器号
.GoOnReading:mov ah, 2 ; 读mov al, byte [bp-2] ; 读 al 个扇区int 13hjc .GoOnReading ; 如果读取错误 CF 会被置为 1, ; 这时就不停地读, 直到正确为止add esp, 2pop bpret
【2】把文件加载到内存的步骤:寻找文件 + 定位文件 + 读入内存
- 2.1)寻找文件方法:
- 2.1.a) 将根目录的第一个扇区(如第19个全局扇区)读入到起始地址为 es:bx=9000h:0100(该地址其实 是在软盘中的数据区去了) ,循环下去的话,读第20、21、….扇区,而es:bx=9000h:0100 永不改变;
- 2.1.b) 因为一个 sector = 512Bytes, 而根目录条目=32Bytes,所以一个扇区就含有16个条目,我们要遍历这16个条目,并将条目中的DIR_NAME属性(即文件名)和boot 代码中静态的 LoaderFileName 做比较,如果完全匹配的话,那该DIR_NAME所在的条目就是我们要找的根目录条目, 如果不匹配话,转向 步骤c;
- 2.1.c) add di, offeh , 使得di 指向该条目开头(因为在发现条目中的DIR_NAME 与 LoaderFileName 不等的时候,di指向的是DIR_NAME 的下一个字节),然后 add di, 20h(32个字节,一个条目大小为32字节) , di指向下一条目开头,继续循环比较;如果 第一个扇区的16个根目录条目都比较完了,转向步骤a,只不过该读当前扇区的下一个扇区了;
Return)该步骤完成后,若寻找文件成功,返回的是 满足 DIR_NAME==LoaderFileName 的 根目录条目;
(Attention): 你要知道根目录条目是多么 的重要,因为它存储有 (文件名 + 文件属性 + 最后一次写入时间 + 最后一次写入日期 + 此条目对应的开始簇号 + 文件大小) 等信息;这个根目录条目 ,不可小觑;
- 2.1.c) add di, offeh , 使得di 指向该条目开头(因为在发现条目中的DIR_NAME 与 LoaderFileName 不等的时候,di指向的是DIR_NAME 的下一个字节),然后 add di, 20h(32个字节,一个条目大小为32字节) , di指向下一条目开头,继续循环比较;如果 第一个扇区的16个根目录条目都比较完了,转向步骤a,只不过该读当前扇区的下一个扇区了;
2.2)定位文件方法(本代码还未涉及到):(参见 http://blog.csdn.net/pacosonswjtu/article/details/48391467 【2.2】文件分配表-FAT 看个荔枝)“
如FAT所在扇区(一个扇区512字节)存储值为:F0 FF FF FF 8F 00 FF FF FF FF FF FF 09 A0 00 FF , 0F 00 00 ;
则簇号分别为:0-FF0 1-FFF 2-FFF 3-008 4-FFF 5-FFF 6-FFF 7-FFF 8-009 9-00A A-FFF
如果根目录去中有条目记载某文件A 的 DIR_FstClus=3的话,则对应第3个FAT项,结合上一行,我们知道FAT3==008,所以下一个簇号是8-009 , 以此类推9-00A、 A-FFF。FFF就表示这个簇是最后一个簇了。
Conclusion:找出该文件在数据区中对应的所有簇,就定位了该文件了;2.3)读入内存方法(先定位全局扇区,再对寄存器编程):
(上图错误更正)应该是怎样由扇区号求扇区在磁盘中的位置,不是定位文件;
如何读取扇区内容到内存? 参见 source code 中的 ReadSector 函数。
【3】总结
3.1)首先你要想,寻找文件? 为什么要寻找文件,是因为,我们boot代码要加载loader 代码进入内存,而loader代码在软盘上(硬盘)上,所以我们就要在软盘上寻找该文件。
为什么boot和loader 不写在同一个程序中?因为 引导扇区只装的下最多 512B,所以要把boot程序和 loader 程序分开来存放,然后再由 boot 跳转到 loader程序去执行;3.2)怎样寻找? 要知道FAT12软盘中的 根目录区条目存储有 所有文件的相关信息,最重要的就是文件名。通过 利用ReadSector函数 实现 “怎样由扇区号求扇区在磁盘中的位置 (扇区号 -> 磁道=柱面号, 起始扇区, 磁头号=磁面)”的功能【暂且叫定位扇区功能,因为一个扇区最直观的表示是全局扇区号,而扇区在软盘中的表示是由3个维度来进行:磁头号(盘面号0,1),磁柱=磁道号,该磁道的上的扇区号来确定】,
我们就把根目录区的第一个全局扇区号(循环,就进入当前扇区的下一个扇区号),如FAT12 的根目录区第一个扇区号为19(相对于根目录区而言是1,而对于全局而言是19),传入ReadSector函数,将传入的扇区内容读入到 es:bx;下一步,我们就把 es:bx中的根目录条目的FIR_NAME 和 boot代码中静态写死的文件名LoaderFileName 进行比较;- 3.2.1)若相等,则文件寻找成功,返回当前所比较的根目录条目(即是LoaderFileName ==DIR_NAME所在的条目)。要知道一个扇区=512Bytes,一个根目录条目=32Bytes,所以一个扇区==16个根目录条目, 所以要在es:bx 处比较16次,是个循环比较;
- 3.2.2)如果比较不成功,全局扇区号加1(当前为19,加1为20,以此类推),循环下去,直到找到与LoaderFileName 相等的 根目录条目,或者,遍历完 根目录条目的所有扇区(如 根目录条目扇区数量为14,当然,这个是由FAT12的引导扇区设置的,可以变化的)
(Attention):其实,你也看到了,要寻找文件,免不了要去定位全局扇区号(磁头号,磁道号,该磁道上的扇区号),定位后,还要读取该扇区到内存的某个位置,读入后,还要对该内存的某些特定值进行比较操作,比较结果有成功,有失败;成功后,返回的是比较成功的当前根目录条目值;这就知道了Loader文件在 根目录区的描述了,包括(文件名 + 文件属性 + 最后一次写入时间 + 最后一次写入日期 + 此条目对应的开始簇号 + 文件大小),接下来,我们就把 Loader 文件加载到内存,准备开始运行该Loader文件了。source code 参见 p114.asm >> https://github.com/pacosonTang/Orange-s-OS/blob/master/p114.asm
os引导程序boot 在根目录区寻找os加载程序文件loader 对应的根目录条目相关推荐
- os引导程序boot从扇区拷贝os加载程序loader文件到内存(boot copy kernel to mem in the same method)
[0]README 0.1) 本代码旨在演示 在boot 代码中,如何 通过 loader文件所在根目录条目 找出该文件的 在 软盘所有全局扇区号(簇号),并执行内存中的 loader 代码: 0.2 ...
- 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码......
当我在窗体初始化的时候,调用了一个外部的dill时,它就不知什么原因的 抛出一个"正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码&quo ...
- 检测到 LoaderLock Message Microsoft.DirectX.dll”正试图在 OS 加载程序锁内执行托管代码。...
今天在群里有朋友问了一个"检测到 LoaderLock Message Microsoft.DirectX.dll"正试图在 OS 加载程序锁内执行托管代码."的问题,自 ...
- 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码...
在窗体初始化的时候,调用了一个外部的dll,不知什么原因的 抛出一个"正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码"的异常, ...
- CAD调试时抛出“正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码”异常的解决方法...
这些天重装了电脑Win10系统,安装了CAD2012和VS2012,准备进行软件开发.在调试程序的时候,CAD没有进入界面就抛出 "正试图在 os 加载程序锁内执行托管代码.不要尝试在 Dl ...
- 正试图在 os 加载程序锁内执行托管代码
问题: 正尝试在 OS 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起. 方法一: 调试->异常->Managed Debu ...
- Bug:正试图在 OS 加载程序锁内执行托管代码
在运行程序退出后,有时候会不然出现这样的错误:正试图在 os 加载程序锁内执行托管代码.不要尝试在DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起. 解决方法是: 把vs200 ...
- VS2010 : 正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。
出错提示: 正尝试在 OS 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起. 原因分析: .NET2.0中增加了42种非常强大的调试助手 ...
- 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码
http://blog.csdn.net/skd12/article/details/46786117 当我在窗体初始化的时候,调用了一个外部的dill时,它就不知什么原因的 抛出一个"正试 ...
最新文章
- docker安装mysql远程不能访问,虚拟机中docker安装mysql远程无法访问解决方法
- 210319opencv图像的存储与显示
- poj2624 4th Point
- 机器学习入门必备的13张“小抄”(附下载)
- 第 8 章 crontab
- pymysql 数据库操控
- in与exist , not in与not exist 的区别
- 第22课: JSP语句 switch判断语句 (JSP教程 JSP入门实战教程 黄菊华Java网站开发系列教程)
- 超级搜索术6-问题驱动/系统思维
- 试题 基础练习 字母图形 java代码
- html中class类怎么写,HTML class 属性 | 菜鸟教程
- 一个初学者的计算天数的C语言代码
- 取消计算机触摸板,笔记本电脑触摸板,教您笔记本电脑触摸板怎么关闭
- three.js 08-03 之 加载和保存对象
- Easy Touch参数
- 计算机科学与技术2018毕业设计,计算机科学与技术学院关于补充2018届本科毕业设计(论文)工作细则的.PDF...
- uniapp中输入框禁用表情与特殊符号
- 清华大学胡事民是计算机视觉,ResNet也能用在3D模型上了,清华“计图”团队新研究已开源...
- 下载安装Hbuilder X
- AutoX安途杯中山大学程序设计校赛(同步赛)题解
热门文章
- CF611F. New Year and Cleaning
- Educational Codeforces Round 107 (Rated for Div. 2)
- 牛客题霸 [ 实现二叉树先序,中序和后序遍历]C++题解/答案
- CodeForces:749(div1)750(div2)
- YBTOJ:消除格子(二分图匹配)
- P4780-Phi的反函数【dfs】
- P4852-yyf hates choukapai【单调队列优化dp】
- U102488-傻叉题【dp】
- jzoj3833-平坦的折线【模型转换,LIS】
- ssl1213-多边形面积【差积,计算几何】