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 assembly embutido injetado em 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.
Em include/linux/syscalls.h
sob o diretório fonte do seu kernel, você encontra isto:
asmlinkage long sys_mkdir(const char __user *pathname, int mode);
Então, em /usr/include/asm*/unistd.h
, você encontra isto:
#define __NR_mkdir 83
__SYSCALL(__NR_mkdir, sys_mkdir)
Este código está dizendo mkdir(2)
é a chamada do sistema # 83. Ou seja, as chamadas do sistema são chamadas por número, não por endereço como em uma chamada de função normal dentro de seu próprio programa ou por uma função em uma biblioteca vinculada ao seu programa. O código de cola de montagem inline que eu mencionei acima usa isso para fazer a transição do usuário para o espaço do kernel, levando seus parâmetros junto com ele.
Outra pequena evidência de que as coisas são um pouco estranhas aqui é que nem sempre há uma lista de parâmetros rígidos para as chamadas do sistema: open(2)
, por exemplo, pode ter 2 ou 3 parâmetros. Isso significa que open(2)
é sobrecarregado , um recurso do C ++, não do C, mas a interface syscall é compatível com o C. (Isso não é a mesma coisa que o recurso varargs do C , que permite que uma única função obtenha um número variável de argumentos.)
Para responder à sua primeira pergunta, não há um único arquivo em que 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 ao kernel esconder tudo o que está por trás de uma única chamada de sistema é chamada de VFS . Então, você provavelmente quer começar a pesquisar em 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 do ext4 é chamada ext4_mkdir()
, definida em fs/ext4/namei.c
.
Quanto à sua segunda pergunta, sim, há padrões para tudo isso, mas não uma regra única. O que você realmente precisa é de um entendimento bastante amplo de como o kernel funciona para descobrir onde você deve procurar qualquer chamada de sistema específica. Nem todas as chamadas de sistema envolvem o VFS, portanto, suas cadeias de chamadas do lado do kernel não são todas iniciadas em fs/namei.c
. mmap(2)
, por exemplo, começa em 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.