登录 注册

Large Disk mini-HOWTO 大硬盘

资讯 驱动中国 91 次阅读 0 条评论
分享 Q

作者:AndriesBrouwer,jaeb@cwi.nl
译者:AsdL.Chen,asdchen@ms1.hinet.net
v1.0,26June1996翻译日期:10-13November1997


--------------------------------------------------------------------------------
所有有关diskgeometry及1024cylinder的限制.
--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

1.问题所在
假如你的磁碟超过1024个磁簇(cylinders).还有,假如你的作业系统使用基本输出入系统(BIOS).那麽你会遇到一个问题,因为一般磁碟输出入/输入所使用的INT13BIOS介面以一个10位元(bit)的栏位来操作磁簇,所以无法存取第1024及之後的磁簇.

幸运的是,Linux不使用BIOS,所以没有问题.

话是这麽说,但有两件事例外:

(1)当你在启动系统时,Linux还没开始执行所以无法让你避免这个问题.这对LILO以及类似的启动载入程式(bootloaders)有些影响.

(2)使用磁碟的所有作业系统必须同意分割区的位置.换句话说,如果你在一颗磁碟上使用Linux以及,例如DOS,那麽两者必须以相同的方式解读分割表的资料.这对Linux核心以及fdisk有些影响.

底下是对所有相关细节更详细的描述.注意,我使用2.0.8版核心原始程式做为参考.其它的版本可能有一点点出入.




--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

2.启动
当系统启动时,BIOS从第一个磁碟(或从软碟)读取磁区0(一般通称的MBR-MasterBootRecord,主启动磁区)并跳至在该处的程式码-通常是一些启动载入程式(bootstraploader).这些小小的启动程式一般不会有自己的磁碟驱动程式而会使用BIOS所提供的服务.这意谓著只有整个Linux核心都位於开头的1024个磁簇内时才能够被启动.

这个问题很容易解决:确定核心(也许还包括其它启动时用到的档案,像是LILOmap档)是放在一个BIOS可以存取的到,全都在开头的1024个磁簇内的分割区里-这可以(可能)是第一个或第二个磁碟.

另一点是启动载入程式与BIOS必须同意彼此对磁碟逻辑(geometry)上的看法.给LILO`linear'这个选项参数可能会有些帮助.细节後述.




--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

3.磁碟geometry以及分割区
如果你的磁碟上有好几种作业系统,每一种使用一个或多个分割区.那麽对於分割区位於何处不同的看法可能导致灾难性的後果.

MBR中包含一个分割表描述分割区(主分割区:primary)在那里.有四个表格给四个主要分割区使用,它们看起来像

structpartition{
charactive;/*0x80:bootable,0:notbootable*/
charbegin[3];/*CHSforfirstsector*/
chartype;
charend[3];/*CHSforlastsector*/
intstart;/*32bitsectornumber(countingfrom0)*/
intlength;/*32bitnumberofsectors*/
};

(其中CHS是磁簇/磁头/磁区:Cylinder/Head/Sector的缩写)
因此,有项资讯是重覆的:分割区的位置可以由24位元的begin以及end栏位,和32位元的start以及length栏位给定.

Linux只使用start以及length栏位,故最多可以处理包含2^32个磁区的分割区,也就是,最大2TB的分割区.这是现今磁碟机的两百倍,所以也许足够往後十年的需求.

不幸的是,BIOSINT13呼叫使用三个位元组的CHS编码,10个位元作为磁簇号码,8个位元作为磁头号码,及6个位元作为磁轨上的磁区号码.可能的磁簇号码是0-1023,可能的磁头号码是0-255,而磁轨上可能的磁区号码为1-63(是的,磁轨上的磁区是由1起算,不是0).以这24位元最多可以定址8455716864个位元组(7.875GB),这是1983年磁碟机的两百倍.

更不幸的是,标准的IDE介面容许256个磁区/磁轨,65536个磁簇以及16个磁头.它自己本身可以存取2^37=137438953472个位元组(128GB),但是加上BIOS方面63个磁区与1024个磁簇的限制後只剩528482304个位元组(504MB)可以定址的到.

这不足以应付现今的磁碟,人们使用各种硬体或软体上的方法来克服.




--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

4.转换与磁碟管理程式
没有人对磁碟的'真实'geometry有兴趣.磁轨的磁区数通常是变动的-接近磁碟外围的磁轨有比较多的磁区-所以没有'真实'的每磁轨磁区数.对於使用者而言最好是把磁碟当作编号0,1,...,的磁区组合成的线性阵列,让控制器去找出磁区究竟位於磁碟的那里.

此线性编号一般通称为LBA.对於geometry为(C,H,S)的磁碟而言属(c,h,s)的线性位址为c*H*S+h*S+(s-1).所有SCSI控制器都使用LBA,某些IDE控制器也是.

如果BIOS把这24个位元(c,h,s)转换成LBA并□给懂得LBA的控制器,那麽又可以定址到7.875GB.并不足以应付所有的磁碟,但仍然是个改进.注意此处BIOS使用的CHS,它不再与'实体'有任何关系.

当控制器不懂何为LBA但是BIOS知道如何转换时有些类似的方法可行.(在BIOS设定中通常称为'Large'.)现在BIOS将呈现geometry为(C',H',S')给作业系统,而在与磁碟控制器沟通时则使用(C,H,S).通常S=S',C'=C/N而H'=H*N,其中N是确保C'<=1024之2的最小次方(所以C'=C/N时舍去的数浪费少许容量).再一次,这允许存取最多达7.875GB.

如果BIOS不知道'Large'或是'LBA',那麽还是有软体的解决方案.像是OnTracker或EZ-Drive这些个磁碟管理程式会以它们自己的函式(routines)替换掉BIOS的.通常这是藉由将磁碟管理程式放在MBR及其後几个磁区(OnTrack称这些程式码为DDO:DynamicDriveOverlay)来达成的,所以它会在任何其它作业系统之前被启动.这也就是为什麽在安装磁碟管理程式後从软碟启动可能会出问题.

这影响可能多於或少於BIOS转换-但特别是在相同的磁碟上跑数种不同的作业系统时,磁碟管理程式可能引起许多问题.

Linux从1.3.14版开始支援OnTrack磁碟管理程式,从1.3.29开始支援EZ-Drive.下面有些更进一步的资讯.




--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

5.核心的IDE磁碟转换
如果Linux侦测到IDE磁碟上有某些磁碟管理程式存在,它将会试著使用与该磁碟管理程式相同的方式来重新对应磁碟,所以Linux看到与,例如DOS配合OnTrack或是EZ-Drive相同的磁碟分割.然而,当你在指令列上指定geometry时,就不会做任何的重新对应-所以一行`hd=cyls,heads,secs'指令列选项可能取消掉与磁碟管理程式的相容.

