O kernel não tem uma main
funçã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
init
processo), 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
init
programa executa todos os scripts de inicialização. Todos os serviços são iniciados. Shell é chamado. Os usuários podem fazer login.
A main
funçã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.