Verder Terug Inhoud

10. Details

10.1 IDE details - de zeven geometries

De IDE driver heeft vijf bronnen met informatie over de geometrie. De eerste (G_user) is datgene wat door de gebruiker op de opdrachtregel is gespecificeerd. De tweede (G_bios) is de BIOS Fixed Disk Parameter Tabel (voor alleen de eerste en de tweede disk) die bij het opstarten van het systeem wordt ingelezen, voor de overschakeling naar 32-bit mode. De derde (G_phys) en vierde (G_log) worden door de IDE controller geretourneerd als een reactie op de opdracht IDENTIFY - dit zijn de `fysieke' en `huidig logische' geometries.

Aan de andere kant heeft de driver twee waarden nodig voor de geometrie: aan de ene kant G_fdisk, geretourneerd door een HDIO_GETGEO ioctl, en aan de andere kant G_used, die eigenlijk wordt gebruikt voor het doen van I/O. Beiden, G_fdisk en G_used zijn geïnitialiseerd als G_user als gegeven, aan G_bios als deze informatie overeenkomstig CMOS aanwezig is, en anders aan G_phys. Als G_log er redelijk uitziet dan wordt G_used daarop ingesteld Anders, als G_used redelijk is en G_phys ziet er redelijk dat wordt G_used ingesteld naar G_phys. Hier betekent `redelijk' dat het aantal heads zich bevindt in het bereik 1-16.

Met andere woorden: de opdrachtregel overschrijft de BIOS en zal vaststellen wat fdisk ziet, maar als het een vertaalde geometrie specificeert (met meer dan 16 heads), dan zal de vertaalde geometrie voor kernel I/O door de uitvoer van de opdracht IDENTIFY worden overschreven.

Merk op dat G_bios nogal onbetrouwbaar is: voor systemen die vanaf SCSI booten kunnen de eerste en tweede disk heel goed SCSI-disks zijn, en de geometrie die de BIOS voor sda rapporteert wordt door de kernel voor hda gebruikt. Bovendien worden disks die niet in de BIOS Setup staan vermeld niet door de BIOS gezien. Dit betekent b.v. dat in een alleen-IDE systeeem waar hdb niet in de Setup is opgegeven, de geometries die door de BIOS voor de eerste en tweede disk worden gerapporteerd, voor hda en hdc zullen gelden.

10.2 SCSI details

De situatie voor SCSI is iets anders, aangezien de SCSI opdrachten reeds logische bloknummers gebruiken, dus een `geometrie' is volledig irrelevant voor de eigenlijke I/O. Het formaat van de partitietabel is echter nog steeds hetzelfde, dus fdisk moet een bepaalde geometrie uitvinden en gebruikt ook hier HDIO_GETGEO - inderdaad, fdisk maakt geen onderscheid tussen IDE en SCSI disks. Zoals men in de hieronderstaande gedetailleerde beschrijving kan zien, vinden de diverse drivers ieder een iets andere geometrie uit. Inderdaad, één grote rommel.

Als je geen DOS of iets dergelijks gebruikt, voorkom dan alle uitgebreide vertalingsinstellingen en gebruik gewoon 64 heads, 32 sectoren per spoor ( voor een mooie, gepaste 1 MiB per cylinder) als dit mogelijk is, zodat er geen problemen ontstaan als je de disk van de ene naar de andere controller verplaatst. Een aantal SCSI diskdrivers (aha152x, pas16, ppa, qlogicfas, qlogicisp) zijn zo nerveus over DOS compatibiliteit dat ze het niet toestaan dat een alleen-Linux systeem van meer dan ongeveer 8 GiB gebruiken. Dit is een bug.

Wat is de werkelijke geometrie? Het makkelijkste antwoord is dat er zoiets niet is. En als dit wel zo zou zijn, zou je het niet willen weten, en zeker NOOIT, OOIT fdisk of LILO of de kernel erover vertellen. Het is zuiver een zaak tussen de SCSI controller en de disk. Laat me dat herhalen: alleen domme mensen vertellen fdisk/LILO/kernel over de ware SCSI disk geometrie.

Maar als je nieuwsgierig bent en aandringt, zou je het disk zelf kunnen vragen. Er is de belangrijke opdracht READ CAPACITY dat de totale grootte van de disk zal geven, en je hebt de MODE SENSE opdracht, dat in de Rigid Disk Drive Geometry Page (page 04) het aantal cylinders en heads geeft (dit is informatie die niet kan worden gewijzigd), en geeft in de Format Page (page 03) het aantal bytes per sector en sectoren per spoor. Dit laatste nummer is typisch afhankelijk van de inkeping, en het aantal sectoren per spoor varieert - de buitenste sporen hebben meer sectoren dan de binnenste sporen. Het Linux programma scsiinfo zal je deze informatie geven. Er zijn veel details en complicaties en het is duidelijk dat niemand (waarschijnlijk zelfs het besturingssysteem niet) deze informatie wil gebruiken. Bovendien, zolang als we slechts zijn geïnteresserd in fdisk en LILO, krijgt men typisch antwoorden als C/H/S=4476/27/171 - waarden die niet kunnen worden gebruikt door fdisk omdat de partitietabel slechts 10 resp. 8 resp. 6 bits voor C/H/S reserveert.

