Linux Inside
44
Linux Boot Process
Παρόμοιο πρόβλημα προκύπτει και με την εγκατάσταση
μίας διανομής. Οι διανομές που προσαρτούν τις κατατμήσεις
με βάση την ετικέτα τόμου, μπορεί να προκαλέσουν πρόβλη-
μα εάν προσαρτήσουμε έναν δεύτερο δίσκο με κατατμήσεις
από την ίδια διανομή. Σε αυτή την περίπτωση θα βρεθούν δύο
διαφορετικές κατατμήσεις με το ίδιο όνομα!
Επειδή αυτό το πρόβλημα αγγίζει όλες τις εταιρείες και
τους υπολογιστές, δημιουργήθηκε ο Universally Unique
IDentifier. Ο UUID παράγεται από έναν αλγόριθμο, του οποίου
το αποτέλεσμα είναι μοναδικό.
Με αυτόν το μοναδικό αριθμό μπορούμε να διαχειριστούμε
τις κατατμήσεις μας και να τις προσαρτούμε βάση αυτού στον
αντίστοιχο κατάλογο με συγκεκριμένο όνομα. Η σημαντικότη-
τα του UUID έγκειται στο ότι παράγεται πάντα και αυτόματα,
σε αντίθεση με την ετικέτα τόμου, η οποία είναι προαιρετική
σε έναν δίσκο.
Με την εντολή blkid μπορούμε να δούμε τα UUID και τις
ετικέτες των block devices μας.
Έχουμε τη δυνατότητα να τροποποιήσουμε το αρχείο
/etc/fstab με τέτοιο τρόπο, ώστε να προσαρτά τους δίσκους
δεδομένων με βάση το UUID. Ακόμη, μπορούμε να επεξεργα-
στούμε το αρχείο /boot/grub/menu.lst, ώστε να εκκινεί το
rootfs με βάση αυτόν τον αριθμό.
Ένα παράδειγμα:
# blkid
/dev/sda1: LABEL=”root” UUID=”242ffd39-59a1-4ea3-
bf4c-34e40428e6d0” TYPE=”ext4”
Οπότε το /boot/grub/menu.lst θα πρέπει να είναι:
kernel /boot/vmlinuz root=/dev/disk/by-uuid/242ffd39-
59a1-4ea3-bf4c-34e40428e6d0 ro
Και το /etc/fstab θα πρέπει να είναι κάπως έτσι:
UUID=242ffd39-59a1-4ea3-bf4c-34e40428e6d0 /
ext4 defaults 0 0
Διαδικασία εκκίνησης του πυρήνα
Επιλέγοντας τη διανομή από το μενού επιλογής του GRUB,
ξεκινά η διαδικασία φόρτωσης του πυρήνα (kernel) στη μνήμη
του συστήματός μας. Ο kernel είναι το πρόγραμμα που ορίζε-
ται ως λειτουργικό σύστημα στη διανομή μας. Με λίγα λόγια,
ξεκινά το λειτουργικό σύστημά μας στη μνήμη RAM.
Το GRUB, διαμέσου της δήλωσης: root (hd0,0), διαβάζει
την κατάτμηση στην οποία βρίσκεται ο πυρήνας του λειτουρ-
γικού συστήματος. Όταν βρει το kernel /boot/vmlinuz, ξέρει
σε ποιο partition θα εντοπίσει τον πυρήνα.
Αφού εντοπίσει το συμπιεσμένο αρχείο, ξεκινά η φόρτωση
και η αποσυμπίεση του πυρήνα στην μνήμη του υπολογιστή
μας. Μόλις ολοκληρωθεί αυτή η φάση, φορτώνει στη μνήμη
και το αρχείο της δήλωσης: initrd /boot/initramfs.img.
Το initramfs αποτελεί ένα αρχείο στο οποίο έχουν περαστεί
όλα τα απαραίτητα modules (αρθρώματα) τα οποία χρειάζε-
ται ο πυρήνας του λειτουργικού συστήματος για να εκκινηθεί.
Εάν δεν έχουμε κάνει μόνοι μας re-compile τον πυρήνα, προ-
σθέτοντάς του επιπλέον αρθρώματα, τότε τα modules που
βρίσκονται στο initramfs θα φορτωθούν δυναμικά στη μνήμη
του συστήματός μας. Το βασικότερο άρθρωμα που χρειάζε-
ται ο πυρήνας του λειτουργικού μας, είναι εκείνο που αφορά
στο σύστημα αρχείων της διανομής μας.
Το initramfs, εκτός από τα απαραίτητα modules, ενσωματώ-
νει και ένα εκτελέσιμο αρχείο με όνομα linuxrc.
Σε αυτό το πρόγραμμα μεταβιβάζεται η διαδικασία εκκίνη-
σης του λειτουργικού μας.
Μετά το πέρας της φόρτωσης των αρθρωμάτων, το linuxrc
αναλαμβάνει να συνεχίσει τη διαδικασία. Ο πυρήνας, μέχρι
αυτό το σημείο, διαβάζει το αρχεία συστήματος στη μνήμη ως
Read-Only ramdisk filesystem. Μέσω της δήλωσης του
GRUB: root=/dev/sda1 εντοπίζει πού είναι το πραγματικό
rootfs της διανομής μας.
Μέχρι αυτό το σημείο, όπως προαναφέραμε, το λειτουργι-
κό σύστημά μας βρίσκεται στη μνήμη του συστήματός μας.
Στη συνέχεια, το kernel image προσαρτά σε προσωρινό κατά-
λογο τη rootfs κατάτμηση της διανομής και εκτελείται μία εκ
των δύο εντολών pivot_chroot ή switch_chroot.
Αυτές οι δύο εντολές εκτελούν την ίδια διαδικασία με πα-
ρεμφερή τρόπο.
Αφού γίνει η προσάρτηση της διανομής, πραγματοποιείται
μεταπήδηση από τη μνήμη του συστήματός σε αυτή και απο-
δεσμεύεται η μνήμη.
Έπειτα ο πυρήνας της διανομής συνεχίζει τη διαδικασία εκ-
κίνησης, πλέον από το σκληρό δίσκο, και εκτελεί την πρώτη
διεργασία στο μηχάνημα, την εντολή init.
Διεργασία Init
Η διανομή συνεχίζει πλέον από το δίσκο, διαβάζοντας τα
αρχεία των κατατμήσεων και σε κατάσταση read-write. Στη
μνήμη φορτώνονται τα αρχεία από τις εκτελούμενες διεργα-
σίες και υπηρεσίες. Το init process ξεκινά έχοντας το
proccess id: 1. H init δεν πεθαίνει ποτέ!
Μάλιστα, όταν κάποιο πρόγραμμα τερματιστεί βίαια και
έχουν απομείνει εκτελούμενες διεργασίες, αυτές θα μεταβι-
βάσουν τον έλεγχό τους στην init. Eίναι η πατρική διεργασία
(γονέας) για όλες τις υπόλοιπες που ξεκινούν είτε κατά το
boot proccess είτε στη συνέχεια από εμάς.
Η init διαβάζει το αρχείο /etc/inittab για να βρει το προκαθο-
ρισμένο runlevel και φορτώνει τις διεργασίες που βρίσκονται
σε αυτό.
Runlevels
Τα runlevels είναι καταστάσεις στις οποίες μεταβαίνει η
διεργασία init. Στην πραγματικότητα, είναι απλώς κάποια
profiles (υπό τη μορφή καταλόγων) στα οποία αποθηκεύουμε
τις διεργασίες που επιθυμούμε να ξεκινήσουν αυτόματα κατά
τη διαδικασία εκκίνησης.
Υπάρχουν επτά runlevels:
Runlevel 0:
Δηλώνει ότι το σύστημά μας είναι σβηστό
(power off).
Runlevel 1 ή S:
Σε αυτό το runlevel δεν τρέχει καμία διερ-
γασία. Γίνεται η προσάρτηση των κατατμήσεων μας κανονικά,
αλλά το init δεν εκκινεί καμία άλλη διεργασία. Εκτελεί τα αρ-
χεία rc.sysinit και rc.local. Μπορεί να συνδεθεί μόνο ένας
χρήστης, δεν υπάρχει ούτε γραφικό περιβάλλον ούτε
network.
Runlevel 2:
Η εκκίνηση του συστήματός μας γίνεται σε
multiuser (δυνατότητα να συνδεθούν χρήστες). Ξεκινά επίσης
τις διεργασίες (δαίμονες/προγράμματα) που έχουν δηλωθεί
να ξεκινήσουν σε αυτό το runlevel.
Το initramfs αποτελεί ένα αρχείο στο οποίο
έχουν περαστεί όλα τα απαραίτητα modules
(αρθρώματα) τα οποία χρειάζεται ο πυρήνας του
λειτουργικού συστήματος για να εκκινηθεί.