mardi 1 juin 2010

Stockage CHS

Décodage stockage CHS

Dans le billet précédent, nous avons avec la commande od affiché une table de partitions et nous en avons expliqué le contenu, mis à part certaines zones qui ont été ignorées. Il s'agit des zones où  sont enregistrées les données CHS (Cylindre,Tête, Secteur) relatives au début et à la fin des partitions.
Nous allons expliquer comment décoder les données CHS que l'on peut trouver dans une table de partitions.
Affichons avec od la table de partitions du disque utilisé comme exemple:
# od -Ad -tx1 -j 446 -N 66 /dev/sda
0000446 00 01 01 00 0b ef bf 5e 3f 00 00 00 b1 0a 8c 00 
0000462 80 01 81 5f 07 ef ff ff 2f 0b 8c 00 d1 47 1c 04 
0000478 00 ef ff ff 83 ef ff ff 00 53 a8 04 10 3b 00 00 
0000494 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
0000510 55 aa 
La colonne 1 de la table nous indique que la partition sda2 est marquée comme étant amorçable.
La colonne 5 nous apprend que:
sda 1 est une partition FAT 32
sda2 est une partition NTFS
sda3 est une partition linux
(Voir billet précédent).
Le secteur qui contient cette table de partition est le secteur 0 du disque: il se trouve sur le cylindre 0 et est lu par la tête 0. Cependant dans le système d'adressage CHS, les secteurs sont comptés à partir de 1.
Son adresse CHS est donc
CHS=(0,0,1)
Pour les autres adresses CHS, nous allons maintenant considérer les colonnes sur fond orange (données CHS du début de la partition) et sur fond gris (données CHS de fin de la partition).
Le premier octet se rapporte à la tête, les deux suivant à l'ensemble secteur cylindre.
Ainsi pour le début de la partition 1, il semble évident que:
CHS=(0,1,1)
Ce n'est pas faux, mais en fait, c'est un peu plus compliqué que cela.
En effet si le premier octet donne le numéro de la tête,  dans le deuxième octet, seuls les bits 0 à 5 correspondent au  numéro du secteur. Les bits 6 et 7  constituent les bits supérieurs (8 et 9) du numéro de cylindre. Le numéro de cylindre est donc un nombre à 10 bits dont le maximum est 1023.
Le tableau suivant montre ce qu'il en est pour le stockage des données relatives à la fin de la partition sda1:

Tête
Secteur Cylindre
E
F
B
F
5
E
1
1
1
0
1
1
1
1
1
0
1
1
1
1
1
1
0
1
0
1
1
1
1
0
7
6
5
4
3
2
1
0
7
6
5
4
3
2
1
0
7
6
5
4
3
2
1
0
La ligne 2 du tableau reprend les données en hexadécimal provenant de la table de partitions, la ligne 3 reprend les mêmes données en binaire. En ligne 4, on trouve la numérotation des bits.
Les bits sur fond jaune se rapport au numéro de cylindre, les bits sur fond vert au numéro de secteur.
Réorganisons le tableau de manière à mettre ensemble les bits qui constituent le numéro de cylindre:

Tête
Secteur
Cylindre
E
F
3
F
2
5
E
1
1
1
0
1
1
1
1
1
1
1
1
1
1
1
0
0
1
0
1
1
1

0
7
6
5
4
3
2
1
0
5
4
3
2
1
0
9
8
7
6
5
4
3
2
1
0
239
63
606
(On a ajouté au tableau une 5ième ligne qui donne l'équivalent en décimal des nombres hexadécimaux de même couleur).
L'adresse CHS de la fin de la partition est donc:
CHS=(606,239,63)
Dessinons des tableaux du même genre pour rechercher l'adresse CHS du début de sda2:

Tête
Secteur Cylindre
0
1
8
1
5
F
0
0
0
0
0
0
0
1
1
0
0
0
0
0
0
1
0
1
0
1
1
1
1
1
7
6
5
4
3
2
1
0
7
6
5
4
3
2
1
0
7
6
5
4
3
2
1
0

Tête
Secteur
Cylindre
0
1
0
1
2
5
F
0
0
0
0
0
0
0
1
0
0
0
0
0
1
1
0
0
1
0
1
1
1
1
1
7
6
5
4
3
2
1
0
5
4
3
2
1
0
9
8
7
6
5
4
3
2
1
0
1
1
607
On trouve:
CHS=(607,1,1)
Les autres données CHS qui figurent dans la table de partition étudiée sont toutes égales à EF FF FF FF ce qui donne des numéros de cylindre valant tous 3FF (1023). Ces données ne sont donc d'aucune utilité pour établir des adresses CHS.
Cependant, il existe des formules permettant de calculer l'adresse CHS à partir du système d'adressage LBA (Logical Block Adress) dans lequel les N blocs logiques d'un disque sont numérotés de 0 à N1. Les blocs logiques sont ici identiques aux secteurs et l'adresse LBA du début des partitions est celle qui figure dans la table de partitions occupant les colonnes 9 à 12. Pour l'adresse de fin, il suffit d'ajouter la taille (en secteurs) moins 1. Si A désigne l'adresse LBA, NS le nombre de secteurs par piste et NT le nombre de têtes, les formules sont les suivantes:
S = ( A % NS ) + 1
H = ( A - S + 1 ) / NS % NT
C = ( A - S + 1 ) / NS / NT
(% est l'opérateur modulo)
Pour notre disque exemple NS=63 et NT=240
Calculons l'adresse CHS de la fin de la partition sda1, pour vérifier si on retrouve bien les valeurs directement lues dans la table des partitions.
Rappelons que les adresses en secteurs (en blocs logiques) des partitions se présentent dans la table de partitions sous forme d'un nombre hexadécimal de 32 bits au format little-endian. Idem pour les tailles qui elles se trouvent aux colonnes 13 à 16. On pourrait convertir ces adresses et ces tailles en nombre décimal, ou même les afficher directement sous ce format à l'aide de od (voir billet précédent), mais la puissance extraordinaire de la ligne de commande linux fait qu'il n'est même pas nécessaire d'effectuer ces conversions:
$ A=$((0x3f+0x8c0ab1-1))
$ S=$(((A%NS)+1))
$ H=$(((A-S+1)/NS%NT))
$ C=$(((A-S+1)/NS/NT))
$ echo $C,$H,$S
606,239,63
Procédons de même pour la fin de la partition sda2:
A=$((0x8c0b2f+0x41c47d1-1))
$ S=$(((A%NS)+1))
$ H=$(((A-S+1)/NS%NT))
$ C=$(((A-S+1)/NS/NT))
$ echo $C,$H,$S
5167,239,63
Ces dernières valeurs ne peuvent pas être stockées dans la tables de partitions à l'emplacement prévu, puisque le numéro du cylindre est supérieur à 1023.