⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 booting-loading_process_5.htm

📁 编写自己的操作系统
💻 HTM
📖 第 1 页 / 共 4 页
字号:
<P><FONT face="Times New Roman TUR" 
size=3>但这并不意味着,如果通过了BIOS软盘参数表的验证,而读取就一定能够成功。例如,软盘参数表中所记录的“每磁道的扇区数”为18,而实际的“每磁道的扇区数”为9,如果现在一个INT 
13h, ax = 2的调用指定:磁头为0,磁道为1,磁道内起始扇区为2,要读取的扇区数目为9;由于磁道内起始扇区+要读取的扇区数-1 = 2+9 -1 = 
10 &lt; 
18,通过软盘参数表的验证没有任何问题,但当软盘驱动器真正去读取磁头0,磁道1,第10个扇区的时候,而这个扇区并不存在,调用依然会失败。</FONT></P>
<P><FONT face="Times New Roman TUR" 
size=3>所以,为了保证一个需要读取软盘的程序不出错误,我们必须保证:</FONT></P>
<P><FONT face="Times New Roman TUR" size=3>“要读取的扇区数” + “磁道内起始扇区” - 1 &lt;= 
软盘参数表中“每磁道的扇区数”的数值</FONT></P>
<P><FONT face="Times New Roman TUR" size=3>同时保证:</FONT></P>
<P><FONT face="Times New Roman TUR" size=3>“要读取的扇区数” + “磁道内起始扇区” - 1 &lt;= 
实际的“每磁道的扇区数”</FONT></P>
<P><FONT face="Times New Roman TUR" 
size=3>你如果想保证你的程序永远不在读取软盘的时候出此类错误,最稳妥的方法是每次只读取一个扇区,但这样效率很低,真正作软件的人都愿意有效率更高,而又稳妥地方法——所以我们要在提高效率的目标下,寻找一种方法来确保效率。</FONT></P>
<P><FONT face="Times New Roman TUR" 
size=3>我们还是看一看上面所列的两个条件,从中我们可以首先得知——我们必须知道实际的“每磁道的扇区数”,否则,我们肯定会出错。那么,在我们知道实际的“每磁道的扇区数”的前提下,软盘参数表中“每磁道的扇区数”的数值不能小于实际的“每磁道的扇区数”,否则,仍然会出错。那么大于呢?由于BIOS对软盘参数表中“每磁道的扇区数”的数值的验证放在前面,如果大于的话,这一级验证即使通过了,还有实际的“每磁道的扇区数”这一关需要通过。所以大于是不会有任何问题的。等于就更不用说了。</FONT></P>
<P><FONT face="Times New Roman TUR" 
size=3>由此得知,要想让我们的程序不出此类错误,我们必须保证两点:</FONT></P>
<P><FONT face="Times New Roman TUR" size=3>1、保证 软盘参数表中“每磁道的扇区数”的数值 大于等于 
实际的“每磁道的扇区数”。</FONT></P>
<P><FONT face="Times New Roman TUR" size=3>2、知道实际的“每磁道的扇区数”;</FONT></P>
<P><FONT face="Times New Roman TUR" 
size=3>对于第1点,或许大家会问,难道BIOS厂商不能够来保证这一点吗?答案是,能够。但不幸的是,在现实生活中,由于历史的原因,确确实实有一些BIOS厂商将软盘参数表中“每磁道的扇区数”的数值设置的比较小。这样,我们就必须靠自己来保证这一点。</FONT></P><STRONG><FONT 
face="Times New Roman TUR" size=3>
<HR width="100%" SIZE=1>
</FONT></STRONG>
<P><STRONG><FONT face="Times New Roman TUR" 
size=3>如何保证软盘参数表中“每磁道的扇区数”大于等于实际的“每磁道的扇区数”?&nbsp;</FONT></STRONG></P>
<P><FONT face="Times New Roman TUR" 
size=3>我们在前面已经说过,在BIOS的中断向量表中断1Eh的地址0:78h处,放置的仅仅是指向软盘参数表的的指针,而软盘参数表被放在BIOS 
ROM中,我们无法修改。所以,我们可以在RAM中复制一份软盘参数表,进行修改。然后将BIOS的中断向量表中断1Eh的地址0:78h处的远指针修改为指向RAM中新复制的软盘参数表。</FONT></P>
<P><FONT face="Times New Roman TUR" 
size=3>由于到目前为止,最大可能的“每磁道扇区数”为36(参见表1-5-1),所以我们只需要将新的软盘参数表中的“每磁道扇区数”修改为36,即可以保证软盘参数表中“每磁道的扇区数”的数值大于等于实际的“每磁道的扇区数”。</FONT></P>
<P align=center><FONT face="Times New Roman TUR" size=3><IMG 
src="booting-loading_process_5.files/fpt_move.jpg" 
tppabs="http://pagoda-ooos.51.net/os_book/booting/loading-process/fpt_move.jpg"></FONT></P>
<P><FONT face="Times New Roman TUR" size=3>下面是Linux 2.4的相关代码。</FONT></P>
<P><FONT face=System size=3># 将0:78h位置所保存的磁盘参数表指针所指向的位置的12格字节拷贝到0x4000-12的<BR># 
位置处,然后将磁盘新参数表的sectors/track值修改为36(2.88M软盘的参数),<BR># 最后修改0:78h处的指针指向0x4000-12 
(es:di)<BR>#<BR>&nbsp;movw&nbsp;&nbsp; %cx, 
%fs&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp; # %fs = 
0<BR>&nbsp;movw&nbsp;&nbsp; $0x78, %bx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # 
%fs:%bx is parameter table address<BR>&nbsp;pushw&nbsp; 
%ds<BR>&nbsp;ldsw&nbsp;&nbsp;&nbsp;&nbsp; %fs:(%bx), %si&nbsp;&nbsp;&nbsp; # 
%ds:%si is source<BR>&nbsp;movb&nbsp;&nbsp; $6, 
%cl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
# copy 12 bytes<BR>&nbsp;pushw&nbsp; 
%di&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
# %di = 
0x4000-12.<BR>&nbsp;rep&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;# don't worry about 
cld<BR>&nbsp;movsw&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
# already done above<BR>&nbsp;popw&nbsp;&nbsp;&nbsp; 
%di<BR>&nbsp;popw&nbsp;&nbsp;&nbsp; %ds<BR>&nbsp;movb&nbsp;&nbsp;&nbsp; $36, 
0x4(%di)&nbsp;&nbsp;&nbsp;&nbsp; # patch sector 
count<BR>&nbsp;movw&nbsp;&nbsp;&nbsp; %di, 
%fs:(%bx)<BR>&nbsp;movw&nbsp;&nbsp;&nbsp; %es, %fs:2(%bx)</FONT></P>
<P><FONT face="Times New Roman TUR" size=3></FONT><STRONG></P><FONT 
face="Times New Roman TUR" size=3>
<HR width="100%" SIZE=1>
</FONT></STRONG>
<P><FONT face="Times New Roman TUR" size=3></FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><STRONG><FONT face="Times New Roman TUR" 
size=3>如何获取实际的“每磁道的扇区数”?</FONT></STRONG></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><STRONG><FONT face="Times New Roman TUR" 
size=3></FONT></STRONG>&nbsp;</P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face="Times New Roman TUR" 
size=3>除了去猜测之外,没有什么好的方法能够获取“实际的每磁道扇区数”。所幸的是,实际存在的软盘只有有限的几个种类,而不同的“实际的每磁道扇区数”就更加有限。参见表1-5-1,我们可以得知,“实际的每磁道扇区数”有9,15,18,36四种。于是,我们就可以对一张软盘使用这四个数值从大到小依次猜测。</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face="Times New Roman TUR" size=3></FONT>&nbsp;</P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face="Times New Roman TUR" 
size=3>猜测的方法,是读取磁头0,磁道0,当前磁道最大扇区。首先猜测“当前磁道最大扇区”为36,如果实际的“每磁道扇区数”小于36,则读取失败。然后猜测“当前磁道最大扇区”为18,如果失败了,再猜测15……依次类推,直到猜测为9为止,这是最小可能的“每磁道扇区数”。</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face="Times New Roman TUR" size=3></FONT>&nbsp;</P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face="Times New Roman TUR" size=3>下面是Linux 2.4的相关代码。</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face="Times New Roman TUR" size=3></FONT>&nbsp;</P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3># Get disk drive parameters, specifically 
number of sectors/track.</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3># It seems that there is no BIOS call to get 
the number of sectors.</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3># Guess 36 sectors if sector 36 can be read, 
18 sectors if sector 18</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3># can be read, 15 if sector 15 can be 
read.&nbsp; Otherwise guess 9.</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3># Note that %cx = 0 from rep movsw 
above.</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3></FONT>&nbsp;</P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
movw&nbsp;&nbsp; $disksizes, %si&nbsp;&nbsp; # table of sizes to try</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System 
size=3>probe_loop:<BR>&nbsp;lodsb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
# Load byte at address DS:SI to AL 
(DN)<BR>&nbsp;cbtw&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp; # extend to word (ax = (disksizes))<BR>&nbsp;movw&nbsp;&nbsp; %ax, 
sectors&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;# sectors = max sectors per 
track (DN)<BR>&nbsp;cmpw&nbsp;&nbsp; $disksizes+4, %si&nbsp;# there is 4 
parameters</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
jae&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 
got_sectors&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # 
If all else fails, try 9</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3></FONT>&nbsp;</P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3>&nbsp;&nbsp;&nbsp; # 读取第一个软驱的Head 0, Track 
0, Max sector</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3>&nbsp;&nbsp;&nbsp; </FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 
xchgw&nbsp;&nbsp; %cx, %ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
&nbsp;&nbsp; &nbsp;&nbsp;# %cx = track and 
sector<BR>&nbsp;xorw&nbsp;&nbsp;&nbsp;&nbsp; %dx, 
%dx&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;# drive 
0, head 0<BR>&nbsp;movw&nbsp;&nbsp; $0x0200, %bx&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;# 
address = 512, in INITSEG (%es = %cs)<BR>&nbsp;movw&nbsp;&nbsp; $0x0201, 
%ax&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # service 2, 1 
sector<BR>&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$0x13<BR>&nbsp;jc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
probe_loop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # try next 
value</FONT></P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System size=3></FONT>&nbsp;</P>
<P class=MsoNormal 
style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; tab-stops: list 21.0pt; mso-list: l5 level1 lfo3" 
align=left><FONT face=System 
size=3>got_sectors:</FONT></P></SPAN></SPAN></SPAN></SPAN></FONT></SPAN></FONT></SPAN></FONT></SPAN></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -