¿El núcleo tiene una función main ()? [cerrado]


52

Estoy aprendiendo controladores de dispositivos y programación de Kernel. Según el libro de Jonathan Corbet, no hay main()función en los controladores de dispositivos.

Entonces yo dos preguntas:

  • ¿Por qué no necesitamos una main()función en los controladores de dispositivo?
  • ¿El núcleo en sí tiene una main()función?

¿Alguien puede explicarme esto?


1
También preguntado por el mismo usuario aquí: stackoverflow.com/q/18266063/827263
Keith Thompson

@KeithThompson ... Sí ... Solo porque no obtuve la respuesta que quería, así que lo pregunté aquí.
alguien

@Shadur ... de todos modos ahora está a punto de cerrarse ... Y no tengo el privilegio de migrar eso ...
alguien

Esto debería haberse cerrado al revés, este tiene muchas más vistas :-)
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:


82

En los programas de espacio de usuario, main()es el punto de entrada al programa al que se llama el código de inicialización de libc cuando se ejecuta el binario. El código del kernel no tiene el lujo de confiar en libc, ya que libc se basa en la interfaz syscall del kernel para la asignación de memoria, E / S, gestión de procesos, etc.

Dicho esto, el equivalente del main()código del núcleo es start_kernel(), que es llamado por el gestor de arranque después de haber cargado la imagen del núcleo, descomprimirla en la memoria y configurar el hardware esencial y la paginación de la memoria. start_kernel()realiza la mayoría de la configuración del sistema y finalmente genera el proceso de inicio.

El punto de entrada a los módulos del kernel de Linux es una función init que se registra con el kernel llamando a la module_init()macro. La función de inicio del módulo registrado se llama mediante el código del núcleo a través de la do_initcalls()función durante el inicio del núcleo.


11
Gracias por reconocer el verdadero propósito del mainmétodo en C. (Es una idea errónea muy común que el sistema operativo hace una llamada directa main, lo cual no es el caso y es aún menos el caso, por ejemplo, en C ++). Te daría otro voto positivo si pudiera por eso.
un CVn

1
@Thomas ... Gracias por esta excelente respuesta ...
alguien

17

El kernel no tiene una mainfunción. mainEs un concepto del lenguaje C. El núcleo está escrito en C y ensamblado. El código de entrada del núcleo se escribe por ensamblado.

La secuencia de arranque se organiza de la siguiente manera:

  1. El BIOS generalmente carga un cargador de arranque desde un dispositivo de bloque de arranque. Un cargador de arranque popular en este momento es grub.
  2. Grub carga una imagen del kernel en ram, posible con un dispositivo raíz inicial ( initrd). Luego se ejecuta el código en alguna dirección.
  3. La imagen del núcleo tiene algunos módulos del núcleo, por ejemplo: módulos del sistema de archivos, controladores de dispositivos. La imagen del núcleo utiliza el módulo del sistema de archivos para montar el sistema de archivos raíz. Ahora el núcleo puede cargar y ejecutar todos los módulos del núcleo desde el disco.
  4. El kernel ejecuta tareas de inicialización. Por ejemplo: atraviese el bus PCI y encuentre todos los dispositivos PCI, inicialice todos los controladores de dispositivo.
  5. Finalmente, el núcleo crea el proceso 0 y el proceso 1 (el initproceso), cambia el contexto de la CPU del anillo 0 al anillo 3 e inicia el proceso de inicio (el ID del proceso es 1). ¡Ahora el arranque del kernel ha terminado!
  6. El initprograma ejecuta todos los scripts de inicio. Todos los servicios se inician. Se llama Shell. Los usuarios pueden iniciar sesión.

La mainfunción es una función C. En realidad, el método principal no es el punto de entrada de los programas en C. El tiempo de ejecución C llama muchas funciones antes main. GCC tiene una característica extendida: constructores. Las funciones declaradas "constructor" se llaman antes main.

Por ejemplo:

/* This should not be used directly. Use block_init etc. instead. */ 
#define module_init(function, type) \
    static void _attribute__((constructor)) do_qemu_init ## function(void) { \
    register_module_init(function, type); \
} 

Esta macro es del proyecto qemu.


El método principal es el método ac. En realidad, el método principal no es la entrada del programa c. El tiempo de ejecución de C ha llamado a muchos métodos antes que el método principal.
Edward Shen

bueno, la BIOS generalmente carga un gestor de arranque, y ese gestor de arranque carga una imagen del núcleo (y posiblemente un initrd). El código del kernel está en la imagen del kernel, no initrd
Stéphane Chazelas

GCC tiene una característica extendida: constructor. La declaración de método "constructor" se llama antes del método principal. Por ejemplo: / * Esto no debe usarse directamente. Utilice block_init, etc. en su lugar. * / #define module_init (function, type) \ static void _attribute __ ((constructor)) do_qemu_init ## function (void) {\ register_module_init (function, type); \}
Edward Shen

1
initrd.img NO ES la imagen del núcleo. Es un conjunto de módulos cargados por el núcleo en el arranque. Las imágenes del núcleo generalmente tienen nombres que comienzan con "vmlinuz" pero difieren de una distribución a otra.
Ricitos de oro

3
Esta respuesta está repleta de "todo es una PC / Linux / i86" y arranca de esa manera y el núcleo es de esa manera ... ¿Por qué todos piensan que esa es la única forma posible en el mundo?
Jens

9

Hay, por ejemplo, una función main () en arch / x86 / boot / main.c para preparar el sistema para cambiar del modo real al modo protegido, pero otras arquitecturas no tienen dicho código. Hay una buena visión general de cómo funciona el arranque del kernel de Linux 2.6.x en la plataforma x86. Realmente vale la pena leerlo.

Según el documento CÓMO hacer el desarrollo del kernel de Linux , el kernel de Linux es

un entorno C independiente, sin depender de la biblioteca C estándar, por lo que algunas partes del estándar C no son compatibles.

lo que según el estándar C BTW significa que

Se define la implementación si se requiere un programa en un entorno independiente para definir una función 'principal'.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.