3.1 Budowa dyskietki

Od momentu kiedy komputery zyskały możliwość startowania z dysku CD i pamięci USB dyskietki zostały zupełnie wyparte z rynku. Jednak pozostał ich pewien cień w postaci kompatybilności ładowania systemu z USB lub CD w formie takiej jak gdyby były one dyskietkami 3.5 calowymi. Jak to się odbywa mam nadzieję opisać w przyszłości, ale tutaj skupię się przede wszystkim na przypomnieniu nieco historii odnośnie dyskietek.

 

Cylindry i sektory dyskietki
Front dyskietki 3.5
Dysk magnetyczny dyskietki 3.5
Front dyskietki 3.5

Dyskietka 3.5" zawiera w sobie miękki dysk magnetyczny, który zbudowany jest z materiału, który podlega namagnesowywaniu. Kiedyś do zapisu danych stosowano taśmy magnetyczne o takiej samej mechanice zapisu. Na dyskietce nie znajduje się żadna ciągła spirala tak jak na płytach CD, natomiast dysk taki jest podzielony na cylindry i sektory. Kontroler stacji dyskietek FDC (Floppy Disc Controler) chcąc odczytać zawartość określonego sektora ustawia głowicę nad odpowiednim cylindrem za pomocą silnika krokowego, a następnie opuszcza głowicę na dysk i odczytuje jego zawartość. Przyjęło się numerować cylindry od 0 do 80 zaczynając od zewnętrznej części dysku. Tak samo ponumerowano strony dysku jako 0 i 1. Na każdej stronie na każdy cylinder przypada po 18 sektorów.

Warto przeczytać najpierw o kodowaniu FM i MFM, gdyż znajomość od podstaw systemu zapisu danych na dyskietce pomaga w zrozumieniu dalszej części tej strony.

Fizyczna organizacja dyskietki

Z punktu widzenia systemu operacyjnego jak i każdego innego programu, dyskietka składa się z cylindrycznych ścieżek, które zawierają pewną ilość 512 bajtowych sektorów. Sektor taki jest to jednostkowa ilość danych jaką można odczytać lub zapisać programując FDC. Jednak z poziomu kontrolera ścieżka dyskietki składa się ze znacznie większej ilości bajtów niż by to wynikało z sumy bajtów wszystkich sektorów. Dodatkowe pola są to pola kontrolne i synchronizacyjne. Zabezpieczają one silnik przed rozsynchronizowaniem ,służą do oznaczenia sektora jako uszkodzony lub też stanowią jakąś kontrolną wartość danych.

Przedstawię teraz i opiszę schemat takiej ścieżki od strony fizycznego rozmieszczenia danych. Wszystkie te bajty są zapisywane na dyskietkę po przejściu przez proces dekodowania FM lub MFM w postaci zmian namagnesowania podłoża.

Track

BOT
Sektor 1
Sektor 2
... ...
Sektor 18
EOT

Ścieżkę dyskietki podzieliłem na bloki ze względu na ich funkcję. BOT jest to Begin Of Track czyli blok stanowiący początek ścieżki. "Sektor N" jest to blok składający się z danych N sektora jak i jego dodatkowych znaczników. EOT jest to End Of Track, koniec ścieżki.

Przyjrzyjmy się bliżej blokowi BOT:

BOT

Z1
S
Z2
Z3

 

(Wartości poszczególnych pól w postaci ilości i wartości bajtów należy odczytać z tabeli pól znajdującej się gdzieś tutaj niżej)

Jak widać po podliczeniu sam blok BOT zajmuje 146 bajtów.

Znacznik Z1 jest znacznikiem początku ścieżki. Znacznik S składający się z samych zer ma na celu wymuszenie występowania impulsów zegarowych. Jak wiadomo dane składające się z samych zer po zakodowaniu systemem FM lub MFM dają impulsy przemagnesowania traktowane jako impulsy synchronizacji (zegarowe). Pole S składające się z samych zer ma na celu zsynchronizowanie prędkości obracania dysku z występowaniem zapisanych na nim danych. Z2 jest znacznikiem końca bloku BOT. Resztę bloku BOT wypełnia szczelina Z3 złożona z wartości 0x4E.

Sektor

S
D1
ID
CRC1
Z4
S
D3
Dane
CRC2
Z5

