发信人: zinger.bbs@cs3.xmu.edu.cn (小白鼠), 信区: cnlinux
标  题: [CLDP] Large-Disk mini-HOWTO (转载)
发信站: XMU CS BBS (Thu Nov 20 18:32:55 1997)
转信站: Lilac!ustcnews!ustcnews!sjtunews!xmucs
出  处: cs3.xmu.edu.cn

【 以下文字转载自 twlinux 讨论区 】
【 原文由 CLDP.bbs@physbbs.iams.sinica.edu.tw 所发表 】










 Large Disk mini-HOWTO 中译版

      作者: Andries Brouwer, jaeb@cwi.nl

   译者: Asd L. Chen, asdchen@ms1.hinet.net

       v1.0, 26 June 1996 翻译日期: 10-13 November 1997



   Abstract

     所有有关 disk geometry 及 1024 cylinder 的限制.



1.  问题所在

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

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

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

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

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

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


2.  启动

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

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

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


Large Disk mini-HOWTO 中译版       1





Large Disk mini-HOWTO 中译版       2



3.  磁碟 geometry 以及分割区

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

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

     struct partition {
  char active;   /* 0x80: bootable, 0: not bootable */
  char begin[3];  /* CHS for first sector */
  char type;
  char end[3];   /* CHS for last sector */
  int start;   /* 32 bit sector number (counting from 0) */
     int length;     /* 32 bit number of sectors */
     };


(其中 CHS 是磁簇/磁头/磁区: Cylinder/Head/Sector 的缩写)

因此, 有项资讯是重覆的: 分割区的位置可以由 24 位元的 begin 以及 end 栏位, 和 32
位元的 start 以及 length 栏位给定.

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

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

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

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


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.875 GB .并不足以应付所有的磁碟, 但仍然是个改进.注意此处








Large Disk mini-HOWTO 中译版       3



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.875 GB.

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

这影响可能多於或少於 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.1  EZD

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

      #define FAKE_FDISK_FOR_EZDRIVE  0


并重新编译核心来改变.

5.2  DM6:DDO

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









Large Disk mini-HOWTO 中译版       4



5.3  DM6:AUX

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

5.4  DM6:MBR

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

5.5  PTBL

最後, 核心会尝试从主分割区的 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_GETGEO
ioctl.但使用者可以交谈式地或在指令列上重定 geometry.

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

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

6.1  IDE 细节

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

另一方面, 对於 geometry 驱动程式需要两个值: 其中之一是 G_fdisk, 由 HDIO_GETGEO
ioctl  传回, 另一个是 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 就设为








Large Disk mini-HOWTO 中译版       5



G_phys.此处的'合理'代表磁头数在 1-16 的范围内.

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

6.2  SCSI 细节

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

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

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

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

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

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

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

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

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










Large Disk mini-HOWTO 中译版       6



      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 中的 `> 1 GB' 选项,
    此情况下 H=255, S=63.

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

      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) , 并印出启动讯息 "Adopting
    Geometry from Partition Table".

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

      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.1 GB).
    这是只臭虫.

      ultrastor and u14_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. 如果不对, 不是因为没有分割区,








Large Disk mini-HOWTO 中译版       7



就是因为它们的大小很奇怪, 那麽只看磁碟容量 M. 演算法: 放入 H =
M/(62*1024)(无条件进位),S = M/(1024*H)(无条件进位), C =
M/(H*S)(无条件舍去).这能产生一 (C,H,S) 其中 C 最大 1024 而 S 最大 62.



























































Large Disk mini-HOWTO 中译版       8





































































   CONTENTS



1. 问题所在 ................................................................. 1

2. 启动 ..................................................................... 1

3. 磁碟 geometry 以及分割区 ................................................. 2

4. 转换与磁碟管理程式 ....................................................... 2

5. 核心的 IDE 磁碟转换 ...................................................... 3
   5.1 EZD .................................................................. 3
   5.2 DM6:DDO .............................................................. 3
   5.3 DM6:AUX .............................................................. 4
   5.4 DM6:MBR .............................................................. 4
   5.5 PTBL ................................................................. 4

6. 结论 ..................................................................... 4
   6.1 IDE 细节 ............................................................. 4
   6.2 SCSI 细节 ............................................................ 5


































       i


--
CLDP homepgae: http://www.linux.org.tw/CLDP/
               http://www.phys.ntu.edu.tw/~cwhuang/pub/os/linux/CLDP/
CLDP mailing list: ldp-trans@linux.org.tw

[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:217.595毫秒