O kernel não tem uma mainfunção. mainé um conceito da linguagem C. O kernel é escrito em C e assembly. O código de entrada do kernel é escrito por assembly.
A sequência de inicialização está organizada da seguinte maneira:
- O BIOS geralmente carrega um carregador de inicialização de um dispositivo de bloco de inicialização. Um gerenciador de inicialização popular agora é o grub.
- O Grub carrega uma imagem do kernel no ram, possível com um dispositivo raiz inicial (
initrd). Em seguida, o código em algum endereço é executado.
- A imagem do kernel possui alguns módulos do kernel, por exemplo: módulos do sistema de arquivos, drivers de dispositivo. A imagem do kernel usa o módulo do sistema de arquivos para montar o sistema de arquivos raiz. Agora o kernel pode carregar e executar todos os módulos do kernel a partir do disco.
- O kernel executa tarefas de inicialização. Por exemplo: atravesse o barramento PCI e encontre todos os dispositivos PCI, inicialize todos os drivers de dispositivo.
- Finalmente, o kernel cria o processo 0 e o processo 1 (o
initprocesso), alterna o contexto da CPU do anel 0 para o anel 3 e inicia o processo init (a identificação do processo é 1). Agora a inicialização do kernel está concluída!
- O
initprograma executa todos os scripts de inicialização. Todos os serviços são iniciados. Shell é chamado. Os usuários podem fazer login.
A mainfunção é uma função C. Na verdade, o método principal não é o ponto de entrada dos programas C. O tempo de execução C chama muitas funções antes main. O GCC possui um recurso de extensão: construtores. As funções declaradas "construtor" são chamadas antes main.
Por exemplo:
/* 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); \
}
Essa macro é do projeto qemu.