Kernel do Linux: O que significa asmlinkage na definição de chamadas de sistema?
A resposta curta à sua pergunta é que asmlinkage diz ao seu compilador para procurar na pilha da CPU os parâmetros da função, em vez de registos. Na verdade, ele usa o atributo regparam do GCC's (http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html), ou syscall_linkage para IA64:
- #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
A parte interessante é porque isto é necessário. Chamadas de sistema são serviços que o espaço do usuário pode chamar para solicitar ao kernel para executar algo para eles (e portanto executar no espaço do kernel). Estas funções são bastante pouco ortodoxas no sentido de que você não pode esperar que elas se comportem como funções normais, onde os parâmetros são tipicamente passados por escrito para a pilha de programas, mas ao invés disso são escritos para registros. Enquanto ainda no espaço do usuário, a chamada ao syscall requer a escrita de certos valores para certos registros é traduzida. O número da chamada de sistema (http://lxr.linux.no/linux+v3.5.4/arch/x86/syscalls/syscall_64.tbl) será sempre escrito em eax, enquanto o resto dos parâmetros irão para ebx, ecx, etc. Pegue por exemplo uma chamada para sethostname(2), declarada como int sethostname(char *name, size_t len), ela se parecerá com algo parecido:
- 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(). Entrar em detalhes sobre esta função está fora do escopo desta questão, então a coisa mais importante que você precisa ter em mente é que ela começa salvando todos os registros na pilha da CPU (eax, ebx, ecx, etc). Depois de verificar outras coisas, como validar parâmetros, ele chamará a respectiva chamada do sistema se tudo estiver em ordem. In this example: sys_sethostname, defined as:
- SYSCALL_DEFINE2(sethostname, char __user *, name, int, len)
- {
- ...
- >li>}
>/p>
Então, como toda a informação sobre os parâmetros passados desde a terra do usuário até este ponto é bem armazenada na pilha, o compilador deve ser instruído sobre isso, daí o asmlinkage.
Note que apesar de uma chamada de sistema não requerer parâmetros, tais como fork(), o registro eax será sempre preenchido com o número syscall.
Para mais detalhes sobre chamadas de sistema e a ponte entre o espaço do usuário e o espaço do kernel, eu recomendo Entender o Kernel Linux, 3ª Edição.
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
Código fonte para a função sethostname: http://lxr.linux.no/linux+v3.5.4/kernel/sys.c#L1365
Código fonte para x86 system_call: http://lxr.linux.no/linux+v3.5.4/arch/x86/kernel/entry_64.S#L495
Artigos semelhantes
- O Chrome OS é realmente baseado no kernel do Linux? Se sim, por que ele não pode rodar programas Linux?
- Qual é a diferença entre 'Android', 'Embedded Linux', e 'Vanilla Linux kernel'?
- Como portar um novo kernel num dispositivo Android com kernel existente
- Quais são as principais alterações que o Android fez no kernel do Linux?