Portabilidad del sistema Linux: proceso de inicio del kernel

Portabilidad del sistema Linux: proceso de inicio del kernel

Para iniciar el código del kernel de Linux, primero mire el archivo vmlinux.lds de su secuencia de comandos de enlace, el archivo es el siguiente:

20220321193507

Indica una entrada de entidad de función: función stext, ubicada en arch/arm/kernel/head.S

Hay un comentario de segmento en la entrada de la función.

20220321193847

Se estipula que la MMU, D-cache, r0=0, r1=machine nr (es decir, el ID de la máquina), r2=atags o la primera dirección del árbol de dispositivos (dtb) deben cerrarse antes de ejecutar la función ( r1, r2 son los parámetros pasados ​​por la función)

La función primero realiza algunos juicios y conversiones para determinar que el modo está en BE8 y usa instrucciones de pulgar

20220321194431

Luego use la macro safe_svcmode_maskall para proteger las interrupciones IRQ y FIQ y cambie al modo SVC; guarde el valor CPSR original guardado en r9 en SPSR

safe_svcmode_maskall r9

Luego lea la identificación del procesador, el valor de la identificación se almacena en el registro r9

20220321194836

Llame a la función __lookup_processor_type para verificar si el sistema actual admite esta CPU y, de ser así, obtenga la información de procinfo en r5

20220321194950

El kernel de Linux abstrae cada procesador en una estructura proc_info_list, y cada procesador corresponde a un procinfo, por lo que la estructura procinfo correspondiente se encuentra a través de la ID del procesador.

Las siguientes definiciones de macro realizan diferentes funciones de acuerdo con las definiciones, sáltelas y no las mire.

Línea 121, llame a la función __vet_atags para verificar la validez de las etiquetas o el árbol de dispositivos (dtb)

20220321195149

Luego llame a __create_page_tables para crear una tabla de páginas y guarde la dirección de la función __mmap_switched al registro r13

20220321203709

Finalmente, llame a la función __enable_mmu para habilitar la MMU, __enable_mmu enciende la MMU llamando a __turn_mmu_on, y luego __turn_mmu_on ejecutará la función __mmap_switched guardada en r13 al final, __mmap_switched finalmente llama a start_kernel para iniciar el kernel de Linux

La función start_kernel se define en el archivo init/main.c. Esta función completa algunos trabajos de inicialización antes de que Linux comience llamando a muchas subfunciones. Hay muchas subfunciones aquí, que no se ampliarán en detalle. Estas funciones establecerán el tamaño de la pila e inicialice la pila. , configure algún código relacionado con la arquitectura, complete alguna inicialización del kernel y llame a la función rest_init después de que todo esté listo

La función rest_init se define en el archivo init/main.c

20220321204748

Primero llame a la función rcu_scheduler_starting para iniciar el programador de bloqueo de RCU

Luego llame a la función kernel_thread para crear el proceso kernel_init. El proceso init es un proceso kernel al principio (es decir, se ejecuta en el modo kernel), y luego el proceso init buscará un programa llamado "init" en el sistema de archivos raíz. , y este programa "init" está en modo usuario. , al ejecutar este programa "init", el proceso init realizará la transición del modo kernel al modo usuario

Luego llame a la función kernel_thread para crear el proceso del kernel kthreadd, el PID de este proceso del kernel es 2, y el proceso kthreadd es responsable de la programación y administración de todos los procesos del kernel.

Finalmente, se llama a la función cpu_startup_entry para ingresar al proceso inactivo cpu_startup_entry llamará a cpu_idle_loop .

Ingrese ps -A debajo de la interrupción de Linux para ver el proceso init y el proceso ktthreadd

20220321205241

systemd es el proceso de inicio

Es muy importante usar el proceso init. Parte del contenido se inicializa en el proceso. De acuerdo con los parámetros de ramdisk_execute_command y execute_command, se encuentra un programa ejecutable init en el sistema de archivos raíz. Si todo está vacío, ejecute "/sbin/ init", "/etc/init", "/bin/init" y "/bin/sh" son los cuatro programas de inicio de respaldo. Si estos cuatro no se ejecutan, se terminará y el sistema no podrá iniciarse. Además, el proceso init también llamará La función do_basic_setup se utiliza para completar la inicialización del controlador del dispositivo en Linux, completar la inicialización del subsistema del modelo del controlador en Linux y abrir el dispositivo "/dev/console" como entrada estándar y salida del sistema, realice la interacción de la línea de comandos y llame a la función prepare_namespace para montar el sistema de archivos raíz, por lo que la función do_basic_setup es muy importante para el proceso de inicio.

Lo anterior es un proceso general de inicio del kernel de Linux

Supongo que te gusta

Origin blog.csdn.net/qq_45396672/article/details/123646158
Recomendado
Clasificación