As chamadas do sistema não são tratadas como chamadas de função regulares. É necessário um código especial para fazer a transição do espaço do usuário para o espaço do kernel, basicamente um pouco de código de montagem embutido injetado no seu programa no site de chamada. O código do lado do kernel que "captura" a chamada do sistema também é algo de baixo nível que você provavelmente não precisa entender profundamente, pelo menos a princípio.
No include/linux/syscalls.h
diretório de origem do seu kernel, você encontra o seguinte:
asmlinkage long sys_mkdir(const char __user *pathname, int mode);
Então /usr/include/asm*/unistd.h
, você encontra o seguinte:
#define __NR_mkdir 83
__SYSCALL(__NR_mkdir, sys_mkdir)
Este código está dizendo mkdir(2)
é a chamada de sistema # 83. Ou seja, as chamadas do sistema são chamadas por número, não por endereço, como ocorre com uma chamada de função normal em seu próprio programa ou para uma função em uma biblioteca vinculada ao seu programa. O código de cola de montagem em linha que mencionei acima usa isso para fazer a transição do espaço do usuário para o kernel, levando seus parâmetros junto com ele.
Outra evidência de que as coisas são um pouco estranhas aqui é que nem sempre existe uma lista estrita de parâmetros para chamadas do sistema: open(2)
por exemplo, pode-se usar 2 ou 3 parâmetros. Isso significa que open(2)
está sobrecarregado , um recurso do C ++, não do C, mas a interface do syscall é compatível com o C. (Isso não é o mesmo que o recurso varargs de C , que permite que uma única função receba um número variável de argumentos.)
Para responder sua primeira pergunta, não existe um arquivo único onde mkdir()
exista. O Linux suporta muitos sistemas de arquivos diferentes e cada um tem sua própria implementação da operação "mkdir". A camada de abstração que permite que o kernel oculte tudo isso atrás de uma única chamada do sistema é chamada de VFS . Então, você provavelmente quer começar a pesquisar fs/namei.c
, com vfs_mkdir()
. As implementações reais do código de modificação do sistema de arquivos de baixo nível estão em outro lugar. Por exemplo, a implementação ext4 é chamada ext4_mkdir()
, definida em fs/ext4/namei.c
.
Quanto à sua segunda pergunta, sim, existem padrões para tudo isso, mas nenhuma regra. O que você realmente precisa é de um entendimento bastante amplo de como o kernel funciona, a fim de descobrir onde você deve procurar qualquer chamada específica do sistema. Nem todas as chamadas do sistema envolvem o VFS; portanto, as cadeias de chamadas do lado do kernel nem todas são iniciadas fs/namei.c
. mmap(2)
, por exemplo, inicia mm/mmap.c
, porque faz parte do subsistema de gerenciamento de memória ("mm") do kernel.
Eu recomendo que você obtenha uma cópia de " Entendendo o Kernel do Linux ", de Bovet e Cesati.