|
-
Με τη χρήση της ιδιότητας LKM (Loadable Kernel Modules) του πυρήνα του
Linux είναι δυνατόν να γράψει κανείς κώδικα ο οποίος θα εκτελείται σε kernel
space.
-
Συνήθως ο επεξεργαστής επιβάλει προστασία του συστήματος από τις εφαρμογές.
Οι Intel επεξεργαστές έχουν 4 τέτοια επίπεδα προστασίας, τα μεσαία εκ των
οποίων δεν χρησιμοποιούνται μέχρι σήμερα από κανένα λειτουργικό σύστημα.
Επομένως μας μένουν δύο επίπεδα: 1. Το υψηλό επίπεδο (real,supervisor mode
ή kernel level), και η περιοχή μνήμης που χρησιμοποιεί (kernel space).
Σε αυτό το επίπεδο λειτουργεί ο πυρήνας του Linux και έχει τη δυνατότητα
της απευθείας πρόσβασης στο hardware και την χωρίς έλεγχο πρόσβαση σε όλη
τη μνήμη. 2. Το χαμηλό επίπεδο (protected mode ή user level), και η περιοχή
μνήμης που χρησιμοποιεί (user space).
-
Μπορεί κανείς να μεταφερθεί από το ένα επίπεδο στο άλλο μέσω περιορισμένου
αριθμού πυλών. Το Linux μεταφέρει την εκτέλεση προγραμμάτων από το kernel
στο user space, χρησιμοποιώντας κλήσεις συστήματος (system calls) και hardware
interrupts.
-
Οι εφαρμογές εκτελούνται σειριακά, ενώ ο πυρήνας λειτουργεί ασύγχρονα,
εκτελώντας κλήσεις συστήματος για λογαριασμό των εφαρμογών. Ο πυρήνας είναι
υπεύθυνος για την είσοδο/έξοδο (I/O), καθώς και για την διαχείρηση των
πόρων κάθε διεργασίας στο σύστημα. Ένα module είναι συνδεδεμένο με όλο
τoν πυρήνα του λειτουργικού συστήματος και λειτουργεί σε kernel mode. Πρέπει
κανείς να είναι διαχειριστής του συστήματος για να φορτώσει ένα kernel
module, όχι όμως και για κάνει compile ένα module.
-
Κάθε module καθορίζει ένα σύμβολο που λέγεται kernel_version, και το οποίο
ελέγχει το insmod έναντι του αριθμού έκδοσης του τρέχοντος πυρήνα. Βρισκεται
δε προκαθορισμένο στο <linux/module.h>.
-
Ένα απλό Makefile για να κάνετε compile to πρώτο σας kernel module hello.c:
Χρησιμοποιούμε linux kernel version: 2.2.19:
INCLUDEDIR= /usr/src/linux/include
HOSTCFLAGS =-D__KERNEL__ -O2 -Wstrict-prototypes
-fomit-frame-pointer \
-fno-strict-aliasing -D__SMP__ -pipe -fno-strength-reduce -m486 -malign-loops=2
\
-malign-jumps=2 -malign-functions=2 -DCPU=586 -DMODULE \
-DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h
VER = $(shell awk -F"\"" '/REL/ {print $$2}' $(INCLUDEDIR)/linux/version.h)
CC = /usr/bin/gcc
hello.o: hello.c
$(CC) -I$(INCLUDEDIR) $(HOSTCFLAGS) -c hello.c
install:
install -c hello.o /lib/modules/$(VER)/misc
clean:
rm -f hello.o core
-
Το πρώτο module hello.c το οποίο τυπώνει στο /proc/kmsg (use dmesg!), ένα
μύνημα (use insmod):
/* Standard in kernel modules */
#include <linux/kernel.h> /* We're doing kernel work
*/
#include <linux/module.h> /* This is header for LKM work*/
#ifdef MODULE
int
init_module(void);
void
cleanup_module(void);
#endif
/* Deal with CONFIG_MODVERSIONS */
#ifdef CONFIG_MODVERSIONS /*Version of the module -- linked
with kernel version at
compile time*/
#define MODVERSIONS
#include <linux/modversions.h>
#endif
int init_module() /*This is the main function, executes when ``insmod
hello.o``*/
{
printk(KERN_ERR "Hello -- world\n"); /*See syslog.h fot KERN_ERR*/
return (0);
}
void cleanup_module()
{
printk(KERN_ERR "Short is the life of a kernel module\n");/*this is
called when unloading
module using rmmod hello*/
}
-
Συνοπτική διαδικασία εκκίνησης ενός Intel επεξεργαστή:
1. Execute address 0xFFF0 (ROM-BIOS)
2. BIOS: Initialize interrupt vector at physical address 0
3. Load first sector of bootable media to 0x7C00
4. Jump to 0x7C00
------------------ LINUX BOOT ------------------
5. Move to 0x90000
6. Load the first 2 Kbytes of boot device to 0x90200 and rest of kernel
to 0x10000
7. Identify host System and Vga card
8. Enter protected mode: Move the whole system from 0x10000 to user
space address 0x1000
9. kernel decompression to 0x10000000 ( Αυτός είναι και ο λόγος που
το Linux δεν μπορεί να λειτουργήσει με λιγότερο από 2MB RAM )
10. Decompressed code is executed at 0x1010000
11. 32 bit Setup accomplished, IDT, GDT, LDT loaded
12. Coprossecor initialized
13. Paging Started
14. start_kernel() invoked: a) memory bounds set, paging_init() called
b) Initializes traps, IRQ channels and scheduling c) Parses the command
line buffer d) Allocates a profiling buffer
15. Initialize devices
16. Calibrated delay loop and computes the BogoMips number
17. Checks if int 16 works with a corprocessor
18. move_to_user_mode()
19. Init Started , process inittab and exec rc (/usr/src/linux/init/main.c)
20. Daemons Started from rc and login process from inittab |