Τι είναι μια κλήση συστήματος Linux;

What Is Linux System Call



Πριν εμβαθύνουμε στον ορισμό της κλήσης συστήματος Linux και εξετάσουμε τις λεπτομέρειες της εκτέλεσης της, είναι καλύτερο να ξεκινήσουμε με τον καθορισμό των διαφόρων επιπέδων λογισμικού ενός τυπικού συστήματος Linux.

Ο πυρήνας Linux είναι ένα εξειδικευμένο πρόγραμμα που εκκινεί και τρέχει στο χαμηλότερο διαθέσιμο επίπεδο στο υλικό σας. Έχει το καθήκον να ενορχηστρώσει ό, τι τρέχει στον υπολογιστή, συμπεριλαμβανομένου του χειρισμού πληκτρολογίου, δίσκου και συμβάντων δικτύου, ώστε να παρέχει χρονικά τμήματα για την παράλληλη εκτέλεση πολλών προγραμμάτων.







Όταν ο πυρήνας εκτελεί ένα πρόγραμμα σε επίπεδο χρήστη, εικονικοποιεί το χώρο της μνήμης, έτσι ώστε τα προγράμματα να πιστεύουν ότι είναι η μόνη διαδικασία που εκτελείται στη μνήμη. Αυτή η προστατευτική φούσκα απομόνωσης υλικού και λογισμικού αυξάνει την ασφάλεια και την αξιοπιστία. Μια μη προνομιακή εφαρμογή δεν μπορεί να αποκτήσει πρόσβαση στη μνήμη που ανήκει σε άλλα προγράμματα και εάν αυτό το πρόγραμμα διακοπεί, ο πυρήνας τερματίζεται έτσι ώστε να μην μπορεί να βλάψει το υπόλοιπο σύστημα.



Παραβίαση του φραγμού με κλήσεις συστήματος Linux

Αυτό το επίπεδο απομόνωσης μεταξύ μη προνομιακών εφαρμογών παρέχει ένα εξαιρετικό όριο για την προστασία άλλων εφαρμογών και χρηστών στο σύστημα. Ωστόσο, χωρίς κάποιον τρόπο διασύνδεσης με τα άλλα στοιχεία του υπολογιστή και του εξωτερικού κόσμου, τα προγράμματα δεν θα μπορούσαν να επιτύχουν πολλά.



Για να διευκολύνει την αλληλεπίδραση, ο πυρήνας ορίζει μια πύλη λογισμικού που επιτρέπει στο τρέχον πρόγραμμα να ζητήσει από τον πυρήνα να ενεργήσει για λογαριασμό του. Αυτή η διεπαφή είναι γνωστή ως κλήση συστήματος.





Δεδομένου ότι το Linux ακολουθεί τη φιλοσοφία UNIX ότι όλα είναι ένα αρχείο, πολλές λειτουργίες μπορούν να εκτελεστούν ανοίγοντας και διαβάζοντας ή γράφοντας ένα αρχείο, το οποίο θα μπορούσε να είναι μια συσκευή. Στα Windows, για παράδειγμα, μπορεί να χρησιμοποιήσετε μια συνάρτηση που ονομάζεται CryptGenRandom για πρόσβαση σε τυχαία byte. Αλλά στο Linux, αυτό μπορεί να γίνει απλά ανοίγοντας το αρχείο/dev/urandom και διαβάζοντας byte από αυτό χρησιμοποιώντας τυπικές κλήσεις συστήματος εισόδου/εξόδου αρχείων. Αυτή η κρίσιμη διαφορά επιτρέπει μια απλούστερη διεπαφή κλήσης συστήματος.

Wafer-Thin Wrapper

Στις περισσότερες εφαρμογές, οι κλήσεις συστήματος δεν πραγματοποιούνται απευθείας στον πυρήνα. Σχεδόν όλα τα προγράμματα συνδέονται στην τυπική βιβλιοθήκη C, η οποία παρέχει ένα λεπτό αλλά σημαντικό περιτύλιγμα γύρω από κλήσεις συστήματος Linux. Η βιβλιοθήκη βεβαιώνεται ότι τα ορίσματα συνάρτησης αντιγράφονται στα σωστά μητρώα επεξεργαστή και στη συνέχεια εκδίδει την αντίστοιχη κλήση συστήματος Linux. Όταν λαμβάνονται δεδομένα από την κλήση, το περιτύλιγμα ερμηνεύει τα αποτελέσματα και τα επιστρέφει πίσω στο πρόγραμμα με συνεπή τρόπο.



