【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.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 对应的根目录条目相关推荐

  1. os引导程序boot从扇区拷贝os加载程序loader文件到内存(boot copy kernel to mem in the same method)

    [0]README 0.1) 本代码旨在演示 在boot 代码中,如何 通过 loader文件所在根目录条目 找出该文件的 在 软盘所有全局扇区号(簇号),并执行内存中的 loader 代码: 0.2 ...

  2. 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码......

    当我在窗体初始化的时候,调用了一个外部的dill时,它就不知什么原因的 抛出一个"正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码&quo ...

  3. 检测到 LoaderLock Message Microsoft.DirectX.dll”正试图在 OS 加载程序锁内执行托管代码。...

    今天在群里有朋友问了一个"检测到 LoaderLock Message Microsoft.DirectX.dll"正试图在 OS 加载程序锁内执行托管代码."的问题,自 ...

  4. 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码...

    在窗体初始化的时候,调用了一个外部的dll,不知什么原因的 抛出一个"正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码"的异常, ...

  5. CAD调试时抛出“正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码”异常的解决方法...

    这些天重装了电脑Win10系统,安装了CAD2012和VS2012,准备进行软件开发.在调试程序的时候,CAD没有进入界面就抛出 "正试图在 os 加载程序锁内执行托管代码.不要尝试在 Dl ...

  6. 正试图在 os 加载程序锁内执行托管代码

    问题: 正尝试在 OS 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起. 方法一: 调试->异常->Managed Debu ...

  7. Bug:正试图在 OS 加载程序锁内执行托管代码

    在运行程序退出后,有时候会不然出现这样的错误:正试图在 os 加载程序锁内执行托管代码.不要尝试在DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起. 解决方法是: 把vs200 ...

  8. VS2010 : 正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。

    出错提示: 正尝试在 OS 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起. 原因分析: .NET2.0中增加了42种非常强大的调试助手 ...

  9. 正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码

    http://blog.csdn.net/skd12/article/details/46786117 当我在窗体初始化的时候,调用了一个外部的dill时,它就不知什么原因的 抛出一个"正试 ...

最新文章

  1. docker安装mysql远程不能访问,虚拟机中docker安装mysql远程无法访问解决方法
  2. 210319opencv图像的存储与显示
  3. poj2624 4th Point
  4. 机器学习入门必备的13张“小抄”(附下载)
  5. 第 8 章 crontab
  6. pymysql 数据库操控
  7. in与exist , not in与not exist 的区别
  8. 第22课: JSP语句 switch判断语句 (JSP教程 JSP入门实战教程 黄菊华Java网站开发系列教程)
  9. 超级搜索术6-问题驱动/系统思维
  10. 试题 基础练习 字母图形 java代码
  11. html中class类怎么写,HTML class 属性 | 菜鸟教程
  12. 一个初学者的计算天数的C语言代码
  13. 取消计算机触摸板,笔记本电脑触摸板,教您笔记本电脑触摸板怎么关闭
  14. three.js 08-03 之 加载和保存对象
  15. Easy Touch参数
  16. 计算机科学与技术2018毕业设计,计算机科学与技术学院关于补充2018届本科毕业设计(论文)工作细则的.PDF...
  17. uniapp中输入框禁用表情与特殊符号
  18. 清华大学胡事民是计算机视觉,ResNet也能用在3D模型上了,清华“计图”团队新研究已开源...
  19. 下载安装Hbuilder X
  20. AutoX安途杯中山大学程序设计校赛(同步赛)题解

热门文章

  1. CF611F. New Year and Cleaning
  2. Educational Codeforces Round 107 (Rated for Div. 2)
  3. 牛客题霸 [ 实现二叉树先序,中序和后序遍历]C++题解/答案
  4. CodeForces:749(div1)750(div2)
  5. YBTOJ:消除格子(二分图匹配)
  6. P4780-Phi的反函数【dfs】
  7. P4852-yyf hates choukapai【单调队列优化dp】
  8. U102488-傻叉题【dp】
  9. jzoj3833-平坦的折线【模型转换,LIS】
  10. ssl1213-多边形面积【差积,计算几何】