gnu/linux kernel module programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · moduli –...
TRANSCRIPT
![Page 1: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/1.jpg)
Linux Day 2006
GNU/Linux Kernel Module GNU/Linux Kernel Module ...Programming ...Programming
Fabio RubinoFabio [email protected]@cs.unibo.it
![Page 2: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/2.jpg)
ModuliModuli
● Cosa sono
● Perche' scriverli
● Quando è utile scriverli
● Come scriverli
![Page 3: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/3.jpg)
Moduli – Cosa sonoModuli – Cosa sono
Codice che può essere caricato e rimosso dinamicamente
Si possono pensare come librerie, plugin per vari programmi, in questo caso il Kernel
![Page 4: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/4.jpg)
Moduli – Peche' scriverliModuli – Peche' scriverli
● Supporto di nuove funzionalitàa a runtime driver file system protocolli ....
![Page 5: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/5.jpg)
Moduli – Quando è utile scriverliModuli – Quando è utile scriverli
● Aggiunta di nuove funzionalità solo quando servono
● Risparmio di memoria
● Velocizzare la fase testing
![Page 6: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/6.jpg)
Moduli – Come scriverliModuli – Come scriverli
E' bene tener presente alcune differenze tra la scrittura di un semplice programma e la scrittura di un modulo del kernel
● Ciclo di vita● Contesto di esecuzione● Funzioni esterne● Protezione memoria● Memoria disponibile● Concorrenza● Floating point
![Page 7: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/7.jpg)
Ciclo di vitaCiclo di vita
Programmi● Iniziano, fanno ciò che devono e terminano
Moduli● Caricati, rimangono in attesa di richieste● Rimossi, le funzionalità non sono più disponibili
![Page 8: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/8.jpg)
Contesto di esecuzioneContesto di esecuzione
Programmi● User space
non hanno accesso diretto al risorse
Moduli● Kernel space
accesso a tutto le risorse
![Page 9: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/9.jpg)
Funzioni esterneFunzioni esterne
Programmi● Possibile utilizzo di funzioni di libreria
printf() strcopy() ...
Moduli● Solo funzioni e macro esportate dal kernel
printk() put_user() ...
![Page 10: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/10.jpg)
Protezione della memoriaProtezione della memoria
Programmi● Fornita dal S.O.
dereferenzianzione di un puntatore nullo invio del segnale SIGSEGV da parte del kernel e uccisione del processo
Moduli● PANIC!
![Page 11: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/11.jpg)
Memoria disponibileMemoria disponibile
Programmi● Rappresentati in memoria virtuale
ampio stack
Moduli● Stack molto piccolo 4/8KB
non passare grandi strutture usare l'allocazione dinamica
● Rischio di sovrascrivere la memoria
![Page 12: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/12.jpg)
ConcorrenzaConcorrenza
Programmi● Generalmente singlethreaded
sequenziale (no racecondition)Moduli● Multithreaded
accesso a strutture dati condivise in maniera casuale a secondo della
schedulzione possiblie perdita di consistenza (rececondition)● Proteggere le strutture dati
semafori, spinlock...
![Page 13: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/13.jpg)
Floating pointFloating point
Programmi● Hanno a disposizioni i registri per il calcolo del FP
Moduli● Non è ammesso l'uso del FP per evitare di dover salvare i registri FP ad ogni entrata e uscita dal kernel space
![Page 14: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/14.jpg)
IniziamoIniziamo
Primo esempio il classico hello world che illustra lo scheletro che sta dietro ogni modulo
![Page 15: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/15.jpg)
Il classico Hello worldIl classico Hello world#include <linux/init.h>#include <linux/module.h>#include <linux/kernel.h>
static *char namemodule_param (name, charp, S_IRUGO);
static int __init hello_init(void){
printk(KERN_ALERT "Hello, %s\n", name);return 0;
}
static void __exit hello_exit(void){
printk(KERN_ALERT "Goodbye, %s\n", name);}
module_init(hello_init);module_exit(hello_exit);
![Page 16: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/16.jpg)
Analisi StrutturaAnalisi Struttura
Solo due funzioni di base:
● Una funzione hello_init() eseguita al momento del caricamento
● Una funzione hello_exit() eseguita la momento della rimozione dal modulo
![Page 17: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/17.jpg)
Analisi – hello_init()Analisi – hello_init()
static int __init hello_init(void){
printk(KERN_ALERT "Hello world %s\n", name);return 0;
}
Invocata al momento del caricamento da module_init() stampa nel file di log “Hello, <name>”
● Inizializza strutture, device
![Page 18: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/18.jpg)
Analisi – hello_exit()Analisi – hello_exit()
static void __exit hello_exit(void){
printk(KERN_ALERT "Goodbye, %s\n", name);}
Invocata al momento della rimozione da module_exit() stampa nel file di log “Goodbye, <name>”
● Dealloca tutto ciò che è stato inizializzato dalla init
![Page 19: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/19.jpg)
Analisi – Stadi di log Analisi – Stadi di log
● I possibili stadi di log KERN_EMERG 0 sistema instabile
KERN_ALERT 1 stato di allerta KERN_CRIT 2 stato critico KERN_ERR 3 stato di errore KERN_WARNING 4 stato in pericolo KERN_NOTICE 5 KERN_INFO 6 informazioni KERN_DEBUG 7 messaggi di debug
![Page 20: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/20.jpg)
Analisi – Passaggio dei parametriAnalisi – Passaggio dei parametri
● Tramite la macro module_param(name, type, perm)
name nome variabile type tipo passato perm permessi di accesso
![Page 21: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/21.jpg)
Analisi HeadersAnalisi Headers
● <linux/init.h>macro ( __init e __exit)
● <linux/module.h>strtture descrittive(nome, autore, licenza)funzioni (module_init/exit())
● <linux/kernel.h>prototipi di funzioni (printk())stadi di log (KERN_ALERT)
![Page 22: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/22.jpg)
CompilazioneCompilazione
● Creare un Makefile contenenteobjy := hello.o (statica)objm := hello.o (come moulo)
● Compilare con il comando
make C <KernelDir> M=$(pwd) modules
KernelDir Directory del kernel M=$(pwd) Directory contenente i moduli modules Crea i moduli
![Page 23: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/23.jpg)
Caricamento e rimozioneCaricamento e rimozione
● Per caricare un moduloinsmod <nome modulo>insmod hello.ko
● Per rimuoverlo rmmod <nome modulo>rmmod hello
![Page 24: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/24.jpg)
Device driverDevice driver
● Character device
● Block device
● Si trovano in /dev /proc/devices tutti i device caricati
● Major number e minor number
![Page 25: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/25.jpg)
Major e minor numberMajor e minor number
$ ls l devbrwrw 1 root disk 3, 0 20061026 14:03 /dev/hda
● Major numbernumero del device drivere utilizzato
● Minor number numero distintivo per ogni componente
hardware che usa il device driver
![Page 26: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/26.jpg)
registrare un character deviceregistrare un character device
● Reggistriamo il nostro deviceregister_chrdev(0, "cdev", &fops); primo parametro il major number secondo parametro il nome del device terzo parametro struttura file_operations restituisce il major number assegnato
● Per rilasciare un dispositivo unregister_chrdev("cdev");
![Page 27: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/27.jpg)
file_operation structfile_operation struct
● Definire le operazioni open, read, write...
Struttura file operations di cdev
static struct file_operations fops = {.read = cdev_read,.write = cdev_write,.open = cdev_open,.release = cdev_release
};
![Page 28: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/28.jpg)
cedv_open()cedv_open()
static int cdev_open(struct inode *inode, struct file *file){
if (Busy)return EBUSY;
Busy++;string_p = string;try_module_get(THIS_MODULE);return 0;
}
● Controlla possibili errori del device● Inizializa il device
![Page 29: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/29.jpg)
cdev_read()cdev_read()
static ssize_t cdev_read(struct file filp, /* file pointer */char __user *buffer, /* userdata pointer */
size_t l_data, /* length data read */loff_t * offs) /* offset posizione corrente */
{if (*string_p == 0)
return 0;
while (length && *string_p) {put_user(*(string_p++), buffer++);
l_data;}return 0;
}
● Non si puo dereferenziare buffer si usa put_user()
![Page 30: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/30.jpg)
cdev_write()cdev_write()
static ssize_t cdev_write(struct file filp, /* file pointer */char __user *buffer, /* userdata pointer */
size_t l_data, /* length data write */loff_t * offs) /* offset posizione corrente */
{int i;for (i = 0; i < l_data && i < MAXLENGTH; i++)
get_user(string[i], buffer + i);return i;
}
● Non si puo dereferenziare buffer si usa get_user()
![Page 31: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/31.jpg)
cdev_release()cdev_release()
static int cdev_release(struct inode *inode, struct file *file){
Busy;module_put(THIS_MODULE);return 0;
}
● Chiude il device
![Page 32: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/32.jpg)
Dopo tanto....Dopo tanto....
● Compiliamo ● Carichiamo il modulo● Creiamo il dispositivo
mknod /dev/<nome device> c <Maj> <min>
● Per scopire il Major number assegnatocat /dev/devices
● Proviamoloecho “Linux Day 2006” > /dev/cdev0cat < /dev/cdev0
![Page 33: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/33.jpg)
Per finire...Per finire...
NON AVVELENATE IL KERNEL!!!
● Rilasciate il vostri moduli sotto copyleft GPL
● Basta aggiungereMODULE_LICENSE(“GPL”);
![Page 34: GNU/Linux Kernel Module Programmingerlug.linux.it/linuxday/2006/contrib/rubino.pdf · Moduli – Cosa sono Codice che può essere caricato e rimosso dinamicamente Si possono pensare](https://reader031.vdocuments.mx/reader031/viewer/2022021810/5c669e3e09d3f252168ca657/html5/thumbnails/34.jpg)
Grazie..Grazie..
Happy Hacking!