miércoles, 29 de abril de 2015

Swapper... the ancestor - Hay vida antes de init?

Todos los que por algún u otro motivo nos vemos inmersos en la administración de sistemas Unix-Like como GNU/Linux sabemos que hay un proceso muy particular llamado init. Algunas de sus particularidades son:

  • Es el primer proceso en user-space. 
  • Lleva el número 1 como su identificador de proceso.
  • Es el padre de todos los procesos del sistema.
  • Inicia y termina junto con el sistema.
Todos reconocemos a init como el primer proceso y el motor que desencadena el inicio del sistema. PERO....

juan@moon:~$ ps axo ppid,pid,comm|head
PPID PID COMMAND
0 1 init
0 2 kthreadd 
2 3 ksoftirqd/0
2 5 kworker/0
2 7 rcu_sched
2 8 rcuos/0
2 9 rcuos/1
2 10 rcuos/2
2 11 rcuos/3
juan@moon:~$

qué me dicen del PPID del proceso kthreadd? A caso kthreadd no debería ser hijo de init? Cómo puede ser que init y kthreadd sean hermanos (tienen el mismo PPID)? Quién demonios creó kthreadd!!!!???

Todo indica que debería existir un proceso con identificador 0 y que este proceso de alguna manera dio vida a init y a kthreadd. Pero no existe proceso con ese identificador, para confirmar veamos directamente en /proc (de donde ps obtiene la información):

juan@moon:/proc$ find . 1 -maxdepth 0 -type d
.
1
juan@moon:/proc$ find . 2 -maxdepth 0 -type d
.
2
juan@moon:/proc$ find . 0 -maxdepth 0 -type d
.
find: «0»: No existe el archivo o el directorio
juan@moon:/proc$ 


Hurgando un poco en los confines mas oscuros de Internet encontré que existe vida antes de init!!!

Luego de que le indicamos al boot loader qué kernel queremos iniciar, este se descomprime en memoria y se lanza el génesis...
 
Swapper es el nombre de la primer tarea que corre el kernel, se crea durante la etapa de inicialización a partir de la función start_kernel(). Algunas de las tareas que realiza son:


  • Inicialización de estructuras del kernel
  • Configuración de interrupciones
  • Configuración de la administración de memoria
  • Inicia el kernel init (proceso 1).
  • Iniciar otros hilos de kernel, kthreadd (proceso 2) por ejemplo.
Luego de todo esto, swapper se retira del escenario y ejecuta cpu_idle() que en esencia pone a swapper a hacer nada indefinidamente. El proceso queda en un estado TASK_RUNNING y es ejecutado por algún procesador cuando no hay mas procesos que precisen ser ejecutados.

En conclusión... init es el primer proceso en espacio de usuario, pero NO el primer proceso en ejecutarse. El primer proceso en ejecutarse se llama swapper (PID=0), y es quien lanza a init y kthreadd (en ese orden).

Y si, hay vida antes de init!

Fuentes:

http://www.inf.fu-berlin.de/lehre/SS01/OS/Lectures/Lecture05.pdf
http://en.wikipedia.org/wiki/Linux_startup_process
http://duartes.org/gustavo/blog/post/kernel-boot-process/
http://www.dedoimedo.com/computers/crash-analyze.html