Zaraz za blokiem BOT znajduje się ciąg następujących po sobie bloków sektorów. Schemat takiego bloku znajduje się powyżej.

Rozpoczyna się znacznikiem S synchronizującym częstotliwość zegara. Znacznik D1 informuje kontroler o tym że następnym znacznikiem jest metryka adresowa sektora ID. Pole ID zostało szerzej opisane poniżej w tabeli przedstawiającej wartości wszystkich znaczników. Pole ID informuje kontroler FDC o numerze ścieżki, głowicy, sektora i rozmiarze tego sektora. Podczas odczytu FDC właśnie po polu ID identyfikuje dany sektor który trzeba odczytać. Pola D1 i ID zabezpieczone są kodem CRC1 znajdującym się tuż za nimi. Z4 następna szczelina pomiędzy CRC1 ,a kolejnym polem synchronizującym S. Znacznik D3 informuje o początku danych sektora, które są zabezpieczone kodem CRC2 zapisanym tuż za nimi.

Szczeliny Z4 i Z5 mają funkcję operacji NOP w asemblerze. Podczas odczytu ich zawartości kontroler FDC oblicza sumy CRC i porównuje z odczytanymi wartościami. Tak więc pełnią one funkcję opóźniającą.

Wszystkie sektory są zapisane w tym samym schemacie przedstawionym wcześniej i następują kolejno po sobie. Czyli pole S następnego sektora jest tuż za polem Z5 poprzedniego i tak aż do ostatniego sektora ścieżki. Po wszystkich sektorach znajduję się pole EOT zawierające tylko jeden znacznik Z6.

Wnioski

Po podliczeniu całkowitej fizycznej ilości bajtów przypadającej na blok zapisu sektora otrzymamy 654 bajty. Więc należy mieć świadomość tego że fizycznie dysk ma dużo większą pojemność danych niż pojemność jaką się przeznacza na efektywne wykorzystanie. Jednak nie można pominąć istnienia dodatkowych pól kontrolnych bo stanowią one bazę do możliwości odczytu zapisanych przez nas danych.

Formatowanie niskopoziomowe nie jest niczym innym jak właśnie nanoszeniem na dysk takiej podstawowej struktury kontroli i przechowywania danych. Na niektóre uszkodzenia dyskietek tylko formatowanie niskopoziomowe pomaga w przywróceniu ich do funkcjonowania.

Znacznik
Opis
Z1
80 bajtów o wartości 4Eh
S
12 bajtów o wartości 0
Z2
4 bajty o wartościach C2h C2h C2h FCh
Z3
50 bajtów o wartości 4Eh
D1
4 bajty o wartościach A1h A1h A1h FEh
CRC1
16bitowy kod zabezpieczający pola D1 i ID
CRC2
16bitowy kod zabezpieczający pole Danych
Z4
22 bajty o wartości 4Eh
D3
4 bajty o wartościach A1h A1h A1h FBh
Z5
80 bajtów o wartości 4Eh
Z6
80 bajtów o wartości 4Eh (EOT)
ID
bajt1 - numer ścieżki
bajt2 - numer głowicy
bajt3 - numer sektora
bajt4 - rozmiar sektora
* 000 - 128B
* 001 - 256B
* 010 - 512B
* 011 - 1KB
* 100 - 2KB
* 101 - 4KB
* 110 - 8KB
* 111 - 16KB

 

Adresowanie Sektora

Pole ID każdego sektora charakteryzuje jego adres i rozmiar z czego wywodzi się adresowanie fizyczne dysku, które jest nazywane CHS. W tłumaczeniu na polski Cylinder-cylinder, Head-głowica, Sector-sektor. Head określa która głowica ma wykonać odczyt jest to praktycznie jednoznaczne z numerem strony dysku.

Sektory na danym cylindrze są numerowane od 1 do określonej ich liczby, przykładowo 0x12 czyli 18d. Na cylindrze jest jedno miejsce ściśle określone jako początek ścieżki i od tego miejsca zaczyna się numerowanie sektorów od 1 do 18. Cylindry numeruje się od 0 do ich określonej liczby. Pierwszy (czyli zerowy) cylinder znajduje się na zewnętrznej części dysku.

