Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
course
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
gc_courses
sys-exploit
course
Commits
fc4dd1bf
Commit
fc4dd1bf
authored
8 months ago
by
Guillaume Chanel
Browse files
Options
Downloads
Patches
Plain Diff
Finalize part 4 on file systems: minix
parent
f93b3b12
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
9.filesystems/04_Systemes_fichiers_minix.md
+74
-97
74 additions, 97 deletions
9.filesystems/04_Systemes_fichiers_minix.md
with
74 additions
and
97 deletions
9.filesystems/04_Systemes_fichiers_minix.md
+
74
−
97
View file @
fc4dd1bf
...
...
@@ -101,14 +101,11 @@ struct minix_inode {
Format du champs
`i_mode`
(16 bits) de l'inode :
Bits | Description | t
<div
style=
"font-size:0.8em"
>
Bits | Description ||
----------------| -------------------------- |---------------------------
`12-15`
| Type de fichier : |
`0x1`
: named pipe (FIFO)
`` | a |`0x2` : char device
b | b |`0x4` : directory
c | c |`0x6` : block device
d | d |`0x8` : regular file
we | e |`0xA` : symbolic link
`12-15`
| Type de fichier |
`0x1`
: named pipe (FIFO)
<br>
`0x2`
: char device
<br>
`0x4`
: directory
<br>
`0x6`
: block device
<br>
`0x8`
: regular file
<br>
`0xA`
: symbolic link
`11`
| SUID bit |
`10`
| SGID bit |
`9`
| Sticky bit |
...
...
@@ -116,15 +113,16 @@ Bits | Description | t
`3-5`
| group permissions (rwx) |
`0-2`
| others permissions (rwx) |
</div>
--
## Structure des entrées de répertoires
Structure d'une entrée de répertoire dans MINIX-fs v1.0 :
\vspace{.2cm}
```{.c .verysmall}
```
c
// Variante : superblock magic 0x137F
#define MINIX_NAME_LEN 14
...
...
@@ -134,7 +132,8 @@ struct minix_dir_entry {
};
```
- Taille d'un `dir_entry` en bytes ?
-
Taille d'un
`dir_entry`
en bytes ?
\
`$14*sizeof(char) + 2$ bytes ($16$ bits) $= 16$ bytes si $sizeof(char)=1$ byte`
<!-- .element class="fragment" -->
--
...
...
@@ -142,9 +141,7 @@ struct minix_dir_entry {
Structure du superbloc dans MINIX-fs v1.0 :
\vspace{.2cm}
```{.c .tiny}
```
c
struct
minix_super_block
{
u16
s_ninodes
;
// total number of inodes
u16
s_nzones
;
// total number of blocks (including superblock)
...
...
@@ -159,19 +156,19 @@ struct minix_super_block {
};
```
-
Taille du superbloc en bytes ?
-
Taille du superbloc en bytes ?
\
`$20$ bytes`
<!-- .element class="fragment" -->
--
## Exemple de superbloc
-
Soit un disque de 20 MB et une taille de bloc de 1 KB
\
$
\r
ightarrow$
`
fs_blocks`
= nombre de blocs au total
-
Nombre inodes =
`(fs_blocks/3 + 32) & 0xFFFFFFE0`
[^1]
`
$\rightarrow$ fs_blocks`
= nombre de blocs au total
-
Nombre inodes =
`(fs_blocks/3 + 32) & 0xFFFFFFE0`
<sup>
1
</sup>
\v
space{.2cm}
```
{.c .tiny}
```
c
struct
minix_super_block
{
u16
s_ninodes
=
6848
;
// total number of inodes
u16
s_nzones
=
20480
;
// total number of blocks
...
...
@@ -190,14 +187,15 @@ struct minix_super_block {
u16
s_state
=
1
;
// was the FS properly unmounted?
};
```
<!-- .element style="font-size:0.5em" -->
[
^1
]:
\scriptsize
permet d'arrondir au prochain multiple de la taille d'un inode
<small>
1:
permet d'arrondir au prochain multiple de la taille d'un inode
</small>
--
## Exemple de superbloc
```
{.c .tiny}
```
c
struct
minix_super_block
{
u16
s_ninodes
=
6848
;
// total number of inodes
u16
s_nzones
=
20480
;
// total number of blocks
...
...
@@ -216,9 +214,10 @@ struct minix_super_block {
u16
s_state
=
1
;
// was the FS properly unmounted?
};
```
<!-- .element style="font-size:0.5em" -->
\c
entering

{ width=100% }

--
...
...
@@ -226,9 +225,7 @@ struct minix_super_block {
Contenu de l'inode 1, la racine du FS
\v
space{.2cm}
```
{.c .verysmall}
```
c
struct
minix_inode
{
u16
i_mode
=
0x41ED
;
// 0x4 = directory
// 0x1ED = 755 in octal
...
...
@@ -249,12 +246,11 @@ struct minix_inode {
## Exemple de bloc de données - contenu répertoire
\f
ootnotesize
1er bloc de données référencé par l'inode 1
\
1er bloc de données référencé par l'inode 1
-
bloc 220 (offset = 220
*
1024 = 0x37000)
```
{.tiny}
```
00037000 01 00 2E 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00037010 00 00 79 6F 00 00 00 00 00 00 00 00 00 00 00 00 ..yo............
00037020 01 00 2E 2E 00 00 00 00 00 00 00 00 00 00 00 00 ................
...
...
@@ -272,21 +268,23 @@ struct minix_inode {
000370E0 32 00 64 65 76 00 00 00 00 00 00 00 00 00 00 00 2.dev...........
000370F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
```
<!-- .element style="font-size:0.4em" -->
<div
style=
"font-size: 0.8em"
>
\s
criptsize
-
Les noms
`.`
(0x2E) et
`..`
(0x2E2E) pointent sur l'inode 1 (la racine)
-
7 répertoires :
`root`
,
`bin`
,
`usr`
,
`etc`
,
`tmp`
,
`dev`
(inodes 1, 2, 3, 4, 0xA, 0xF, 0x32)
-
8
`dir_entry`
inutilisées (inodes à 0) ; rappel : une entrée fait 16 bytes
</div>
--
## Exemple d'inode - fichier répertoire
Contenu de l'inode 2, répertoire
`/root`
\v
space{.2cm}
```
{.c .verysmall}
```
c
struct
minix_inode
{
u16
i_mode
=
0x41ED
;
// 0x4 = directory
// 0x1ED = 755 in octal
...
...
@@ -307,14 +305,11 @@ struct minix_inode {
## Exemple de bloc de données - contenu répertoire
\s
mall
1er bloc de données référencé par l'inode 2
\
1er bloc de données référencé par l'inode 2
-
bloc 221 (offset = 221
*
1024 = 0x37400)
\v
space{.2cm}
```
{.tiny}
```
00037400 02 00 2E 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00037410 6C 03 6C 69 6E 75 78 00 00 00 00 00 00 00 00 00 l.linux.........
00037420 01 00 2E 2E 00 00 00 00 00 00 00 00 00 00 00 00 ................
...
...
@@ -326,23 +321,25 @@ struct minix_inode {
00037480 0E 00 2E 62 61 73 68 5F 6C 6F 67 69 6E 00 00 00 ...bash_login...
00037490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
```
<!-- .element style="font-size:0.5em" -->
<div
style=
"font-size: 0.8em"
>
\f
ootnotesize
-
Le nom
`.`
(0x2E) pointe sur l'inode 2 (lui même)
-
Le nom
`.`
(0x2E2E) pointe sur le répertoire parent, l'inode 1 (la racine)
-
Il y a 2 répertoires :
`linux`
(inode 0x36C) et
`system`
(inode 0x9)
-
Il y a 2 fichiers :
`hello.c`
(inode 0xB) et
`.bash_login`
(inode 0xE)
-
Il y a 4
`dir_entry`
inutilisées (inodes à 0)
</div>
--
## Exemple d'inode - fichier régulier
Contenu de l'inode 11 (0xB)
\v
space{.2cm}
```
{.c .verysmall}
```
c
struct
minix_inode
{
u16
i_mode
=
0x81A4
;
// 0x8 = regular file
// 0x1A4 = 644 in octal
...
...
@@ -362,14 +359,11 @@ struct minix_inode {
## Exemple de bloc de données - contenu fichier régulier
\s
mall
Contenu du 1er bloc de données référencé par l'inode 11
\
-
bloc 583 (offset = 583
*
1024 = 0x91C00)
\v
space{.2cm}
```
{.tiny}
```
00091C00 23 69 6E 63 6C 75 64 65 20 3C 73 74 64 69 6F 2E #include <stdio.
00091C10 68 3E 0A 0A 76 6F 69 64 20 6D 61 69 6E 28 29 0A h>..void main().
00091C20 7B 0A 09 09 70 72 69 6E 74 66 28 22 48 65 6C 6C {...printf("Hell
...
...
@@ -392,9 +386,7 @@ Contenu du 1er bloc de données référencé par l'inode 11\
Contenu de l'inode 16
\v
space{.2cm}
```
{.c .verysmall}
```
c
struct
minix_inode
{
u16
i_mode
=
0x81C9
;
// 0x8 = regular file
// 0x1C9 = 711 in octal
...
...
@@ -415,14 +407,11 @@ struct minix_inode {
## Exemple de bloc de données - contenu fichier régulier
\s
mall
Contenu du bloc indirect référencé par l'inode 11
\
-
bloc 595 (offset = 595
*
1024 = 0x94C00)
\v
space{.2cm}
```
{.tiny}
```
00094C00 54 02 55 02 56 02 57 02 58 02 59 02 5A 02 5B 02 T.U.V.W.X.Y.Z.[.
00094C10 5C 02 5D 02 5E 02 5F 02 60 02 61 02 62 02 63 02 \.].^._.`.a.b.c.
00094C20 64 02 65 02 66 02 67 02 68 02 69 02 6A 02 6B 02 d.e.f.g.h.i.j.k.
...
...
@@ -443,44 +432,51 @@ Contenu du bloc indirect référencé par l'inode 11\
## Important : inodes
\s
mall
<div
style=
"font-size: 0.8em"
>
-
Le nombre total d'inodes pouvant être créés dans le FS est indiqué par le champs
`ninodes`
du superbloc
-
La table des inodes possède
`ninodes`
entrées
-
Le premier inode de la table (à l'indice 0) est l'inode 1
-
\f
ootnotesize il n'y a donc pas d'inode 0 !
-
**Attention**
: le bit 0 du bitmap indique l'état de l'inode 0
\
!
-
\f
ootnotesize le bit 0 est toujours à 1 (utilisé), bien que l'inode 0 n'existe pas
-
Le premier inode de la table (à l'indice 0) est l'inode 1, il n'y a donc pas d'inode 0 !
-
**Attention**
: le bit 0 du bitmap indique l'état de l'inode 0 !
-
le bit 0 est toujours à 1 (utilisé), bien que l'inode 0 n'existe pas
-
un FS vide aura donc 2 bits à 1 dans le bitmap
\
: le bit 0 (inode 0) et le bit 1 (inode 1 = répertoire racine)
En conséquence :
\v
space{-.3cm}
</div>
<br>
<fieldset>
<legend>
En conséquence :
</legend>
-
Pour lire le contenu de l'inode
`n`
, il faut lire l'entrée à l'indice
`(n-1)`
dans la table des inodes
-
Pour savoir si l'inode
`n`
est utilisé, il faut lire le bit à l'indice
`n`
dans le bitmap des inodes
</fieldset>
</div>
--
## Important : blocs de données
\s
mall
<div
style=
"font-size: 0.8em"
>
-
Les n° de blocs dans l'inode sont relatifs au début du FS
-
Le bitmap des blocs de données indique uniquement l'état des
**blocs de données**
utilisés (donc pas superbloc, bitmaps, etc.)
-
**Attention**
: le bit 0 du bitmap des blocs de données est à
**ignorer**
\
!
-
**Attention**
: le bit 0 du bitmap des blocs de données est à
**ignorer**
!
-
\f
ootnotesize il est toujours à 1 et ne représente aucun bloc de données
-
le bit 1 du bitmap correspond au bloc
`firstdatazone`
indiqué dans le superbloc
-
il correspond donc au premier bloc de données
En conséquence[^2] :
\v
space{-.3cm}
</div>
<br>
<fieldset>
<legend>
En conséquence :
</legend>
-
Tout bloc n indiqué dans l'inode correspond à l'indice
`(n-firstdatazone+1)`
dans le bitmap des blocs de données
-
Nombre total de blocs de données :
`(nzones-firstdatazone)`
[
^2
]:
\scriptsize
\t
exttt{firstdatazone} et
\t
exttt{nzones} sont les champs du même nom dans le superbloc
<small>
*firstdatazone*
et
*nzones*
sont les champs du même nom dans le superbloc
</small>
</fieldset>
<!--
-
où
`firstdatazone`
est le champs du même nom dans le superbloc (= nombre de blocs utilisés par
\
: superbloc + bitmaps + table d'inodes)
...
...
@@ -496,12 +492,10 @@ En conséquence[^2] :
-
L'
*endianness*
défini la manière dont les entiers sont stockés en mémoire
\v
space{.2cm}
-
***Big-endian***
-
le byte le plus significatif (d'un mot) est stocké à l'adresse la plus basse
-
le byte le moins significatif est stocké à l'adresse la plus haute
\v
space{.2cm}
-
***Little-endian***
-
le byte le plus significatif (d'un mot) est stocké à l'adresse la plus haute
-
le byte le moins significatif est stocké à l'adresse la plus basse
...
...
@@ -512,14 +506,12 @@ En conséquence[^2] :
Exemple de valeurs 8 bits, 16 bits et 32 bits, en représentation hexadécimale, où les adresses "grandissent" de gauche à droite :
\v
space{.3cm}
\s
mall
**Taille de mot**
**Valeur**
**Big-endian**
**Little-endian**
----------------- ----------- -------------- -----------------
8 bits (1 byte)
`4c`
`4c`
`4c`
16 bits (2 bytes)
`4c3f`
`4c 3f`
`3f 4c`
32 bits (4 bytes)
`4c3f85ed`
`4c 3f 85 ed`
`ed 85 3f 4c`
**Taille de mot**
|
**Valeur**
|
**Big-endian**
|
**Little-endian**
-----------------
|
-----------
|
--------------
|
-----------------
8 bits (1 byte)
|
`4c`
|
`4c`
|
`4c`
16 bits (2 bytes)
|
`4c3f`
|
`4c 3f`
|
`3f 4c`
32 bits (4 bytes)
|
`4c3f85ed`
|
`4c 3f 85 ed`
|
`ed 85 3f 4c`
--
...
...
@@ -528,7 +520,8 @@ Exemple de valeurs 8 bits, 16 bits et 32 bits, en représentation hexadécimale,
-
**Sérialisation**
de structure = écriture, en une opération, d'une structure sur un fichier, un socket, un pipe, etc.
-
typiquement via un appel à
`write`
ou
`fwrite`
\v
space{.3cm}
<br></br>
-
**Déserialisation**
de structure = lecture, en une opération, depuis un fichier, un socket, un pipe, etc. dans une structure
-
typiquement via un appel à
`read`
ou
`fread`
...
...
@@ -537,7 +530,7 @@ Exemple de valeurs 8 bits, 16 bits et 32 bits, en représentation hexadécimale,
## Danger avec la sérialisation/déserialisation
```
{.c .tiny}
```
c
struct
st1
{
struct
__attribute__
((
__packed__
))
st2
{
uint8_t
tab
[
7
];
uint8_t
tab
[
7
];
uint16_t
n
;
uint16_t
n
;
...
...
@@ -552,22 +545,6 @@ int main() {
}
```
::: incremental
-
Affichage ?
-
**`20 15`**
-
Pourquoi ?
-
Conséquence :
**\textcolor{myred}{toujours}**
utiliser l'attribut
`__packed__`
sur les structures sérialisées
\
!
:::
--
## Ressources
\s
mall
-
`mkfs.minix`
source code
\
\f
ootnotesize
[
\textcolor{myblue}{https://github.com/util-linux/util-linux/blob/master/disk-utils/mkfs.minix.c}
](
https://github.com/util-linux/util-linux/blob/master/disk-utils/mkfs.minix.c
)
\s
mall
-
Affichage ?
`20 15`
<!-- .element class="fragment" -->
-
Pourquoi ?
<text>
Le compilateur ajoute des bytes de padding pour optimiser l'alignement des structures.
</text>
<!-- .element class="fragment" -->
-
Conséquence :
<text>
**toujours**
utiliser l'attribut
`__packed__`
sur les structures sérialisées !
</text>
<!-- .element class="fragment" -->
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment