Jakie to wszystko ma znaczenie? Dla użytkowników Linuxa tylko jedno: muszą się upewnić, że LILO i fdisk używają `poprawnej' geometrii, gdzie `poprawna' w przypadku fdiska jest rozumiana jako geometria używana przez inne systemy operacyjne znajdujące sie na tym samym dysku, a w przypadku LILO, że jest to geometria pozwalająca na poprawną współpracę z BIOSem podczas ładowania systemu.
Jak fdisk dowiaduje się o geometrii?
Pyta się jądra przy pomocy funkcji ioctl HDIO_GETGEO.
Lecz użytkownik może podać dowolną geometrię dysku przez parametry w
wierszu poleceń lub później w samym programie.
Jak LILO dowiaduje się o geometrii dysku? Pyta się jądra przy pomocy
funkcji ioctl HDIO_GETGEO. Lecz użytkownik może podać łasne
inforamacje z pomocą opcji `disk='. Można również skorzystac z
opcji linear, co spowoduje, że LILO zachowa w pliku odwzorwania (map
file) adres LBA, zamiast CHS i podczas ładowania sytemu odczyta
geometrię dysku (wykorzystujęc funkcję nr 8 przerwania INT 13).
Skąd jądro wie co odpowiedzieć?
Ha!, po pierwsze użytkownik może przekazć mu odpowiednie informacje
jako parametr wiersza zachęty startowej:
`hd=cyls,heads,secs'.
W innym przypadku jądro przepyta na ten temat sprzęt.
Trochę szczegółów. Drajwer IDE posiada cztery źródła informacji o geometrii dysku. Pierwsze (G_user) to dane podane przez użytkwonika w wierszu zachety. Drugie (G_bios) to inforamcje BIOSu (tylko dla pierwszego i drugiego dysku), które są odczytywana podczas uruchamiania systemu, przed przełączeniem się w tryb 32-bitowy. Trzecie (G_phys) i czwarte (G_log) są przekazywane przez sterownik IDE jako odpowiedź na polecenie IDENTIFY - są to `fizyczna' i aktualna `logiczna' geometria dysku.
Z drugiej strony, sterownik potrzebuje dwóch informacji o geometrii
dysku: lecz posiada z jednej strony G_fdisk, przekazywane przez funkcję ioctl
HDIO_GETGEO, a z drugiej strony G_used, które jest naprawdę
wykorzystywane do wykonywania operacji We/Wy. Zarówno G_fdisk, jak i
G_used są inicjowane: wartościami G_user jeśli są podane, G_bios jeśli
ta inforamcja jest dostepna wg. CMOS, lub G_phys w przeciwnym wypadku.
Jesli G_log wygląda rozsądnie to G_used przybiera tę własnie
wartość. W przeciwnym wypadku, jeśli G_used nie ma większego sensu i
G_phys wygląda OK, wtedy G_used przyjmuje wartość G_phys. W tym
przypadku `rozsądnie' oznacza, że liczba głowic jest w zakresie 1-16.
Innymi słowy parametry wiersza zachęty są ważniejsze od informacji pobranych z BIOSu i określają jaką geometrię widzi fdisk, lecz jeśli podane informacje odpowiadają geometri poddanej translacji (wiecej niż 16 głowic), wtedy operacje We/wy jądra zostaną zastąpione odpowiedzią sterownika na polecenie IDENTIFY.
Sytuacja w przypadku SCSI jest trochę inna, ponieważ polecenia SCSI
używają logicznych numerów bloków, tak więc geometria dysku nie ma
absolutnie żadnego znaczenia dla operacjami We/Wy.
Jednakże format tabeli partycji jest ciągle ten sam, więc fdisk musi
wymyśleć jakąś geometrię i również w tym przypadku korzysta z funkcji
HDIO_GETGEO - w rzeczywistości fdisk nie rozróżnia dysków IDE i
SCSI. Jak każdy może się sam przekonać (na podstawie szczegółowego
omówienia poniżej) poszcególne drajwery wymyślają różne
geometrię. Rzeczywiście jeden wielki balagan.
Jeśli nie korzystasz DOSu, to unikaj wszelkich ustawień rozszerzonych translacji i jeśli to możliwe, używaj ustawień 64 głowice, 32 sektory na ścieżce (wtedy jeden cylinder ma ładny rozmiar 1MB). Unikniesz problemów, gdy przeniesiesz dysk z jednego sterownika do innego. Niektóre dyski SCSI (aha152x, pas16, ppa, qlogicfas, qlogicisp) są tak nerwowe w sprawach zgodności z MS-DOSem, że nie pozwolą systemowi z zainstalowanym wyłącznie systemem Linux na wykorzystanie więcej niż 8GB. To jest błąd.
Jaka jest rzeczywista geometria? Najprostsza odpowiedź mówi, że nie ma czegoś takiego. I gdyby była, to nie chciałbyś wiedzieć, i na pewno NIGDY, ale to PRZENIGDY nie mów o tym fdiskowi, LILO lub jądru. To jest po prostu sprawa pomiędzy dyskiem i sterownikiem SCSI. Pozwolisz, że powtórzę: tylko głupcy mówią fdiskowi/LILO/jądru o rzeczywistej geometrii dysków SCSI.
Lecz jeśli jesteś ciekaw i nalegasz, możesz spytać o to sam dysk. Istnieje bardzo ważne polecenie READ CAPACITY, które przekazuje całkowią objętość dysku, a drugie polecenie MODE SENSE (patrz Rigid Disk Drive Geometry Page (strona 04)) pozwala odczytać liczbę cylindrów i głowic (ta informacje nie może być zmieniona), natomiast w Format Page (strona 03) podaje liczbę bajów w sektorze i liczbę sektorów w ścieżce. Ta ostania liczba jest zwykle zależna od wycięcia (notch) i liczba sektorów na ścieżce jest zmienna - ścieżki zewnętrzne posiadają więcej sektorów, wewnętrzne mniej. Program pracujący pod Linuxem o nazwie scsiinfo poda ci te wszystkie informacje.
Jest wiele szcegółów i komplikacji, i jest jasne, że nikt (prawdopodobnie nawet sam system operacyjny) nie chce wykorzystywać tej informacji. Co więcej, tak długo jak martwimy się tylko o fdisk i LILO, zwykle otrzymuje się odpowiedz typu C/H.S=4476/27/171 - wartości, które nie mogą być wykorzystane przez fdisk, ponieważ tabela partycji rezerwuje jedynie dla C/H/S odpowiednio 10/8/6 bitów.
To skąd na ten temat bierze informację funkcja HDIO_GETGEO ?
Cóz, albo ze sterownika SCSI lub zgaduje. Wygląda, że niektóre dyski
myslą, że interesuje nas `rzeczywistość', lecz nas oczywiście
interesuje jedynie jakie parametry będą używane przez FDISK pod DOSem
czy OS/2 (lub AFDISK Adapteca).
Pamiętaj, że fdisk Linuxa potrzebuje znać liczbę głowic H i sektorów na ścieżce S, aby móc zamienić numer sektora w foramcjie LBA na adres c/h/s, lecz liczba cylindrów C nie ma znaczenia w tej konwersji. Niektóre dyski używają (C,H,S)=(1032,255,63) w celu zasygnalizowania, że dysk ma co najmniej 1023*255*63 sektorów. Niestety to nie ujawnia aktualnego rozmiaru dysku i będzie ograniczało użytkowników większości wersji programu fdisk do wykorzstania tylko około 8GB ich dysków - w dzisiejszych czasach jest to poważne ograniczenie.
W opisie przedstawionym poniżej, M oznacza całkowitą pojemność dysku, a C,H i S liczbę cylindrów, głowic i sektorów na ścieżce. Jeśli traktujemy C jako wynik działania C = M / (H*S), wtedy wystarczy podać H i S.
Domyślnie H=63,S=32.
H=64, S=32.
H=64, S=32 unless C > 1024, W takim przypadku H=255, S=63, C = min(1023, M/(H*S)). (Tak więc C jest obcięte i h*s*C nie jest aproksymacją rozmiaru dysku M. Taka sytuacja potrafi ogłupić większość wersji programu fdsik.) Kod w pliku ppa.c wykorzystuje M+1 zamiast M i twierdzi, że to z poowdu błędu w sd.c M jest przesunięte o 1.
H=64, S=32 chyba, że C > 1024 i co więcej przy włączonej opcji BIOSu `> 1 GB', co w takim przypadku daje H=255, S=63.
Spytaj sterownika, który z możliwych dwóch schematów translacji jest w użyciu, i użyj albo H=255, S=63 lub H=64, S=32. W ostanim przypadku wyświetlany jest komunikat startowy "aha1542.c: Using extended bios translation".
H=64, S=32 chyba, że C > 1024, i co więcej jeśli przekazano parametr startowy (boot) "extended", lub jeśli w pamięci SEEPROM, lub BIOSie był ustawiony bit `extended', to w takim przypadku przyjmuje się H=255, S=63.
H=64, S=32 chyba, że C >= 1024, i co więcej na sterwoniku została włączona translacja rozszerzona, co w takim pryzpadku powoduje przyjęceie parametrów H=128, S=32 jeśli M < 2^22 lub H=255, S=63 w przeciwnym wypadku. Jednakże po dokonaniu wyboru (C,H,S) odczytywana jest tabela partycji i jeśli dla jednej z trzech możliwości (H,S) = (64,32), (128,32), (255,63) gdziekolwiek zgadza się równość endH=H-1, wtedy stosowana jest dana para (H,S) i wyświetlany jest komunikat "Adopting Geometry from Partition Table".
Znajduje parametry w tabeli parametrów dysku BIOSu, lub odczytuje tabelę partycji i używa translacji H=endH+1, S=endS w przypadku pierwszej partycji (pod warunkiem, że nie jest pusta), lub używa H=64, S=32 w przypadku gdy M < 2^21 (1 GB), lub H=128, S=63 jeśli M < 63*2^17 (3.9 GB) w przeciwnym wypadku. H=255, S=63.
Użyj pierwszej pary (H,S) = (64,32), (64,63), (128,63), (255,63), dla której zajdzie nierówność C <= 1024. W przeciwnym wypadku skróć C do 1023.
Odczytuje C,H,S z dysku. (Horror!) Jeśli C lub S jest zbyt duże wtedy przyjmuje S=17,H=2 i podwaja H aż V <<;= 1024. To znaczy, że H będzie miało wartość 0, jeśliM > 128*1024*17 (1.1 GB). To jest błąd.
W zależności o trybu sterownika wykorzystywane jest jedno z następujących odwzoroań:((H,S) = (16,63), (64,32), (64,63))
Zobacz tabelę partycji. Ponieważ powszechnie partycja kończy się na
granicy cylindra, znając dla każdej partycji end =
(endC,endH,endS) możemy po prostu przyjąć H = endH+1 and S =
endS. (Przypomnij sobie, że sektory liczy się od 1.) A dokładniej
wykonywana jest następująca operacja.
Jeśli istnieje niepusta partycja, odczytaj tę o największej wartości
beginC. Dla tej partycji sprawdź end+1, obliczone przez
dodanie start i length przy założeniu, że ta partycja kończy
się na granicy sektorów. Jeśli obie wartości się zgadzają lub jeśli
endC = 1023 i start+length jest całkowitą wielokrotnością
(endH+1)*endS, wtedy możemy założyć, że ta partycją rzeczywiście
była wyrównana do granicy cylindra i przyjąć H = endH+1 i S =
endS.
Jeśli jednak tak nie jest, a to dlatego, że nie ma żadnej partycji,
lub dlatego, że partycje mają dziwne rozmiary wtedy spróbuj
wykorzystać pojemność dysku M. Algorytm: przyjmij H=M/(62*1024)
(zaokrąglone w górę), S = M/(1024*H) (zaokrąglone w gorę), C = M/(H*S)
(zaokrąglone w dół). W ten sposób otrzymamy geometrię (C,H,S), prz
czym C nie przekroczy 1024, a S 62.