Comment accéder à l'appel système à partir de l'espace utilisateur?
J'ai lu quelques paragraphes dans LKD1
et j'ai juste ne peut pas comprendre le contenu ci-dessous:
Accéder au Système d'Appel à partir de l'Espace Utilisateur
Généralement, la bibliothèque C fournit un soutien pour les appels-système. Les applications de l'utilisateur peut tirer dans les prototypes de fonction de la norme en-têtes et le lien avec la bibliothèque C d'utilisation de votre système d'appel (ou à la bibliothèque de routine qui, à son tour, utilise votre syscall appel). Si vous venez de l'appel système, cependant, il est douteux que la glibc supporte déjà!
Heureusement, Linux fournit un ensemble de macros pour l'emballage d'accès pour les appels système. Il met en place le contenu d'un registre et enjeux le piège des instructions. Ces macros sont nommés
_syscalln()
oùn
est entre zéro et six ans. Le nombre correspond au nombre de paramètres passés dans le syscall, car la macro besoins de connaître le nombre de paramètres à attendre et, par conséquent, de pousser dans des registres. Par exemple, considérons le système d'appelopen()
définie commelong open(const char *filename, int flags, int mode)
Le syscall macro pour utiliser ce système d'appel sans autorisation explicite de la bibliothèque de support serait
#define __NR_open 5 _syscall3(long, open, const char *, filename, int, flags, int, mode)
Ensuite, l'application peut simplement appeler
open()
.Pour chaque macro, il y a 2+2×n paramètres. Le premier paramètre correspond au type de retour de la syscall. Le second est le nom de l'appel système. Suit ensuite le type et le nom de chaque paramètre dans l'ordre de l'appel système. Le
__NR_open
définir est en<asm/unistd.h>
; il est le système de numéro d'appel. Le_syscall3
macro se développe dans une fonction C avec inline assemblée; l'assemblée effectue les étapes décrites dans la section précédente pour pousser le système de numéro d'appel et les paramètres dans les registres et la question de l'interruption logicielle de piège dans le noyau. En plaçant cette macro dans une application est tout ce qui est requis pour l'utilisation de laopen()
appel système.Nous allons écrire la macro à utiliser notre magnifique nouveau
foo()
système d'appel et ensuite écrire un peu de code de test pour montrer nos efforts.#define __NR_foo 283 __syscall0(long, foo) int main () { long stack_size; stack_size = foo (); printf ("The kernel stack size is %ld\n", stack_size); return 0; }
Ce n' l'application peut simplement appeler open()
veux dire?
En outre, pour le dernier morceau de code, où est la déclaration de foo()
? Et comment puis-je faire de ce morceau de code compilable et exécutable? Quels sont les fichiers d'en-tête j'ai besoin d'inclure?
__________
1 Noyau Linux Développementpar Robert de l'Amour.
Le fichier PDF wordpress.com (aller page 81); Google Livres résultat.
source d'informationauteur injoy
Vous devez vous connecter pour publier un commentaire.
Vous devez d'abord comprendre quel est le rôle de la le noyau linuxet que les applications d'interagir avec le noyau seulement thru les appels système.
En effet, l'exécution d'une application sur la "machine virtuelle" fourni par le noyau: il est en cours d'exécution dans le de l'espace utilisateur et ne peut le faire (au plus bas niveau de la machine) le jeu d'instructions machine autorisé dans l'utilisateur du PROCESSEUR en mode augmentée par l'instruction (par exemple
SYSENTER
ouINT 0x80
...) utilisé pour effectuer des appels système. Donc, à partir du niveau de l'utilisateur de l'application point de vue, un syscall est atomique pseudo instruction machine.La Linux Assemblée Howto explique comment un syscall peut être fait à l'assemblée (c'est à dire d'instructions machine).
La GNU libc est de fournir des fonctions C correspondant à la syscalls. Ainsi, par exemple, la ouvert fonction est une petite colle (c'est à dire un wrapper) au-dessus de la syscall de nombre
NR__open
(il fait le syscall de mise à jour deerrno
). Application généralement appel à de telles fonctions C dans la libc au lieu de faire le syscall.Vous pouvez utiliser quelques autres
libc
. Par exemple, le MUSL libc est somhow "simple" et que son code est peut-être plus facile à lire. C'est également l'emballage de la crue appels en C correspondant fonctions.Si vous ajoutez vos propres syscall, vous feriez mieux de mettre en œuvre un semblable fonction C (dans votre propre bibliothèque). Vous devriez donc avoir également un fichier d'en-tête pour votre bibliothèque.
Voir aussi intro(2) et syscall(2) et syscalls(2) des pages de man, et le rôle de VDSO dans les syscalls.
Avis que syscalls ne sont pas C fonctions. Ils n'utilisent pas la pile d'appel (ils pourraient même être invoquée sans pile). Un syscall est fondamentalement un nombre comme
NR__open
de<asm/unistd.h>
unSYSENTER
instruction machine avec des conventions qui enregistre tenir avant les arguments pour le syscall et ceux qui détiennent après le résultat[s] de la syscall (y compris l'absence de résultats, de définirerrno
dans la bibliothèque C enveloppant le syscall). Les conventions pour les appels ne sont pas les conventions d'appel pour les fonctions C dans l'ABI spec (par exemple x86-64 psABI). Si vous avez besoin d'un C wrapper.Au premier abord, je tiens à donner quelques définition de l'appel système. Appel système est un processus synchrone explicite demandant du noyau particulier de service à partir de l'espace utilisateur de l'application. Synchrone signifie que l'acte d'appel système est prédéterminée par l'exécution des instructions de la séquence. Les interruptions est un exemple de système asynchrone de demande de service, car ils arrivent au noyau absolument indépendamment de l'exécution de code sur le processeur. Exceptions dans le contraste pour les appels système sont synchrones mais implicite de la demande pour les services du noyau.
Appel système composé de quatre étapes:
En général, toutes ces actions peuvent être mises en œuvre en tant que partie d'une grande bibliothèque de fonction qui effectue un certain nombre d'auxiliaires actions avant et/ou après la date réelle de l'appel système. Dans ce cas, nous pouvons dire que l'appel système est intégré dans cette fonction, mais la fonction en général n'est pas un appel système. Dans un autre cas, on peut avoir une petite fonction qui ne fait que cela quatre étapes et rien de plus. Dans ce cas, nous pouvons dire que cette fonction est un appel système. En fait, vous pouvez mettre en œuvre le système d'appel lui-même par le manuel de mise en œuvre de tous les quatre étapes mentionnées ci-dessus. Notez que dans ce cas, vous serez obligé d'utiliser de l'Assembleur, car toutes ces étapes sont entièrement dépendants de l'architecture.
Par exemple, Linux/i386 environnement a côté du système de convention d'appel:
include\uapi\asm-generic\unistd.h
.Dans les versions modernes de Linux il n'y a aucune _syscall macro (que je sache). Au lieu de cela, la bibliothèque glibc, qui est une interface principale de la bibliothèque du noyau Linux, un macro -
INTERNAL_SYSCALL
qui s'étend dans un petit morceau de code peuplée par les instructions de l'assembleur inline. Ce morceau de code est destiné à une plate-forme matérielle et met en œuvre toutes les étapes de l'appel système, et pour cette raison, cette macro représente un appel système lui-même. Il y a aussi une autre macro -INLINE_SYSCALL
. La dernière macro permet de la glibc, comme la gestion d'erreur, conformément à ce qui d'échec de l'appel système -1 est retourné et le numéro de l'erreur sera stocké danserrno
variable. Les deux macros sont définies danssysdep.h
de paquet glibc.Vous pouvez invoquer un système d'appel par le moyen suivant:
où
<name>
doit être remplacé par le syscall nom de la chaîne,<id>
par le voulait système de service de numéro,<argc>
par le nombre réel de paramètres (de 0 à 6) et<argv>
- par les paramètres séparés par des virgules (et a commencé par des virgules si des paramètres sont présents).Par exemple:
ou un autre exemple:
Minimum praticable assemblée exemple
hello_world.asm:
Compiler et exécuter:
À partir du code, il est facile de déduire:
eax
contient le syscall nombre, par exemple4
pour écrire. 32 liste des bits sur les sources du noyau: https://github.com/torvalds/linux/blob/v4.9/arch/x86/entry/syscalls/syscall_32.tbl#L13ebx
ecx
etedx
contiennent les arguments d'entrée. Ceux-ci devraient être ressort de la signature de chaque syscall dans le source du noyau. Voir aussi: Quelles sont les conventions d'appel pour UNIX & appels système Linux sur x86-64 et Appel système Linux table ou cheetsheet en langage d'assemblageint 0x80
fait l'appel, bien qu'il existe maintenant de meilleures méthodes: Quoi de mieux "int 0x80" ou "syscall"?Bien sûr, assemblée fastidieux rapidement, et vous allez bientôt vous souhaitez utiliser le C wrappers fournis par la glibc /POSIX chaque fois que vous pouvez, ou le
SYSCALL
macro lorsque vous ne pouvez pas.