Oczywiście w przypadku bezpośredniego odczytu z dyskietki trzeba przesłać do kontrolera FDD te kolejne parametry CHS. Jednak w programach łatwiej jest posługiwać się innym systemem operowania na sektorach. Układa się wszystkie sektory jeden za drugim z cylindrów, stron i numeruje kolejno. Takie adresowanie bezwzględne przez jedną liczbę jest bardzo podobne do adresowania pamięci RAM. To adresowanie sektora nosi nazwę LBA Logical Block Addressing, czyli adresowania logicznego. Należy tylko wyjaśnić, które sektory są brane w kolejno w adresowaniu LBA czyli trzeba podać schemat przeliczania adresów CHS<->LBA.

Jako pierwszy cylinder bierzemy ten najbardziej oddalony od środka czyli brzegowy nr0 ze strony nr0. I kolejne sektory z tego cylindra są pierwszymi sektorami w adresowaniu LBA (sektory w LBA numeruje się od 1). Kolejnymi sektorami są sektory z tego samego cylindra, ale ze strony nr1. Potem są sektory z następnego cylindra strony 0. Postaram się teraz to przedstawić w tabeli:

LBA
1
2
3
...
18
19
20
...
36
37
38
...
54
56
...
C:H:S
0:0:1
0:0:2
0:0:3
...
0:0:18
0:1:1
0:1:2
...
0:1:18
1:0:1
1:0:2
...
1:0:18
1:1:1
...

Tak więc przechodzimy po cylindrach od brzegu zewnętrznego do środka biorąc je na przemian z każdej ze stron.

Od teraz będę podawał numery sektorów w adresowaniu LBA.

Boot Sector

Pierwszy sektor dyskietki jest nazywany BS Boot Sectorem. Jego budowa musi spełniać pewne wymagania bez względu na to jaki system plików znajduje się na niej. Na dyskietkach opisywanych przeze mnie sektor zajmuje 512d = 0x200 bajtów. Schemat takiego sektora opisałem w artykule opisującym system plików FAT więc tych, którzy go nie znają odsyłam właśnie do tamtego opisu. Po odliczeniu miejsca na niezbędne części tego sektora zostaje w nim mniej więcej 449 bajtów wolnych.

Jeżeli podczas startu systemu mamy w BIOSie ustawioną opcję uruchamiania z dyskietki i znajduje się ona w stacji to BS zostaje załadowany pod adres fizyczny 0x7C00. Przy adresowaniu segment:offset jest to adres 07C0:0000. I jest wykonany daleki skok właśnie pod ten adres. W strukturze tego sektora na początku znajduje się bliski skok zaadresowany za blok parametrów nośnika. I to miejsce za tym bokiem jest dostępne dla kodu ładującego system operacyjny z dyskietki. Kod ładujący system jest nazywany BL Boot Loader'em.

449 bajtów nie jest to dużo jak na kod ładujący system, dlatego programy ładujące BL przeważnie nie ładują od razu systemu operacyjnego do pamięci dlatego, że są zbyt małymi programami. Istnieje kilka typów rozwiązań tego problemu.

Można wykorzystać BL to wczytania kolejnych sektorów znajdujących się na dyskietce, które zawierają nasz system operacyjny. Jednak taka dyskietka nie będzie już zawierała struktury FAT i nie będzie mogła być odczytana przez system Windows czy Linux. Jednak cała dyskietka będzie dostępna dla przechowywania naszego kodu systemu (lub naszego dowolnego systemu plików).

Można wykorzystać BL do ładowania N kolejnych sektorów w których znajduje się reszta kodu, która będzie służyła dopiero do załadowania systemu operacyjnego ze struktury FAT12, która zostaje zachowana na dyskietce. Jednak aby zachować zgodność ze strukturą FAT12 w bloku parametrów nośnika w pierwszym sektorze w polu ReservedSectrors należy wpisać wartość N+1. 1 jest to Boot Sector, a N jest to kolejna ilość sektorów, która zawiera resztę kodu ładującego system, która będzie wczytana do pamięci przez nasz Boot Loader. Ten sposób pozwala przechowywać nasz system w postaci dowolnego pliku w systemie FAT12 do którego mamy wolny dostęp z praktycznie każdego systemu operacyjnego. A nasz Boot Loader z pierwszego sektora wczytuje resztę swojego kodu i danych z N kolejnych następnych sektorów, zwiększając swój rozmiar do N*512+449 bajtów. Taki duży BL jest już w stanie wykonać większą ilość zadań poprzedzających załadowanie naszego systemu z pliku w systemie FAT12