  Large Disk HOWTO
  Andries Brouwer, aeb@cwi.nl; svensk versttning: Joel Ros
  dahl, joel@rosdahl.net
  v1.1, 18 May 1998; svensk versttning 20 augusti 1998

  Allt om hrddisk-geometrier och 1024-cylindersgrnsen fr hrddiskar.

  1.  Problemet


  Antag att du har en hrddisk med fler n 1024 cylindrar.  Antag ocks
  att du har ett operativsystem som anvnder sig av BIOS.  D har du
  problem, eftersom det vanliga INT13-BIOS-grnssnittet fr hrddisk-I/O
  anvnder ett 10-bitarsflt fr att ange aktuell cylinder, s att
  cylinder 1024 och drver r otkomliga.

  Som tur r anvnder Linux sig inte av BIOS, s det r inget problem.

  Ja, frutom tv saker, d:

  (1) Linux r inte startat nr du startar datorn och kan drfr inte
  rdda dig frn BIOS-problem.  Det har vissa konsekvenser fr LILO och
  liknande multibootprogram.

  (2) Det r ndvndigt fr alla operativsystem som anvnder en och
  samma hrddisk att komma verens om var partitionerna ligger.  Med
  andra ord, om du anvnder bde Linux och, sg, DOS p samma hrddisk
  mste bda tolka partitionstabellen p samma stt.  Detta har vissa
  konsekvenser fr Linux-krnan och fr fdisk.

  Nedan finns en ganska detaljerad beskrivning av alla relevanta
  detaljer.  Notera att jag anvnde kllkoden fr Linux version 2.0.8
  som referens.  Andra versioner kan skilja sig t lite grann.



  2.  Boot-fasen

  startas lser BIOSet sektor 0 (knt som MBR - Master Boot Record) frn
  den frsta hrddisken (eller frn diskett) och hoppar till koden som
  finns dr -- normalt ngon bootstrap-laddare.  Dessa sm bootstrap-
  program som hittas dr har typiskt inga egna drivrutiner fr
  hrddiskar och anvnder BIOS-tjnster.  Detta innebr att en Linux-
  krna bara kan laddas om den i sin helhet ligger inom de 1024 frsta
  cylindrarna.

  Detta problem r enkelt att lsa: se till att krnan (och mjligen
  andra filer som anvnds under uppstart, som till exempel map-filer
  till LILO), ligger p en partition som i sin helhet ligger inom de
  1024 frsta cylindrarna p en hrddisk som BIOS kan komma t --
  frmodligen innebr detta den frsta eller andra hrddisken.

  En annan sak r att bootblocksladdaren och BIOS mste vara verens om
  vilken geometri hrddisken har.  Det kan hjlpa att ge parametern
  "linear" till LILO.  Mer information om det lngre ner.



  3.  Hrddiskgeometri och partitioner

  Om du har flera operativsystem p dina hrddiskar anvnder var och en
  av dem en eller flera partitioner.  Om operativsystemen inte r
  verens om hur partitionerna ligger kan konsekvenserna bli
  katastrofala.


  MBR innehller en partitionstabell som beskriver var (de primra)
  partitionerna finns.  Det finns 4 poster i tabellen fr 4 primra
  partitioner, och varje post ser ut som



       struct partition {
               char active;    /* 0x80: bootbar, 0: ej bootbar */
               char begin[3];  /* CHS fr frsta sektorn */
               char type;
               char end[3];    /* CHS fr sista sektorn */
               int start;      /* sektornummer (32-bitarstal, med brjan p 0) */
               int length;     /* antal sektorer (32-bitarstal) */
       };




  (dr CHS str fr cylinder/huvud/sektor).

  Slunda r informationen redundant: stllet partitionen ligger p r
  givet bde av de 24-bitars begin- och end-flten och av de 32-bitars
  start- och length-flten.

  Linux anvnder bara start- och length-flten och kan drfr hantera
  partitioner som inte r strre n 2^32 sektorer, det vill sga hgst 2
  TB stora partitioner.  Det r hundra gnger strre n hrddiskarna som
  r tillgngliga idag, s det kanske rcker fr de nstkommande 80
  ren, eller s.

  Olyckligtvis anvnder INT13-BIOS-anropet CHS kodad som tre byte, med
  10 bitar fr antal cylindrar, 8 bitar fr antal huvuden och 6 bitar
  fr antal sektorer.  Mjliga vrden fr antal cylindrar r 0-1023,
  mjliga vrden fr antal huvuden r 0-255 och mjliga vrden fr antal
  sektorer r 1-63 (ja, sektorer p ett spr rknas med brjan p 1,
  inte 0).  Med dessa 24 bitar kan man adressera 8455716864 byte (7,875
  GB), tvhundra gnger strre n hrddiskarna som fanns tillgngliga
  1983.

  nnu mer olyckligt r att standardmssiga IDE-grnssnitt tillter 256
  sektorer/spr, 65536 cylindrar och 16 huvuden.  Detta i sig sjlv
  tillter tkomst till 2^37 = 137438953472 byte (128 GB), men
  kombinerat med BIOS-begrnsningarna (hgst 63 sektorer och 1024
  cylindrar) ger detta att bara 528482304 byte (504 MB) kan adresseras.

  Detta r rcker inte fr dagens hrddiskar, och folk fr ta till alla
  sorters trick, bde hrdvaru- och mjukvarumssiga.



  4.  versttning och hrddiskhanterare

  Ingen r intresserad av vad den "riktiga" geometrin fr en hrddisk
  r.  Faktiskt r antalet sektorer per spr ofta variabelt -- det finns
  fler sektorer per spr nra den yttre kanten p hrddisken -- s det
  finns inget "riktigt" antal sektorer per spr.  Fr anvndaren r det
  bst att betrakta en hrddisk som en linjr samling sektorer numrerade
  0, 1, ..., och lta hrddiskkontrollern ta reda p var en given sektor
  finns p hrddisken.

  Denna linjra numrering kallas fr LBA.  Den linjra adressen som hr
  till (c,h,s) fr en hrddisk med geometrin (C,H,S) r c*H*S + h*S +
  (s-1).  Alla SCSI-kontrollrar, och ngra IDE-kontrollrar, pratar LBA.

  Om BIOSet konverterar 24-bitarsadressen (c,h,s) till LBA och skickar
  den till en kontroller som frstr LBA kommer 7,875 GB att vara
  adresserbart.  Inte nog fr alla sorters hrddiskar, men i alla fall
  en frbttring.  Notera att CHS, s som det anvnds av BIOS, hr inte
  lngre har ngon koppling till "verkligheten".

  Ngonting liknande fungerar nr kontrollern inte pratar LBA, men nr
  BIOS knner till versttning.  (Det indikeras ofta som "Large" i
  BIOS-instllningarna.)  D kommer BIOS att presentera en geometri
  (C',H',S') fr operativsystemet och anvnda (C,H,S) nr den
  kommunicerar med diskkontrollern.  Normalt r S = S', C' = C/N och H'
  = H*N, dr N r den minsta exponenten till tv som skerstller att C'
  <= 1024 (s att s lite av kapaciteten som mjligt slsas bort i
  avrundning av C' = C/N).  ter igen, detta ger en adressrymd p 7,875
  GB.

  Om ett BIOS inte knner till "Large" eller "LBA" finns det
  mjukvarulsningar.  Hrddiskhanterare som OnTrack eller EZ-Drive byter
  ut BIOS' rutiner fr hrddiskhantering mot sina egna.  Detta stadkoms
  ofta genom att lta hrddiskhanterarens kod ligga i MBR och pfljande
  sektorer (OnTrack kallar denna kod DDO: Dynamic Drive Overlay), s att
  den laddas innan operativsystemet.  Det r drfr man kan ha problem
  med att boota frn diskett nr en hrddiskhanterare har installerats.

  Effekten r mer eller mindre likadan som med ett versttande BIOS --
  men hrddiskhanterare kan stlla till med mycket problem, speciellt
  nr man kr flera olika operativsystem p samma hrddisk.

  Linux stder hrddiskhanteraren OnTrack sedan version 1.3.14 och EZ-
  Drive sedan version 1.3.29.  Lite mer detaljer ges nedan.



  5.  Hrddiskversttning av krnan fr IDE-hrddiskar

  detekterar nrvaron av ngon hrddiskhanterare p en IDE-hrddisk
  kommer den att frska mappa om hrddisken p samma stt som denna
  hrddiskhanterare skulle ha gjort, s att Linux ser samma
  hrddiskpartitionering som till exempel DOS med OnTrack eller EZ-
  Drive.  Emellertid grs INGEN ommappning nr en geometri specificeras
  p kommandoraden -- s ett kommandoradsargument som
  "hd=cylindrar,huvuden,sektorer" skulle mycket vl kunna frstra
  kompatibiliteten med en hrddiskhanterare.

  Ommappningen grs genom att testa 4, 8, 16, 32, 64, 128, 255 huvuden
  (och hlla H*C konstant) tills antingen C <= 1024 or H = 255.

  Detaljerna r som fljer -- titlarna fr subkapitlen r strngarna som
  dyker upp i korresponderande boot-meddelanden.  Hr och verallt
  annars i denna text ges partitionstyperna med hexadecimaler.



  5.1.  EZD

  EZ-Drive kan knnas igen genom att den frsta primra partitionen r
  av typ 55.  Geometrin mappas om enligt beskrivning ovan, och
  partitionstabellen frn sektor 0 slngs bort -- istllet lses
  partitionstabellen frn sektor 1.  Hrddiskblockens nummer ndras
  inte, men skrivningar till sektor 0 dirigeras om till sektor 1.  Detta
  beteende kan ndras genom att kompilera om krnan med
   #define FAKE_FDISK_FOR_EZDRIVE  0 i ide.c.


  5.2.  DM6:DDO

  Hrddiskhanteraren OnTrack (p den frsta hrddisken) knns igen genom
  att den frsta primra partitionen r av typ 54.  Geometrin mappas om
  enligt beskrivning ovan, och hela disken skiftas 63 sektorer (s att
  den ursprungliga sektorn 63 blir sektor 0).  Eftert lses en ny MBR
  (med partitionstabell) in frn sektor 0.  Sjlvklart r denna
  skiftning till fr att gra plats fr DDOn -- det r drfr det inte
  grs ngon skiftning p resten av hrddiskarna.


  5.3.  DM6:AUX

  Hrddiskhanteraren OnTrack (p resten av hrddiskarna) knns igen
  genom att den frsta primra partitionen r av typ 51 eller 53.
  Geometrin mappas om enligt beskrivning ovan.


  5.4.  DM6:MBR

  En ldre version av hrddiskhanteraren OnTrack knns inte igen genom
  partitionstyp, utan genom en signatur.  (Testa huruvida offseten som
  finns i byte 2 och 3 p MBRen inte r strre n 430 och talet som
  finns p denna offset r lika med 0x55AA och fljs av en udda byte.)
  terigen, geometrin mappas om enligt ovan.


  5.5.  PTBL

  Till sist finns ett test som frsker berkna en versttning med
  hjlp av start- och end-flten fr de primra partitionerna: Om ngon
  partition har start- och slutcylinder mindre n 256, och start- och
  slutsektor nummer 1 och 63, respektive, och sluthuvuden 31, 63 eller
  127, s (eftersom det r brukligt att avsluta partitioner p en
  cylindergrns och eftersom IDE-grnssnittet anvnder hgst 16 huvuden)
  antas det att en BIOS-versttning r aktiv och att geometrin r
  ommappad till att anvnda 32, 64 eller 128 huvuden, respektive.  (Det
  finns kanske en brist hr; genhd.c borde kanske inte ha testat de tv
  mest signifikanta bitarna av cylindertalet?)  Emellertid grs ingen
  ommappning nr den nuvarande idn om hur geometrin ska vara inbegriper
  63 sektorer per spr och tminstone lika mnga huvuden (eftersom det
  d frmodligen innebr att en ommappning redan r gjord).


  6.  Konsekvenser

  Vad betyder allt det hr?  Fr Linuxanvndare bara en sak: att de
  mste se till att LILO och fdisk anvnder rtt geometri dr "rtt" fr
  fdisk r definierat som geometrin som anvnds av de andra
  operativsystemen p samma hrddisk, och "rtt" fr LILO definieras som
  geometrin som mjliggr lyckad interaktion med BIOSet vid uppstart.
  (Normalt sett sammanfaller dessa.)

  Hur knner fdisk till geometrin?  Den frgar krnan genom att anvnda
  ioctl:n HDIO_GETGEO.  Men anvndaren kan sjlv, interaktivt eller p
  kommandoraden, bestmma vilken geometri som ska anvndas.

  Hur knner LILO till geometrin?  Den frgar krnan genom att anvnda
  ioctl:n HDIO_GETGEO.  Men anvndaren kan sjlv, med hjlp av
  parametern "disk=", bestmma vilken geometri som ska anvndas.  Man
  kan ocks ge parametern "linear" till LILO, som d kommer att lagra
  LBA-adresser istllet fr CHS-adresser i sin map-fil och rkna ut
  vilken geometri som ska anvndas vid uppstart (genom att anvnda INT
  13 funktion 8 fr att frga om hrddiskgeometrin).

  Hur vet krnan vad den ska svara?  Jo, anvndaren kan explicit ha
  specificerat en geometri med en parameter som hd=cyls,heads,secs.
  Annars frgar krnan hrdvaran.


  6.1.  IDE-detaljer

  Lt mig utveckla mig.  IDE-drivrutinen har fyra kllor fr information
  om geometrin.  Den frsta (G_user) r den som anvndaren kan ha
  specificerat p kommandoraden.  Den andra (G_bios) r BIOS'
  parametertabell (fr fixa hrddiskar; bara fr den frsta och den
  andra hrddisken) som lses innan bytet till 32-bitarsmod.  Den tredje
  (G_phys) och fjrde (G_log) returneras av IDE-kontrollern som ett svar
  p kommandot IDENTIFY -- de r de "fysiska" och "nuvarande logiska"
  geometrierna.

   andra sidan behver drivrutinen tv vrden fr geometrin: fr det
  frsta G_fdisk, som returneras av en HDIO_GETGEO-ioctl, och fr det
  andra G_used, som faktiskt anvnds fr I/O.  Bde G_fdisk och G_used
  initialiseras till G_user om den r given, till G_bios om
  informationen finns tillgnglig enligt CMOS, och annars till G_phys.
  Om G_log verkar vara rimlig stts G_used till det.  Annars, om G_used
  inte verkar rimlig och G_phys ser rimlig ut, stts G_used till G_phys.
  Hr betyder "rimlig" att antalet huvuden ligger i intervallet 1-16.

  Med andra ord: kommandoraden har hgre prioritet n BIOSet och
  bestmmer vad fdisk ser, men om det specificerar en versatt geometri
  (med fler n 16 huvuden) kommer det som returneras frn IDENTIFY-
  kommandot att anvndas fr krn-I/O.


  6.2.  SCSI-detaljer

  Situationen fr SCSI r ngot annorlunda, eftersom SCSI-kommandona
  redan anvnder logiska blocknummer, s en "geometri" r helt
  irrelevant fr I/O i praktiken.  Formatet fr partitionstabellen r
  emellertid fortfarande samma, s fdisk mste uppfinna en geometri och
  anvnder HDIO_GETGEO hr ocks -- faktiskt skiljer inte fdisk p IDE-
  och SCSI-hrddiskar.  Som man kan frst frn den detaljerade
  beskrivningen nedan, uppfinner de olika drivrutinerna en ngot
  annorlunda geometri.  Helt klart en sagolik rra.

  Om du inte anvnder DOS eller s, undvik alla instllningar rrande
  utkad versttning och anvnd bara 64 huvuden, 32 sektorer per spr
  (vilket ger trevliga 1 MB per cylinder), om mjligt, s att inga
  problem uppstr nr du flyttar hrddisken frn en kontroller till en
  annan.  Vissa drivrutiner fr SCSI-hrddiskar (aha152x, pas16, ppa,
  qlogicfas, qlogicisp) r s mna om att bibehlla DOS-kompatibilitet
  att de inte tillter ett system som bara kr Linux att anvnda mer n
  8 GB.  Detta r en bugg.

  Vad r den riktiga geometrin?  Det lttaste svaret r att det inte
  finns ngon sdan.  Och om det fanns skulle du inte vilja vet ngot om
  den och skerligen ALDRIG NGONSIN tala om den fr fdisk eller LILO
  eller krnan.  Det r endast relevant fr SCSI-kontrollern och
  hrddisken.  Lt mig upprepa: bara dumma personer talar om den riktiga
  geometrin fr en SCSI-hrddisk fr fdisk/LILO/krnan.

  Men om du r nyfiken och insisterar kan du frga hrddisken sjlv.
  Det finns det viktiga kommandot READ CAPACITY som ger den totala
  storleken p hrddisken och det finns kommandot MODE SENSE som i
  "Rigid Disk Drive Geometry Page" (sida 04) ger antalet cylindrar och
  huvuden (detta r information som inte gr att ndra), och "Format
  Page" (sida 03) ger antal byte per sektor och antal sektorer per spr.
  Det sistnmnda antalet r typiskt beroende av notchen och antalet
  sektorer per spr varierar -- de yttre spren har fler sektorer n de
  inre.  Linuxprogrammet scsiinfo kan ge den hr informationen.  Det
  finns mnga detaljer och komplikationer och det str klart att ingen
  (inte ens operativsystemet) vill anvnda denna information.  Dessutom:
  s lnge man enbart bryr sig om fdisk och LILO fr man typiskt svar
  som C/H/S=4476/27/171 -- vrden som inte kan anvndas av fdisk
  eftersom partitionstabellen endast reserverar 10 respektive 8
  respektive 6 bitar fr C/H/S.

  S var fr krnanropet HDIO_GETGEO sin information frn?  Jo, antingen
  frn SCSI-kontrollern eller genom att gra en kvalificerad gissning.
  Ngra drivrutiner verkar tro att vi vill knna till "verkligheten",
  men sjlvklart vill vi bara veta vad FDISK i DOS eller OS/2 (eller
  Adaptecs AFDISK, etc) kommer att anvnda.

  Notera att Linux' fdisk behver talen H och S (fr huvuden och
  sektorer) fr att kunna konvertera LBA-sektornummer till C/H/S-
  adresser, men talet C (cylindrar) spelar ingen roll i den hr
  konverteringen.  Ngra drivrutiner anvnder (C,H,S) = (1023,255,63)
  fr att signalera att hrddiskkapaciteten r minst 1023*255*63
  sektorer.  Detta r olyckligt, eftersom det inte avsljar den riktiga
  storleken, vilket kommer att begrnsa anvndarna av de flesta fdisk-
  versionerna till att anvnda 8 GB av sina hrddiskar -- en riktig
  begrnsning i dessa dagar.

  I beskrivningen nedan str M fr den totala hrddiskkapaciteten och C,
  H, S fr antalet cylindrar, huvuden och sektorer per spr.  Det rcker
  att ge H, S om vi betraktar C som definierad av M / (H*S).

  Standardmssigt r H=64, S=32.


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


     aha152x, pas16, ppa, qlogicfas, qlogicisp:
        H=64, S=32 om inte C > 1024, d H=255, S=63, C = min(1023,
        M/(H*S)).  (Allts trunkeras C och H*S*C r inte en
        approximation fr hrddiskkapaciteten M.  Detta gr de flesta
        fdisk-versioner frvirrade.)  Koden i ppa.c anvnder M+1
        istllet fr M och sger p grund av en bugg i sd.c att M r ett
        fr lite.


     advansys:
        H=64, S=32 om inte C > 1024 och "> 1 GB" r instllt i BIOS, d
        H=255, S=63.


     aha1542:
        Frga kontrollern vilket av tv mjliga stt att verstta p
        som ska anvndas och anvnd antingen H=255, S=63 eller H=64,
        S=32.  I det frsta fallet blir det ett boot-meddelande:
        "aha1542.c: Using extended bios translation".


     aic7xxx:
        H=64, S=32 om inte C > 1024 och antingen boot-parametern
        "extended" gavs eller att biten "extended" var satt i SEEPROM
        eller BIOS, d H=255, S=63.


     buslogic:

        H=64, S=32 om inte C >= 1024, och om utkad versttning r
        instllt p kontrollern, s r H=128, S=32 om M < 2^22, annars
        H=255, S=63.  Efter att detta val har gjorts lses
        partitionstabellen och om vrdet endH=H-1 syns fr ngon av de
        tre mjligheterna (H,S) = (64,32), (128,32), (255,63), blir det
        ett boot-meddelande: "Adopting Geometry from Partition Table".

     fdomain:
        Ta reda p geometriinformationen frn parametertabellen fr
        hrddiskar i BIOS eller ls partitionstabellen och anvnd
        H=endH+1, S=endS fr den frsta partitionen, ifall den inte var
        tom, annars: anvnd H=64, S=32 fr M < 2^21 (1 GB), H=128, S=63
        fr M < 63*2^17 (3,9 GB) och H=255, S=63.


     in2000:
        Anvnd den frsta av (H,S) = (64,32), (64,63), (128,63),
        (255,63) som gr att C <= 1024.  I det sista fallet, trunkera C
        vid 1023.


     seagate:
        Ls C,H,S frn hrddisken.  (Iiiick!)  Om C eller S r fr stor,
        stt S=17, H=2 och dubbla H tills C <= 1024.  Detta innebr att
        H kommer att sttas till 0 om M > 128*1024*17 (1,1 GB).  Detta
        r en bugg.


     ultrastor och u14_34f:
        En av tre mappningar ((H,S) = (16,63), (64,32), (64,63)) anvnds
        beroende p kontrollerns mappningsmod.


  Om drivrutinen inte specificerar geometrin anvnder vi en kvalificerad
  gissning genom att anvnda partitionstabellen eller genom att anvnda
  den totala hrddiskkapaciteten.

  Kolla p partitionstabellen.  Eftersom, per konvention, partitioner
  slutar p en cylindergrns kan vi, givet end = (endC,endH,endS) fr
  vilken partition som helst, helt enkelt stta H = endH+1 och S = endS.
  (Kom ihg att sektorerna rknas frn 1.)  Mer precist grs fljande:
  Om det finns en icke-tom partition, vlj den partition med strst
  beginC.  Titta p end+1 fr den partitionen, berknat genom att bde
  addera start och length och genom att anta att partitionen slutar p
  en cylindergrns.  Om bda vrdena stmmer verens eller om endC =
  1023 och start+length r en heltalsmultipel av (endH+1)*endS, anta att
  partitionen faktiskt var placerad p en cylindergrns och stt H =
  endH+1 och S = endS.  Om detta inte fungerar, antingen p grund av att
  det inte finns ngra partitioner eller p grund av att de har konstiga
  storlekar, kolla bara p hrddiskkapaciteten M.  Algoritm: stt H =
  M/(62*1024) (avrundat uppt), S = M/(1024*H) (avrundat uppt), C =
  M/(H*S) (avrundat nert).  Detta ger en (C,H,S) med C hgst 1024 och S
  hgst 62.

  7.  Linux 8 GB-begrnsning fr IDE

  Linux IDE-drivrutin hmtar geometrin och hrddiskkapaciteten (och
  mnga andra saker) genom att anvnda ett ATA IDENTIFY-anrop.  Tills
  nyligen trodde inte drivrutinen p det returnerade vrdet frn
  lba_capacity om det var mer n 10 % strre n kapaciteten berknad
  genom C*H*S.  Nyare Quantum Bigfoot 12 GB-hrddiskar returnerar
  emellertid C=16383, H=16, S=63, vilket ger totalt 16514064 sektorer
  (7,8 GB) men rapporterar lba_capacity som 23547888 sektorer (det vill
  sga 11,2 GB, C=23361).

  Nyare Linuxkrnor (2.0.34pre14, 2.1.90) knner till detta och beter
  sig rtt.  Om du har en ldre Linuxkrna och inte vill uppgradera, och
  krnan bara ser 8 GB av en mycket strre hrddisk, kan du testa att
  ndra rutinen lba_capacity_is_ok i /usr/src/linux/drivers/block/ide.c
  till ngonting likt



  static int lba_capacity_is_ok (struct hd_driveid *id) {
          id->cyls = id->lba_capacity / (id->heads * id->sectors);
          return 1;
  }




  Fr en mer frsiktig patch, se 2.1.90.

























































