Processo de Carregamento Unix / Linux

7

Alguém pode me dizer qual processo do sistema operacional carrega o arquivo ELF (formato executável e de vinculação) na RAM?

    
por Naveen kumar 09.10.2012 / 12:55

2 respostas

9

Um usuário geralmente encontra três tipos de arquivos ELF - arquivos .o, executáveis comuns e bibliotecas compartilhadas. Embora todos esses arquivos tenham propósitos diferentes, seus arquivos de estrutura interna são bastante semelhantes.

Um conceito universal entre todos os diferentes tipos de arquivos ELF (e também a.out e muitos outros formatos de arquivos executáveis) é a noção de uma seção. Uma seção é uma coleção de informações de um tipo semelhante. Cada seção representa uma parte do arquivo. Por exemplo, o código executável é sempre colocado em uma seção conhecida como .text ; todas as variáveis de dados inicializadas pelo usuário são colocadas em uma seção conhecida como .data ; e os dados não inicializados são colocados em uma seção conhecida como .bss .

Na verdade, pode-se criar um formato de arquivo executável onde tudo é misturado (como MS DOS ). Mas dividir os executáveis em seções tem vantagens importantes. Por exemplo, depois de carregar as partes executáveis de um executável na memória, essas localizações de memória não precisam ser alteradas. Em arquiteturas de máquinas modernas, o gerenciador de memória pode marcar partes da memória como somente leitura, de tal forma que qualquer tentativa de modificar uma localização de memória somente de leitura resulta no núcleo morrendo e descarregando do programa. Assim, em vez de simplesmente dizer que não esperamos que um determinado local de memória seja alterado, podemos especificar que qualquer tentativa de modificar um local de memória somente leitura é um erro fatal que indica um erro no aplicativo. Dito isto, normalmente você não pode definir individualmente o status somente leitura para cada byte de memória - em vez disso, você pode definir individualmente as proteções de regiões de memória conhecidas como páginas. Na arquitetura i386, o tamanho da página é de 4096 bytes - portanto, você poderia indicar que os endereços 0-4095 são somente leitura e os bytes 4096 e superiores são graváveis, por exemplo.

Dado que queremos todas as partes executáveis de um executável em memória somente leitura e todos os locais modificáveis de memória (como variáveis) em memória gravável, é mais eficiente agrupar todas as partes executáveis de um executável. em uma seção da memória ( a seção .text ), e todas as áreas de dados modificáveis juntas em outra área da memória (doravante conhecida como a seção .data ).

Uma distinção adicional é feita entre as variáveis de dados que o usuário inicializou e as variáveis de dados que o usuário não inicializou. Se o usuário não especificou o valor inicial de uma variável, não faz sentido perder espaço no arquivo executável para armazenar o valor. Assim, as variáveis inicializadas são agrupadas na seção .data e as variáveis não inicializadas são agrupadas na seção .bss, o que é especial porque não ocupa espaço no arquivo - informa apenas quanto espaço é necessário para variáveis não inicializadas.

Quando você pede ao kernel para carregar e executar um executável, ele começa examinando o cabeçalho da imagem para obter dicas sobre como carregar a imagem. Ele localiza a seção .text dentro do executável, carrega-a nas partes apropriadas da memória e marca essas páginas como somente leitura. Em seguida, ele localiza a seção .data no executável e a carrega no espaço de endereço do usuário, dessa vez na memória de leitura / gravação. Finalmente, ele localiza a localização e o tamanho da seção .bss do cabeçalho da imagem e adiciona as páginas apropriadas da memória ao espaço de endereço do usuário. Mesmo que o usuário não tenha especificado os valores iniciais das variáveis colocadas em .bss, por convenção, o kernel inicializará toda essa memória para zero.

Então você vê, é realmente o kernel que emite as ordens para carregar o executável na memória. A seção de texto como resultado de tais chamadas é carregada na memória somente leitura e a seção de dados é carregada na memória de leitura / gravação.

    
por 09.10.2012 / 13:58
4

Depende do sistema operacional.

Por exemplo, no GNU Hurd, o arquivo executável é carregado pelo servidor exec .

Em um SO monolítico mais típico, isso é feito por:

  1. o kernel mapeia o executável e o vinculador dinâmico na memória;

  2. o vinculador dinâmico mapeia os objetos compartilhados na memória.

O próprio kernel do Linux é armazenado como um arquivo ELF: este é carregado pelo gerenciador de inicialização (como o GRUB).

    
por 10.09.2015 / 00:02

Tags