Waar haalt de kernel HDIO_GETGEO dan zijn informatie vandaan? Of van de SCSI controller, of door het maken van een ontwikkelde gissing. Een aantal drivers schijnen te denken dat we de `werkelijkheid' willen weten, maar natuurlijk willen we slechts weten wat DOS of OS/2 FDISK (of Adaptec AFDISK, enz) zal gebruiken.

Merk op dat Linux fdisk de nummers H en S van heads en sectoren per spoor nodig heeft om LBA sectornummers te vertalen naar c/h/s adressen, maar het aantal C van cylinders speelt geen rol in deze conversie. Een aantal drivers gebruiken (C,H,S) = (1023,255 ,63) om te signaleren dat de drive capaciteit tenminste 1023*255*63 sectoren is. Dit is ongelukkig, aangezien het de werkelijke grootte niet bekend maakt, en zal de limiet van gebruikers van de meeste fdisk versies tot ongeveer 8 GiB van hun disks beperken - tegenwoordig een echte beperking.

In de beschrijving hieronder, duidt de M de totale diskcapaciteit aan, en C, H, S het aantal cylinders, heads en sectoren per spoor. Het volstaat om H, S te geven als we C beschouwen als gedefinieerd door M / (H*S).

Standaard, H=64, S=32.

aha1740, dtc, g_NCR5380, t128, wd7000:

H=64, S=32.

aha152x, pas16, ppa, qlogicfas, qlogicisp:

H=64, S=32 tenzij C > 1024, in welk geval H=255, S=63, C = min(1023, M/(H*S)). (Dus C is afgekapt, en H*S*C is geen benaderde waarde van de diskcapaciteit M. Dit zal de meeste versies van fdisk in de war brengen.) De ppa.c code gebruikt M+1 in plaats van M en zegt dat te wijten aan een bug in sd.c M is uit door 1.

advansys:

H=64, S=32 tenzij C > 1024 en bovendien de `> 1 GB' optie in de BIOS is geactiveerd, in welk geval H=255, S=63.

aha1542:

Vraag de controller welke van de twee mogelijke vertaalschema's in gebruik is, en gebruik H=255, S=63 of H=64, S=32. In het eerste geval krijg je een bootmelding "aha1542.c: Using extended bios translation".

aic7xxx:

H=64, S=32 tenzij C > 1024, en bovendien of de "extended" boot parameter was opgegeven, of de `extended' bit in de SEEPROM van de BIOS werd ingesteld, in welk geval H=255, S=63. In Linux 2.0.36 zou deze extended vertaling altijd ingesteld moeten zijn voor het geval geen SEEPROM werd gevonden, maar in Linux 2.2.6 wordt als er geen SEEPROM is gevonden, extended vertaling alleen ingesteld als de gebruiker erom vraagt door deze bootparameter te gebruiken (terwijl als een SEEPROM wordt gevonden, de bootparameter wordt genegeerd). Dit kan betekenen dat een setup die onder 2.0.36 werkt niet boot met 2.2.6 (en het `linear' sleutelwoord voor LILO vereist, of de `aic7xxx=extended' kernel boot parameter).

buslogic:

H=64, S=32 tenzij C >= 1024, en bovendien extended vertaling werd geactiveerd op de controller, in welk geval als M < 2^22 dan H=128, S=32; anders H=255, S=63. Echter na het maken van deze keuze voor (C,H,S), wordt de partitietabel ingelezen, en als voor één van de drie mogelijkheden (H,S) = (64,32), (128,32), (255,63) de waarde endH=H-1 ergens wordt gezien dan wordt dat paar (H,S) gebruikt, en wordt de bootmelding "Adopting Geometry from Partition Table" afgedrukt.

fdomain:

Zoek de geometrie informatie op in de BIOS Drive Parameter Tabel, of lees de partitietabel in en gebruik H=endH+1, S=endS voor de eerste partitie, op voorwaarde dat het niet leeg is, of gebruik H=64, S=32 voor M < 2^21 (1 GiB), H=128, S=63 voor M < 63*2^17 (3.9 GiB) en anders H=255, S=63.

in2000:

Gebruik de eerste van (H,S) = (64,32), (64,63), (128,63), (255,63) dat zal C <= 1024 maken. Kap in het laatste geval C af bij 1023.

seagate:

Lees C,H,S vanaf de disk. (Griezels!) Als C of S te groot is, zet dan S=17, H=2 en verdubbel H tot C <= 1024. Dit betekent dat H op 0 zal worden ingesteld als M > 128*1024*17 (1.1 GiB). Dit is een bug.

ultrastor and u14_34f:

Een van drie afbeeldingen ((H,S) = (16,63), (64,32), (64,63)) wordt gebruikt afhankelijk van de controller afbeeldingsmode.

Als de driver de geometrie niet specificeert, vallen we terug op een ontwikkelde gissing door de partitietabel te gebruiken, of de totale diskcapaciteit te gebruiken.

Kijk naar de partitietabel. Aangezien volgens afspraak partities eindigen op een cylindergrens, kunnen we, gegeven end = (endC,endH,endS) voor enige partitie, gewoon zetten H = endH+1 en S = endS. (Ter herinnering dat sectoren worden geteld vanaf 1.) Preciezer, het volgende wordt gedaan. Als er een niet-lege partitie is, neem de partitie met de grootste beginC. Voor die partitie, kijk naar end+1, berekend door het toevoegen van start en lengte en door ervan uit te gaan dat deze partitie op een cylindergrens eindigt. Als beide waarden overeenkomen, of als endC = 1023 en start+lengte een integrale veelvoud van (endH+1)*endS is, ga er dan vanuit dat deze partitie echt was aangepast op een cylindergrens en zet H = endH+1 en S = endS. Als dit niet werkt, of omdat er geen partities zijn, of omdat ze vreemde groottes hebben, kijk dan slechts naar de diskcapaciteit M. Algorithme: zet H = M/(62*1024) (naar boven afgerond), S = M/(1024*H) (naar boven afgerond), C = M/(H*S) (naar beneden afgerond). Dit heeft als effect het produceren van een (C,H,S) met C ten hoogste 1024 en S ten hoogste 62.


Verder Terug Inhoud