Introduce old redir program
[lcapit-junk-code.git] / Documentation / pt_BR / linux-nova-syscall.txt
blob01911959bb987701e91c21ce5e48e8afc7c5f096
1                 Adicionando novas chamadas de sistema no Linux
2                 ==============================================
4                         Luiz Fernando N. Capitulino
5                          <lcapitulino@gmail.com>
7 1. Introdução
8 =============
10  Este arquivo descreve passo-a-passo como adicionar novas chamadas de
11 sistema no Linux. Para uma descrição sobre como chamadas de sistema
12 funcionam leia: linux-syscall.txt.
14  Licença: http://creativecommons.org/licenses/by-nc-nd/2.5/br/
16 1.1 Adicione a nova chamada de sistema
17 --------------------------------------
19  As chamadas de sistema tem o seguinte protótipo:
21 asmlinkage long sys_nome_da_chamada(arg1, arg2, ...);
23  O arquivo no qual a chamada de sistema deve ser adicionada depende do
24 que a chamada faz. No geral elas ficam nos diretórios:
26  o  kernel/ chamadas genéricas
27  o  fs/     relacionadas ao sistema de arquivos
28  o  mm/     relacionadas ao gerenciamento de memória
29  o  arch/   chamadas específicas de arquitetura 
31  É importante notar que não é possível ter chamadas de sistemas em
32 módulos. Uma das razões é que a tabela que contêm as chamadas não é
33 exportada.
35 FIXME: explicar asmlinkage.
37 1.2. Adicione o protótipo
38 -------------------------
40  O protótipo da nova chamada de sistema deve ser adicionado no
41 arquivo de cabeçalho: include/linux/syscalls.h.
43 1.3. Adicione a entrada na tabela de chamadas de sistema
44 --------------------------------------------------------
46  Cada arquitetura tem sua própria tabela de chamadas de sistema. No geral
47 elas ficam em arch/<arch>/kernel/ e se chamam sys_call_table, mas o nome do
48 arquivo que as contêm pode variar. Dois nomes comuns são systbls.S ou
49 syscall_table.S.
51  Para máquinas i386 a tabela fica em: arch/x86/kernel/syscall_table_32.S,
52 e chama-se sys_call_table.
54  O número da chamada corresponde a sua posição na tabela. A questão da
55 numeração é importante, pois fazem parte da ABI do kernel com user-space.
56 Isso implica, por exemplo, que chamadas deletadas não podem ter seu
57 número reusado por chamadas novas.
59  A sintaxe da tabela em syscall_table_32.S é:
61 .long sys_nome_da_chamada
63 FIXME: para chamadas de sistema que devem estar disponível em todas as
64 arquiteturas tem que alterar todas as tabelas, certo?
66 1.4. Adicione o número da chamada no arquivo include/asm/unistd.h
67 -----------------------------------------------------------------
69  O formato é:
71 #define __NR_nome_da_chamada    número
73  Assim como a tabela de chamadas de sistema, cada arquitetura tem sua
74 versão do arquivo unistd.h. Para chamadas de sistema que devem estar
75 disponível em todas as arquiteturas, todos os arquivos unistd.h devem
76 ser alterados.
78  O número da chamada deve ser pego da tabela de chamadas de sistema.
80 FIXME: confirmar a informação sobre outras arquiteturas.
82 1.5. Atualize a macro NR_syscalls
83 ---------------------------------
85  No mesmo arquivo unistd.h modificado no passo anterior, há uma macro
86 chamada NR_syscalls. O valor dessa macro deve ser acressido de um.
89 2. Utilizando a nova chamada de sistema
90 =======================================
92 2.1 Teste em assembly
93 ---------------------
95  Para testar a nova chamada sem usar a libc, pode-se usar assembly inline.
97  O código deve:
99         1. Colocar o número da chamada no registrador %eax
100         2. Passar argumentos nos registradores: %ebx, %ecx, %esi e %edi
101            (ou um ponteiro para uma estrutura em %ebx se houver mais
102             argumentos)
103         3. Executar 'int 0x80'
105  O exemplo abaixo chama getpid() usando esse método.
108 #include <stdio.h>
109 #include <unistd.h> /* pause() */
111 int main(void)
113         unsigned long num = 20; /* system call's number */
114         unsigned long pid = 0;
116         asm("movl %1, %%eax\n\t"
117              "int $0x80\n\t"
118              "movl %%eax, %0\n\t"
119              : "=r" (pid)
120              : "r" (num)
121              : "eax" );
123         printf("%d\n", (int) pid);
124         pause();
126         return 0;
130 2.2 glibc
131 ---------
133  A glibc tem uma função disponível para fazer chamadas de sistema, o nome
134 dessa função é (advinhe) syscall(2).
136  O mesmo código da função anterior poderia ser escrito como:
139 #include <stdio.h>
140 #define _GNU_SOURCE
141 #include <unistd.h>
142 #include <sys/syscall.h>
143 #include <sys/types.h>
145 int main(void)
147         pid_t pid;
149         pid = syscall(SYS_getpid);
150         printf("%d\n", (int) pid);
151         pause();
153         return 0;
157  Note que o header syscall.h modificado no passo 1.2 não tiver sido
158 instalado, será necessário passar o número da chamada para syscall()
159 ao invés da macro SYS_.