此重新对应的方式是尝试4,8,16,32,64,128,255磁头数(H*C保持不变)直到C<=1024或是H=255.

细节如下-小节的抬头是出现在相对应之启动讯息里的字串.在此以及在这份文件任何其它地方中分割的型态都以十六进位数字表示.


5.1EZD
侦测到EZ-Drive,因为第一个主要分割区型态为55.如上述重新对应geometry,且忽略从第0磁区读入的分割表-以第1磁区的分割表取代.磁碟的区块号码(blocknumbers)没有改变,但对磁区0的写入会转向磁区1.此动作可以藉由修改在ide.c中的

#defineFAKE_FDISK_FOR_EZDRIVE0
并重新编译核心来改变.

5.2DM6:DDO
侦测到OnTrackDiskManager(在第一个磁碟上),因为第一个主要分割区型态为54.如上述重新对应geometry而且整个磁碟平移63个磁区.(所以旧的磁区63变成磁区0)然後从新的第0磁区读入新的MBR(与分割表).此平移当然是为DDO留空间-这也就是为什麽其它磁碟不必平移.


5.3DM6:AUX
侦测到OnTrackDiskManager(在其它磁碟上),因为第一个主要分割区型态为51或53.如上述重新对应geometry.


5.4DM6:MBR
侦测到某旧版的OnTrackDiskManager,并非藉由分割区型态,而是签名(signature).(测试在MBR里第2,3位元组的偏移值是否不大於430,而且在此偏移位址找到的short等於0x55AA,後面并跟著一个奇数的位元组)再一次如上述重新对应geometry.


5.5PTBL
最後,核心会尝试从主分割区的start以及end值推断转换方式:若某些分割区的start以及end磁簇小於256,而且start以及end磁区号码分别为1和63,而且end磁头为31,63,或127,那麽,因为依惯例分割区会在磁簇边界结束,而且更因为IDE介面最多使用16个磁头,故推测有开启BIOS转换,分别使用32,64或128磁头数重新对应geometry.(也许这里有点瑕疵,genhd.c不应该测试磁簇号码前两个位元吗?)无论如何,当目前的geometry已经为每磁轨63个磁区且至少这麽多磁头时,不会做重新对应(因为这可能意谓著重对应已完成).



--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

