Donc, il y a essentiellement deux types de choses différentes ici :
- Les systèmes de fichiers normaux, qui conservent les fichiers dans des répertoires contenant des données et des métadonnées, de la manière familière (y compris les liens symboliques, les liens physiques, etc.). Ceux-ci sont souvent, mais pas toujours, soutenus par un périphérique bloc pour le stockage persistant (un tmpfs vit uniquement dans la RAM, mais est par ailleurs identique à un système de fichiers normal). La sémantique de ceux-ci est familière; lire, écrire, renommer, etc., tout fonctionne comme vous l'attendez.
- Systèmes de fichiers virtuels, de différents types.
/proc
et/sys
sont des exemples ici, tout comme les systèmes de fichiers personnalisés FUSE commesshfs
ouifuse
. Il y a beaucoup plus de diversité dans ceux-ci, car en réalité, ils se réfèrent simplement à un système de fichiers avec une sémantique qui est en quelque sorte « personnalisée ». Ainsi, lorsque vous lisez un fichier sous/proc
, vous n'accédez pas réellement à une donnée spécifique qui a été stockée par quelque chose d'autre qui l'a écrite plus tôt, comme dans un système de fichiers normal. Vous faites essentiellement un appel au noyau, demandant des informations générées à la volée. Et ce code peut faire tout ce qu'il veut, puisqu'il ne s'agit que d'une fonction quelque part implémentantread
sémantique. Ainsi, vous avez le comportement étrange des fichiers sous/proc
, comme par exemple faire semblant d'être des liens symboliques alors qu'ils ne le sont pas vraiment.
La clé est que /dev
est en fait, généralement, l'un des premiers types. Il est normal dans les distributions modernes d'avoir /dev
être quelque chose comme un tmpfs, mais dans les systèmes plus anciens, il était normal que ce soit un répertoire simple sur le disque, sans aucun attribut spécial. La clé est que les fichiers sous /dev
sont des nœuds de périphérique, un type de fichier spécial similaire aux FIFO ou aux sockets Unix ; un nœud de périphérique a un numéro majeur et mineur, et les lire ou les écrire revient à appeler un pilote du noyau, tout comme lire ou écrire un FIFO appelle le noyau pour mettre en mémoire tampon votre sortie dans un tube. Ce pilote peut faire ce qu'il veut, mais il touche généralement le matériel d'une manière ou d'une autre, par ex. pour accéder à un disque dur ou lire du son dans les haut-parleurs.
Pour répondre aux questions initiales :
-
Il y a deux questions pertinentes pour savoir si le « dossier existe » ou non ; il s'agit de savoir si le fichier de nœud de périphérique existe littéralement et si le code du noyau qui le soutient est significatif. Le premier est résolu comme n'importe quoi sur un système de fichiers normal. Les systèmes modernes utilisent
udev
ou quelque chose comme ça pour surveiller les événements matériels et créer et détruire automatiquement les nœuds de périphérique sous/dev
en conséquence. Mais les systèmes plus anciens, ou les versions personnalisées légères, peuvent simplement avoir tous leurs nœuds de périphérique littéralement sur le disque, créés à l'avance. Pendant ce temps, lorsque vous lisez ces fichiers, vous effectuez un appel au code du noyau qui est déterminé par les numéros de périphérique majeur et mineur ; si ceux-ci ne sont pas raisonnables (par exemple, vous essayez de lire un périphérique bloc qui n'existe pas), vous obtiendrez simplement une sorte d'erreur d'E/S. -
La façon dont il détermine le code du noyau à appeler pour quel fichier de périphérique varie. Pour les systèmes de fichiers virtuels comme
/proc
, ils implémentent leur propreread
etwrite
les fonctions; le noyau appelle simplement ce code en fonction du point de montage dans lequel il se trouve, et l'implémentation du système de fichiers s'occupe du reste. Pour les fichiers de périphérique, il est distribué en fonction des numéros de périphérique majeur et mineur.
Voici une liste de fichiers de /dev/sda1
sur mon serveur Arch Linux presque à jour :
% ls -li /dev/sda1
1294 brw-rw---- 1 root disk 8, 1 Nov 9 13:26 /dev/sda1
Ainsi, l'entrée de répertoire dans /dev/
pour sda
a un numéro d'inode, 1294. C'est un vrai fichier sur le disque.
Regardez où la taille du fichier apparaît généralement. "8, 1" apparaît à la place. Il s'agit d'un numéro d'appareil majeur et mineur. Notez également le 'b' dans les autorisations de fichier.
Le fichier /usr/include/ext2fs/ext2_fs.h
contient ce (fragment) struct C :
/*
* Structure of an inode on the disk
*/
struct ext2_inode {
__u16 i_mode; /* File mode */
Cette structure nous montre la structure sur disque de l'inode d'un fichier. Beaucoup de choses intéressantes se trouvent dans cette structure; regardez-le longuement.
Le i_mode
élément de struct ext2_inode
a 16 bits, et il n'en utilise que 9 pour l'utilisateur/groupe/autre, les autorisations de lecture/écriture/exécution, et 3 autres pour setuid, setgid et sticky. Il a 4 bits pour différencier les types tels que "fichier brut", "lien", "répertoire", "canal nommé", "socket de la famille Unix" et "périphérique de bloc".
Le noyau Linux peut suivre l'algorithme de recherche de répertoire habituel, puis prendre une décision en fonction des autorisations et des drapeaux dans le i_mode
élément. Pour 'b', bloquer les fichiers de périphérique, il peut trouver les numéros de périphérique majeur et mineur, et traditionnellement, utiliser le numéro de périphérique majeur pour rechercher un pointeur vers une fonction du noyau (un pilote de périphérique) qui traite des disques. Le numéro de périphérique mineur est généralement utilisé, par exemple, le numéro de périphérique de bus SCSI, ou le numéro de périphérique EIDE ou quelque chose comme ça.
Quelques autres décisions sur la façon de traiter un fichier comme /proc/cpuinfo
sont créés en fonction du type de système de fichiers. Si vous faites un :
% mount | grep proc
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
vous pouvez voir que /proc
a le type de système de fichiers "proc". Lecture d'un fichier en /proc
oblige le noyau à faire quelque chose de différent en fonction du type de système de fichiers, tout comme l'ouverture d'un fichier sur un système de fichiers ReiserFS ou DOS obligerait le noyau à utiliser différentes fonctions pour localiser les fichiers et localiser les données des fichiers.
En fin de compte, ce sont tous des fichiers pour Unix, c'est la beauté de l'abstraction.
La façon dont les fichiers sont gérés par le noyau, maintenant c'est une autre histoire.
/proc et de nos jours /dev et /run (alias /var/run) sont des systèmes de fichiers virtuels en RAM. /proc est une interface/windows pour les variables et les structures du noyau.
Je recommande de lire The Linux Kernel http://tldp.org/LDP/tlk/tlk.html et Linux Device Drivers, Third Edition https://lwn.net/Kernel/LDD3/.
J'ai également apprécié la conception et la mise en œuvre du système d'exploitation FreeBSD http://www.amazon.com/Design-Implementation-FreeBSD-Operating-System/dp/0321968972/ref=sr_1_1
Consultez la page pertinente qui se rapporte à votre question.
http://www.tldp.org/LDP/tlk/dd/drivers.html