|
Załóżmy, że posiadasz dysk z więcej niż 1024 cylindrami. Co więcej załóżmy, że posiadasz system który korzysta z BIOSu. Wtedy masz problem. Masz problem ponieważ zwykły interfejs We/Wy twojego dysku realizowany przez przerwanie BIOSu INT13, które do przekazywania numeru cylindra, na którym ma zostać wykonana operacja We/Wy korzysta z 10-cio bitowego pola, przez co cylindry o numerze 1024 i wiekszym są niedostępne.
Na szczęście Linux nie korzysta z BIOSu, więc nie ma tego problemu.
No prawie, poza dwoma przypadkami:
(1) Kiedy uruchamiasz swój system, Linux jeszcze nie działa i nie potrafi uchronić cię przed kłopotami z BIOSem. Ma to wpływ na pracę LILO i innych ładowaczy systemów (boot loaders).
(2) Wszystkie systemy operacyjne korzystające z tego samego dysku muszą zgadzać się co do położenia poszczególnych partycji. Innymi słowy, jeśli korzystasz na jednym dysku z Linuxa i powiedzmy DOSu, wtedy oba muszą interpretować tabelę partycji w ten sam sposób. Ma to wpływ na sposób zachownia jądra i programu fdisk.
Poniżej znajdziesz sczegółowy opis wszelkich istotnych szczegółów. Zauważ, że wszelkie informacje odnoszą się do jądra w wersji 2.0.8. Inne wersje jądra mogą zachowywać się troszkę inaczej.
Podczas ładowania systemu, BIOS odczytuje z pierwszego dysku twardego (lub z dyskietki) sektor 0 (znany jako główny sektor startowy (Master Boto Record, MBR)) i wykonuje skok do znalezionego tam kodu - zwykle do programu ładowania początkowego. Te małe programy ładujące (ładowacze) jakie się tam znajdują, nie posiadają wlasnych drajwerów dyskowych i korzystają z funkcji BIOSu. To znaczy, że jądro Linuxa może zostać załadowane, tylko wtedy gdy w całości znajduje się poniżej 1024 cylindra.
Ten problem można bardzo łatwo rozwiązać. Upewnij się, że jądro (i być może inne pliki wykorzystywane do startu systemu, np. pliki odzworowań programu LILO) znajdują się na partycji, która w całości zawiera się w obszrze ponizej 1024 cylindra dysku, do którego BIOS ma dostęp - zwykle pierwszy lub drugi dysk twojego komputera.
Poza tym ładowacz i BIOS muszą się zgadzać w sprawie geometrii dysku. Tutaj może okazać się pomocne skorzystanie w konfiguracji LILO z opcji linear. Więcej szczegółów później.
Jeśli posiadasz na jednym dysku kilka systemów operacyjnych, wtedy każdy z nich używa jednej lub więcej partycji. Niezgodność w ocenie, gdzie te partycje się dokładnie znajdują może mieć katastrofalne konsekwencje.
Rekord MBR zawiera tabelę partycji określającą, gdzie znajdują się partycje (podstawowe). Tabela zawiera 4 pozycje (dla 4 partycji) i wygląda mniej więcej tak:
struct partition {
char active; /* 0x80: startowa, 0: nie strtowa */
char begin[3]; /* CHS pierwszego sektora partycji */
char type;
char end[3]; /* CHS ostatniego sektora partycji */
int start; /* 32 bitowy numer sektora (licząc od 0) */
int length; /* 32 bitowa liczba sektorów */
};
(gdzie CHS oznacza numer cylindra/głowicy/sektora).
Jak widać informacja jest nadmiarowa: lokalizacja partycji jest podana
zarówno w 24-ro bitowych polach begin
i end
, oraz w 32-dwu
bitowych polach start
i length
.
Linux korzysta jedynie z pól start
i length
, dlatego potrafi
obsłużyć partycje o liczbie sektorów nie przekraczającej 2^32
tzn. partycje o rozmiarze nie większym niż 2 TB. Czyli dwieście razy
większą od dysków obecnie dostępnych na rynku. Możemy mieć nadzieje,
że będzie to wystarczające na najbliższe 10 lat, a może więcej.
Niestety, funkcja BIOSu INT13 korzysta z inforamacij CHS zakodowanych w polach 3bajtowych, przy czym na numer cylindra przeznaczonych jest 10 bitów, 8 bitów na numer głowicy i 6 bitów na numer sektora na ścieżce. Dozwolone numery cylindrów to 0-1023, głowic 0-255 i dozwolona liczba sektorów na ścieżce wynosi 1-63 (tak, sektory na ścieżce są liczone od 1, a nie od 0). Na tych 24 bitach można zaadresować nie więcej niż 8455716864 bajtów (7.875 GB), dwieście razy więcej niż rozmiar dysków dostępnych w roku 1983.
Kolejne, ważniejsze (groźniejsze) ograniczenie polega na tym, że standard interfejsu IDE pozwala jedynie na: 256 sektorów na ścieżce, 65536 cylindrów i 16 głowic. Sam w sobie pozwala na dostęp do 2^37 = 137438953472 bajtów (128 GB), lecz w połączeniu z ograniczeniami nałożonymi przez BIOS, faktycznie umożliwia na dostęp tylko do 528482304 bajtów (504 MB).
Nie jest to wystarczające dla dostępnych obecnie dysków i ludzie są zmuszeni do stosowania różnego rodzaju sztuczek, zarówno sprzętowych, jak i programowych.
Nikogo nie interesuje jaka jest `rzeczywista' geometria dysku. Tak na prawdę, liczba sektorów na ścieżce często jest zmienna - więcej na ścieżkach zewnętrznych i mniej na ścieżkach wewnętrznych - nie ma tak na prawdę `rzeczywstej' liczby sektorów na ścieżce. Dla użytkownika najwygodniej jest traktować dysk jako liniową tablicę sektorów, ponumerowanych 0,1 ... i pozostawić sterownikowi zadanie odnalezienia położenia danego sektora na dysku.
To numerownie liniwe znane jest pod skrótem LBA. Adres liniowy należacy do sektora (c,h,s) dla dysku o geometrii (C,H,S) jest równy c*H*S+h*S+(s-1). Wszystkie sterowniki SCSI porozumiewają się według standardu LBA, niektóre sterowniki IDE również.
BIOS zamienia 24-bitowe pole (c,h,s) na adres LBA i przekazuje to sterownikowi, który rozumie co to jest LBA. Dzięki temu ponownie mamy dostęp do 7.785 GB. Nie jest to wystarczające dla wszystkich dysków, lecz jest to lepsze niż to co było. Zauważ, że CHS wykorzystywane przez BIOS nie ma żadnego związku z rzeczywistością.
Coś poddobnego dzieje się w sytuacji, gdy sterownik nie rozumie adresów LBA, lecz BIOS wie o translacji (w Setupie BIOSu jest to zwykle oznaczane jako `Large'). Teraz BIOS prezentuje systemowi operacyjnemu geometrię (C',H',S') i używa geometrii (C,H,S) do komunikacji ze sterownikiem. Zwykle S=S' C'=C/N i H'=H*N, gdzie N jest najmniejszą potęgą 2, zapewniającą spełnienie warunku ' <= 1024 (w celu zminimalizowania marnującej się przestrzeni przez zaokrąglenie w dół C'=C/N). Ta metoda również pozwala uzyskać dostęp do 7.875 GB.
Jeśli BIOS nic nie wie na tema `Large' lub LBA, wtedy pozostają rozwiązania oparte na odpowiednich drajwerach. Takie programy, jak OnTrack lub Ez-Drive zamieniają programy obsługi dysku należące do BIOSu na własne. Często jest to realizowane, przez umieszenie kodu należacego do Disk Managera w rekordzie MBR i kolejnych sektorach dysku (OnTrack nazywa to DDO: Dynamic Drive Overlay) aby był on uruchamiany przed załadowniem jakiegokolwiek systemu operacyjnego. To wyjaśnia kłopoty związane ze startowniem systemu z dyskietki, dla dysków z zainstalowanym programem Disk Manager.
Efekt całego tego zamieszania jest mniej więcej taki sam, jak w przypadku translacji przez BIOS - lecz w sytuacjach, gdy na jednym dysku znajduje się wiele systemów operacyjnych programy typu Disk Manager mogą sprawiać wiele kłopotów.
Linux od wersji 1.3.14 rozpoznaje istnienie programu Boot Manager firmy OnTrack i od wersji 1.3.29 firmy EZ-Drive. Więcej szczegółów znajdziesz dalej.
Jeśli jądro Linuxa rozpozna istnienie na dysku IDE programu typu disk
manager, spróbuje przeprowadzić identyczną translację jaką robi ten
właśnie program, tak aby widzieć te same partycje co np. MS-DOS z
programe OnTrack lub EZ-Drive. Jeśli jednak w parametrach startowych
zostanie przekazana geometria dysku, nie jest wykonywana żadna
translacja. Tak więc opcja startowa
`hd=
cyls,
heads,
secs' może zniszczyć
zgodność z programem typu disk manager.
Translacja wykonywana przez jądro polega na wypróbowaniu kolejno liczby głowic równej 4, 8 ,16, 32, 128, 255 (utrzymując stałą wartość H*C) aż do spełnienia warunku C <= 1024 lub H = 255.
Trochę uwag na temat tekstu poniżej - nagłówki podrozdziałów są identyczne z pojawiającymu się w komunikatach startowych. Tutaj i w całym tekscie typy partycji podane są szesnastkowo.
Rozpoznano drajwer EZ-Drive poniważ pierwsza partycja
podstawowa jest typu 55. Geometria dysku podlega opisanej powyżej
translacji i tabela partycji z sektora 0 zostaje pominięta - zmiast
tego korzystamy z tabeli partycji znajdującej się w sektorze 1. Numery
bloków dyskowych pozostają niezmienione, lecz zapis sektora 0 zostaje
przekierowany do sektora 1. To zachownie może zostać zmienione przez
ponowne skompilowanie jądra przy zdefiniowaniu w pliku ide.c #define FAKE_FDISK_FOR_EZDRIVE 0
.
Rozpoznano drajwer OnTrack Manager (na pierwszym dysku) ponieważ pierwsza partycja podstawowa jest typu 54. Geometria dysku podlega opisanej powyżej translacji i cały dysk zostaje przesunięty o 63 sektory (tak więc stary sektor 63 staje się sektorem 0). Następnie nowy rekord MBR (z tabelą partycji) zostaje odczytany z nowego sektora 0. To przesunięcie oczywiście ma na celu zrobienie miejsca dla DDO - dlatego nie jest wykonywane dla innych dysków.
Rozpoznano drajwer OnTrack Manager (na innych dyskach) ponieważ pierwsza partycja podstawowa jest typu 51 lub 53. Geometria dysku podlega opisanej powyżej translacji.
Rozpoznano starszą wersję drajwera OnTrack Manager poniważ znaleziono podpis drajwera (sprawdzono, że przesunięcie znalezione w 2-gim i 3-cim bajcie rekordu MBR nie jest większe od 430, i zmienna typu short znaleziona pod tym adresem jest równa 0x55AA, po której występuje bajt nieparzysty). Geometria dysku podlega opisanej powużej translacji.
Na końcu wykonywany jest test próbujący wydedukować istnienie
translacji na podstawie wartości pól start
i end
partycji
podstawowej:
Jeśli cylinder początkowy i końcowy jednej z partycji jest mniejszy od
256, a sektory początkowy i końcowy mają numery odpowiednio 1, i 63, a
końcowe numery głowic są równe 31, 63 lub 127, wtedy wnioskujemy, że
translacja dysku jest aktywna, i wykorzystujemy liczbę głowic
równą odpowiednio 32, 64 i 127 (ponieważ zwykle partycja kończy się na
granicy cylindra i interfejs IDE nie pozawala na więcej niż
16 głowic). Być może jest tu błąd i genhd.c nie powinien
sprawdzać dwóch najwyższych bitów zmiennej przechowującej numer
cylindra? Jednakże nie wykonuje się żadej translacji, jesli aktualny
pogląd na istniejącą geometrię już zakłada 63 sektory na ścieżce i co
najmniej tyle samo głowic (ponieważ to prawdopodownie oznacza, ze
translacja już została dokonana).
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.
Wszelkie uwagi na temat tłumaczenia mile widziane. Uwagi merytoryczne prosze kierować do autora tekstu angielskiego, chyba że podejżewasz, że są one wynikiem błędnego tłumaczenia.
Inne dokumenty HOWTO przetłumaczone na język polski znajdziesz tutaj: http://www.ippt.gov.pl/~ppogorze/Linux/JTZ/.
Wersje txt i html lepiej nadajace sie do druku sa tutaj: ftp://www.ippt.gov.pl/pub/Linux/JTZ/.
# # # #
Hosting by: Hurra Communications Sp. z o.o.
Generated: 2007-01-26 18:02:22