6.结论
这到底意谓著什麽?对Linux的使用者而言只有一件事:就是他们必须得确保LILO以及fdisk使用正确的geometry,其中'正确'的定义对fdisk而言是与其它在同一个磁碟上的作业系统所使用的geometry相同,而对LILO而言是能够在启动时期成功地与BIOS交谈的geometry.(这两者通常相符.)

fdisk如何得知该geometry?它询问核心,使用HDIO_GETGEOioctl.但使用者可以交谈式地或在指令列上重定geometry.

LILO如何得知该geometry?它询问核心,使用HDIO_GETGEOioctl.但使用者可以用`disk='选项重定.也可以给LILO一个linear选项,如此它将在其map档中储存LBA位址以取代CHS位址,并且在启动时期找出该geometry来使用(藉由INT13功能呼叫8来询问磁碟的geometry).

核心如何知道该怎麽回答?首先,使用者可能以`hd=cyls,heads,secs'指令列选项明确地指定geometry,否则核心将询问硬体.


6.1IDE细节
让我详细说明.IDE驱动程式有四个关於geometry的资讯来源.第一个(G_user)是使用者在指令列上所指定的.第二个(G_bios)是BIOS的固定磁碟参数表(只用於第一及第二个磁碟),在系统启动时,切换至32位元模式之前读入.第三个(G_phys)及第四个(G_log)是由IDE控制器传回,作为对IDENTIFY指令的回应-它们是'实体的'以及'目前逻辑上的'geometries.

另一方面,对於geometry驱动程式需要两个值:其中之一是G_fdisk,由HDIO_GETGEOioctl传回,另一个是G_used,这是执行输出/入时实际使用的.如果给定G_user则G-fdisk以及G_used两者都会设为G_user,当此资讯是根据CMOS所提供时则设为G_bios,其它情形设为G_phys.如果G_log看起来合理则G_used就设为G_log.不然,如果G_used不合理而G_phys看起来合理那麽G_used就设为G_phys.此处的'合理'代表磁头数在1-16的□围内.

换个方式说:指令列选项大於BIOS,并且决定fdisk看到的样子,但如果它指定转换的geometry(磁头数大於16),则核心会藉由IDENTIFY指令的输出重定它.


6.2SCSI细节
在SCSI方面情况有一点点不同,因为SCSI指令已经使用逻辑区块号码,所以'geometry'对实际的输出/入完全没关系.然而,分割区的格式仍然是相同的,所以fdisk必须得捏造些geometry,并且也在此使用HDIO_GETGEO-真的,fdisk不会分辨IDE以及SCSI磁碟.你可以从下面的详细描述见到各种驱动程式捏造一些个不同的geometry.真是,一团混乱.

如果你没有使用DOS或这类系统,那麽避免使用所有额外的转换设定,可能的话,尽管使用64磁头,每磁轨32磁区(良好的,方便每磁簇1MB),如此当你把磁碟从一个控制器换到另一个去时不会遇到任何问题.某些SCSI磁碟驱动程式(aha152x,pas16,ppa,qlogicfas,qlogicisp)非常在意与DOS的相容性而不允许只有Linux的系统使用超过8GB的容量,这是只臭□.

真实的geometry是什麽?最简单的答案是没有这种东西.如果真有的话,你不会想知道,而且的的确确从不,永不需告诉fdisk或是LILO或核心有关它的事.这绝对是SCSI控制器与磁碟之间的事.让我重覆这句话:只有蠢蛋会告诉fdisk/LILO/KernelSCSI磁碟真实的geometry.

但如果你好学且坚持,可以问磁碟机自己.有个重要指令READCAPACITY将会传回磁碟的总容量,而且有个MODESENSE指令RigidDiskDrivePage(page04)会传回磁簇以及磁头的数目(这是不能改变的资讯),而在FormatPage(page03)有每磁区的位元组,以及每磁轨的磁区数.这数字一般与notch有关,而且每磁轨的磁区数是变动的-外围的磁轨拥有比内圈磁轨多的磁区.Linux程式scsiinfo会给予这项资讯.其中有许多繁琐的细节,而且很明白的,没有人(也许甚至是作业系统)需要使用这项资讯.还有,因为我们只关心fdisk以及LILO,一般得到的回答像C/H/S=4476/27/171-这样的值fdisk根本不能使用,因为分割表只保留10resp.8resp.6bits给C/H/S.

那核心之HDIO_GETGEO从何处取得其资讯?嗯,不是从SCSI控制器,就是推论猜测.有些驱动程式似乎认为我们想知道'真相',但我们当然只想知道DOS或OS/2FDISK(或AdaptecAFDISK等等)所用的.

