Kernel Linux: Cosa significa asmlinkage nella definizione delle chiamate di sistema?
La risposta breve alla tua domanda è che asmlinkage dice al tuo compilatore di guardare sullo stack della CPU per i parametri della funzione, invece che nei registri. Infatti, usa l'attributo regparam di GCC (http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html), o syscall_linkage per IA64:
- #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))
La parte interessante è perché questo è necessario. Le chiamate di sistema sono servizi che lo userspace può chiamare per richiedere al kernel di eseguire qualcosa per loro (e quindi eseguire nello spazio kernel). Queste funzioni sono abbastanza poco ortodosse, nel senso che non ci si può aspettare che si comportino come le funzioni normali, dove i parametri sono tipicamente passati scrivendo sullo stack del programma, ma invece sono scritti nei registri. Mentre si è ancora nello userspace, chiamare una syscall richiede la scrittura di certi valori in certi registri viene tradotto. Il numero della chiamata di sistema (http://lxr.linux.no/linux+v3.5.4/arch/x86/syscalls/syscall_64.tbl) sarà sempre scritto in eax, mentre il resto dei parametri andrà in ebx, ecx, ecc. Prendete per esempio una chiamata a sethostname(2), dichiarata come int sethostname(char *name, size_t len), sarà qualcosa del genere:
- mov ecx, len ; amount of bytes in name
- mov ebx, name ; address of name string
- mov eax, 170 ; syscall number (sys_sethostname)
- int 0x80 ; x86 call the kernel -- sysenter is another entry point
With the int there is a software interrupt and the CPU switches to kernel mode, to then execute system_call(). Entrare nel dettaglio di questa funzione è fuori dallo scopo di questa domanda, quindi la cosa più importante da tenere a mente è che inizia salvando tutti i registri nello stack della CPU (eax, ebx, ecx, ecc). Dopo aver controllato altre cose come la convalida dei parametri, chiamerà la rispettiva chiamata di sistema se tutto è in ordine. In this example: sys_sethostname, defined as:
- SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
- {
- ...
- }
Quindi, poiché tutte le informazioni sui parametri passati da userland a questo punto sono ben memorizzate nello stack, il compilatore deve essere istruito su questo, da cui l'asmlinkage.
Nota che anche se una chiamata di sistema non richiede parametri, come fork(), il registro eax sarà sempre popolato con il numero della syscall.
Per maggiori dettagli sulle chiamate di sistema e il ponte tra lo spazio utente e lo spazio kernel, raccomando Understanding the Linux Kernel, 3rd Ed.
http://www.amazon.com/Understanding-Linux-Kernel-Third-Daniel/dp/0596005652/ref=sr_1_1?s=books&ie=UTF8&qid=1348053154&sr=1-1&keywords=understanding+the+linux+kernel
Codice sorgente per la funzione sethostname: http://lxr.linux.no/linux+v3.5.4/kernel/sys.c#L1365
Codice sorgente per x86 system_call: http://lxr.linux.no/linux+v3.5.4/arch/x86/kernel/entry_64.S#L495
Articoli simili
- Cosa si intende per kernel stock e kernel personalizzato?
- Chrome OS è davvero basato sul kernel Linux? Se sì, perché non può eseguire programmi Linux?
- Cos'è un kernel? Quali sono i vantaggi e gli svantaggi di installare kernel personalizzati sugli smartphone Android?
- Come fare il porting del kernel più recente su un dispositivo Android con il kernel esistente