1 Adicionando novas chamadas de sistema no Linux
2 ==============================================
4 Luiz Fernando N. Capitulino
5 <lcapitulino@gmail.com>
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 é
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
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 -----------------------------------------------------------------
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
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 =======================================
95 Para testar a nova chamada sem usar a libc, pode-se usar assembly inline.
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
103 3. Executar 'int 0x80'
105 O exemplo abaixo chama getpid() usando esse método.
109 #include <unistd.h> /* pause() */
113 unsigned long num = 20; /* system call's number */
114 unsigned long pid = 0;
116 asm("movl %1, %%eax\n\t"
123 printf("%d\n", (int) pid);
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:
142 #include <sys/syscall.h>
143 #include <sys/types.h>
149 pid = syscall(SYS_getpid);
150 printf("%d\n", (int) pid);
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_.