LINUS D.I.T. Kernel Department

(Category)  Καλώς Ήρθατε στο Linux Kernel Programming Dept. του Δημοκριτείου Ινστιτούτου Τεχνολογίας.
Linux Kernel Programming Quick Start Guide
The following is a quick start guide Linux Kernel programming.
Κεφάλαιο 1.          Linux Kernel Basics
  • Με τη χρήση της ιδιότητας 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
Suggestions or Ideas for this Quick Start Guide should be submitted via our email: (kernel@dalab.ee.duth.gr).
© Copyright 2002, Sotirios Kontogiannis, ocean@ocean.ee.duth.gr