Llamadas al sistema (System Calls)
Llamadas al sistema (System Calls)
El sistema operativo es un club privado (Kernel Mode) y tus programas son clientes esperando en la puerta (User Mode). La única forma de pedir una bebida, usar el baño o salir, es a través de una lista estricta de peticiones permitidas: la Interfaz de Llamadas al Sistema.
Una System Call (o syscall) es la forma programática en la que un programa solicita un servicio al kernel.
Libc vs. Syscall: La diferencia técnica
Es vital distinguir entre una Función de Librería y una Llamada al Sistema.
1. Función de librería (User Space)
- Son parte del lenguaje (ej.
stdio.hen C). - Corren completamente en modo usuario.
- Son portables (el mismo código funciona en Windows y Linux).
- Ejemplo:
fopen(),printf(),memcpy().
2. Llamada al sistema (Kernel Space)
- Son la entrada al sistema operativo.
- Ejecutan una instrucción de trap para saltar a modo kernel.
- Son específicas del OS (la syscall
readde Linux no es igual aReadFilede Windows). - Ejemplo:
open(),write(),brk().
El flujo real: Tu código llama a
printf(Librería) $\to$printfformatea el texto y llama awrite(Syscall wrapper) $\to$writeejecuta la instrucción de CPUSYSCALL$\to$ El Kernel toma el control, habla con el driver de video y pone el píxel en la pantalla.
Anatomía de una syscall
¿Qué ocurre físicamente en el procesador cuando invocas una syscall como read()? No es un JMP normal a una función.
1. Preparación de registros
El programa (o la librería C) coloca el número de la syscall en un registro específico (ej. RAX en x86-64). También coloca los argumentos en otros registros (RDI, RSI, etc.).
2. La instrucción trampolín
Se ejecuta una instrucción especial de la CPU: INT 0x80 (en sistemas viejos) o SYSCALL (en modernos). Esto dispara una Excepción (Trap).
3. Cruce de frontera (Mode Switch)
El hardware cambia el Bit de Modo de 1 (User) a 0 (Kernel). La CPU salta a la dirección del manejador de syscalls del kernel.
4. Ejecución privilegiada
El kernel verifica que los argumentos sean seguros (ej. que no intentes leer memoria que no es tuya) y ejecuta la operación.
5. Retorno
El kernel coloca el resultado (o código de error) en un registro, ejecuta la instrucción SYSRET y la CPU vuelve a modo usuario.
El costo del rendimiento (Overhead)
Hacer una llamada al sistema no es gratis. Es mucho más lento que una llamada a una función normal dentro de tu programa.
Cada vez que haces una syscall, ocurre un Cambio de Contexto (Context Switch):
- Se deben guardar los registros del usuario.
- Se invalida parte de la caché de la CPU y la TLB (Translation Lookaside Buffer).
- Se cambia el mapa de memoria.
Clasificación POSIX
Aunque cada SO tiene sus propios nombres, el estándar POSIX (Portable Operating System Interface) define un conjunto común que sistemas como Linux y macOS respetan.
| Categoría | Ejemplos Clave | Descripción |
|---|---|---|
| Control de Procesos | fork(), exec(), exit(), wait() | Crear, ejecutar y terminar programas. |
| Gestión de Archivos | open(), read(), write(), close() | Manipular datos persistentes. |
| Gestión de Dispositivos | ioctl(), read(), write() | Configurar hardware (ej. cambiar resolución). |
| Mantenimiento de Info | getpid(), time(), sleep() | Obtener datos del sistema o del proceso. |
| Comunicaciones | pipe(), shmget(), mmap() | IPC (Inter-Process Communication). |
Herramienta indispensable: strace
¿Cómo sabes qué syscalls está haciendo un programa cerrado (como ls o tu propio ejecutable)?
En Linux, existe una herramienta mágica llamada strace.
# Muestra todas las syscalls que hace el comando 'ls'
strace ls
Verás una salida como esta:
execve("/usr/bin/ls", ["ls"], ...) = 0
mmap(NULL, 8192, ...) = 0x7f...
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|...) = 3
getdents64(3, ...) = 2048
write(1, "archivo.txt\n", 12) = 12
close(3) = 0
Es una excelente forma de depurar por qué tu código falla sin mirar el código fuente.