注意,Linuxfdisk需要磁头数H以及每磁轨磁区数S以便转换LBA磁区号码成为c/h/s位址,但磁簇数C在此转换中并未扮演什麽角色.有些驱动程式使用(C,H,S)=(1023,255,63)来表示磁碟容量至少为1023*255*63个磁区.这是不幸的,因为这不能显示实际的大小,而且将限制大部份版本之fdisk的使用者其磁碟最大到8GB-现今实际的限制.

在下面的描述中,M表示磁碟的全部容量,而C,H,S是磁簇,磁头以及每磁轨磁区数.如果我们把C当作M/(H*S)那给H,S就可以满足.

依预设,H=64,S=32.


aha1740,dtc,g_NCR5380,t128,wd7000:
H=64,S=32.


aha152x,pas16,ppa,qlogicfas,qlogicisp:
H=64,S=32除非C>1024,此情况下H=255,S=63,C=min(1023,M/(H*S)).(故C被截断,且H*S*C不是磁碟容量的近似值.这将会混摇淆大部份版本的fdisk.)ppa.c程式码使用M+1取代M并认为这是因为在sd.c里的一只臭□使M的值少一.


advansys:
H=64,S=32除非C>1024而且还开启BIOS中的`>1GB'选项,此情况下H=255,S=63.


aha1542:
询问控制器使用两种可能的schemes中的那一种,并且使用H=255,S=63或H=64,S=32.前者有个启动讯息"aha1542.c:Usingextendedbiostranslation".


aic7xxx:
H=64,S=32除非C>1024,而且还给了"extended"启动参数,或在SEEPROM或BIOS设了`extended'位元,此情况下H=255,S=63.


buslogic:
H=64,S=32除非C>=1024,而且还启动控制器的扩充转换,此情况下若M<2^22则H=128,S=32;否则H=255,S=63.然而,选择(C,H,S)之後,读入分割表,若三种可能的(H,S)=(64,32),(128,32),(255,63)中endH=H-1的值看来可行则使用该对(H,S),并印出启动讯息"AdoptingGeometryfromPartitionTable".


fdomain:
从BIOSDriveParameterTable找出geometry资讯,或从分割表读取并使用H=endH+1,S=endS给第一个分割区,若非空,或使用H=64,S=32forM<2^21(1GB),H=128,S=63forM<63*2^17(3.9GB)andH=255,S=63otherwise.


in2000:
使用(H,S)=(64,32),(64,63),(128,63),(255,63)中第一个让C<=1024的.此情况下,在1023截掉C.


seagate:
从磁碟读取C,H,S.(真诚实!)如果C或S太大,放入S=17,H=2并倍增H直到C<=1024.这表示H将为0如果M>128*1024*17(1.1GB).这是只臭□.


ultrastorandu14_34f:
三种对应之一((H,S)=(16,63),(64,32),(64,63))根据控制器的对应模式而定.


如果驱动程式没有指定geometry,我们就回到使用分割表或磁碟总容量来推断猜测.
仔细看看分割表.因为依惯例分割区在磁簇边界结束,我们可以为任何分割区定end=(endC,endH,ednS),只要放入H=endH+1及S=endS.(记得磁区由1起算.)更明确地的说.如果有个不是空的分割区,则以最大的beginC计.对於此分割区,看看end+1,计算加上start以及length并且假设此分割区在某磁簇边界结束.如果两个值都相符,或endC=1023且start+length是(endH+1)*endS的倍数,那麽假定此分割区真的是在磁簇边界,并放入H=endH+1以及S=endS.如果不对,不是因为没有分割区,就是因为它们的大小很奇怪,那麽只看磁碟容量M.演算法:放入H=M/(62*1024)(无条件进位),S=M/(1024*H)(无条件进位),C=M/(H*S)(无条件舍去).这能产生一(C,H,S)其中C最大1024而S最大62.



--------------------------------------------------------------------------------

LargeDiskmini-HOWTO大硬盘 学习Large
版权声明:本文由驱动中国整理发布,转载需注明出处与原文链接。如有疑问请联系 editor@qudong.com
本文价值 成为第一个评分的人
登录后为本文打分
网友评论0 条评论
正在回复 的评论取消
评论加载中…
🔐

登录后参与互动

评论、点赞均可赚积分
连续签到、邀请好友也有奖励 🎁

电脑端: 微信扫码登录 微信内: 一键登录

微信扫一扫

打开微信「扫一扫」,分享本文到朋友圈或好友