Στα παρασκήνια

Κάθε συνάρτηση σε ένα πρόγραμμα που αλληλεπιδρά με το σύστημα μεταφράζεται τελικά σε κλήση συστήματος. Για να το δείτε στην πράξη, ας ξεκινήσουμε με ένα βασικό παράδειγμα.

κενόςκύριος() {
}

Αυτό είναι ίσως το πιο ασήμαντο πρόγραμμα C που έχετε δει ποτέ. Απλώς αποκτά τον έλεγχο μέσω του κύριου σημείου εισόδου και στη συνέχεια εξέρχεται. Δεν επιστρέφει καν μια τιμή αφού το main ορίζεται ως άκυρο. Αποθηκεύστε το αρχείο ως ctest.c και ας το μεταγλωττίσουμε:

gcc ctest.ντο -το ctest

Μόλις μεταγλωττιστεί, μπορούμε να δούμε το μέγεθος του αρχείου ως 8664 byte. Μπορεί να διαφέρει ελαφρώς στο σύστημά σας, αλλά θα πρέπει να είναι περίπου 8k. Αυτός είναι πολύς κώδικας μόνο για είσοδο και έξοδο! Ο λόγος για τον οποίο είναι 8k είναι ότι περιλαμβάνεται ο χρόνος εκτέλεσης του libc. Ακόμα κι αν αφαιρέσουμε τα σύμβολα, είναι ακόμα λίγο πάνω από 6k.

Σε ένα ακόμη απλούστερο παράδειγμα, μπορούμε να κάνουμε το σύστημα Linux να καλέσει να βγεί αντί να εξαρτηθεί από το χρόνο εκτέλεσης C για να το κάνει αυτό για εμάς.

κενός_αρχή() {
asm('movl $ 1,%eax;'
'xorl %ebx, %ebx;'
'int $ 0x80')?
}

Εδώ μετακινούμαστε 1 στον καταχωρητή EAX, ξεκαθαρίζουμε τον καταχωρητή EBX (ο οποίος διαφορετικά θα περιείχε την τιμή επιστροφής) και καλούμε τη διακοπή κλήσης συστήματος Linux 0x80 (ή 128 σε δεκαδικό). Αυτή η διακοπή ενεργοποιεί τον πυρήνα να επεξεργαστεί την κλήση μας.

Αν καταρτίσουμε το νέο μας παράδειγμα, που ονομάζεται asmtest.c, και βγάλουμε τα σύμβολα και εξαιρέσουμε την τυπική βιβλιοθήκη:

gcc-μικρό-nostdlib asmtest.ντο -o asmtest

θα παράγουμε ένα δυαδικό λιγότερο από 1k (στο σύστημά μου, αποδίδει 984 byte). Το μεγαλύτερο μέρος αυτού του κώδικα είναι εκτελέσιμες κεφαλίδες. Τώρα καλούμε την άμεση κλήση συστήματος Linux.

Για όλους τους πρακτικούς σκοπούς

Σε όλες σχεδόν τις περιπτώσεις, δεν θα χρειαστεί ποτέ να πραγματοποιείτε απευθείας κλήσεις συστήματος στα προγράμματα C σας. Εάν χρησιμοποιείτε γλώσσα συναρμολόγησης, ωστόσο, μπορεί να προκύψει ανάγκη. Ωστόσο, στη βελτιστοποίηση, θα ήταν καλύτερο να αφήσετε τις λειτουργίες της βιβλιοθήκης C να πραγματοποιούν κλήσεις του συστήματος και να έχουν ενσωματωμένο μόνο τις οδηγίες κρίσιμης απόδοσης στις οδηγίες συναρμολόγησης.

Πώς να προγραμματίσετε τα σεμινάρια κλήσεων συστήματος

Λίστα όλων των κλήσεων συστήματος

Εάν θέλετε να δείτε μια λίστα με όλες τις διαθέσιμες κλήσεις συστήματος για Linux, μπορείτε να ελέγξετε αυτές τις σελίδες αναφοράς: Πλήρης λίστα κλήσεων συστήματος στο LinuxHint.com, filippo.io/linux-syscall-table/ και ή syscalls.kernelgrok.com