Como você deve ter imaginado, os formatos executáveis contêm mais do que apenas código de máquina. Por exemplo, eles podem:
- Especifique metadados para o sistema operacional, por exemplo qual arquitetura o executável é destinado. Esses metadados incluem o cabeçalho do arquivo.
-
Especifique o programa layout na memória. Em sistemas operacionais modernos, a maioria dos executáveis não são carregados na memória em um único bloco - eles geralmente têm muitas regiões separadas / seções / segmentos . Alguns desses segmentos conterão código executável. Alguns deles conterão dados imutáveis, como strings de texto. Alguns deles serão designados como memória gravável, para o (s) heap (s) do programa.
Programas diferentes terão requisitos (pedidos) diferentes para os tamanhos dessas seções. Isso é tudo especificado no cabeçalho.
-
Alguns formatos também permitem que você incorpore uma assinatura digital , que permite a verificação de onde o binário veio.
- Why a separate specification is needed for the binary code - Linux uses ELF and Windows uses Portable Executable Format?
As razões são principalmente históricas, e os sistemas operacionais tendem a manter o formato 'nativo' (ou 'padrão') existente, a menos que haja uma razão convincente para mudar (como aconteceu, por exemplo, do formato DOS MZ para PE no NT 3.1, e de a.out para ELF no Linux 1.2, e de COFF para ELF em vários Unixes ao longo dos anos).
Deve-se notar que o código de máquina subjacente depende da arquitetura da CPU, mas é diferente (syscalls e bibliotecas ligadas à parte) amplamente portáteis entre sistemas operacionais. Na verdade, o Windows moderno e o Linux podem executar ambos os formatos executáveis: os executáveis ELF serão executados no Windows via WSL e os executáveis PE serão executados no Linux via WINE.
- Can an operating system and a program that runs on that operating system be created without this binary format specification?
Voltamos ao objetivo principal desses formatos. Sem os metadados informando ao SO onde carregar partes do programa, a maioria dos executáveis modernos não pode ser executada. Alguns formatos muito antigos como COM praticamente contêm código puro, mas não são particularmente flexíveis e caíram em desuso.
Na prática, não há necessidade de um sistema operacional existir. No nível do hardware, assumindo a existência de um BIOS (legado), o BIOS simplesmente começará a ser executado em um local específico no disco (MBR) , que pode ser um código de máquina arbitrário que então assume o controle e inicia um sistema operacional ou faz qualquer outra coisa que desejar. (Você pode ver o próprio MBR como um formato binário, embora não esteja diretamente relacionado ao código executável.) O UEFI mais moderno, no entanto, especifica um formato executável (PE) mais complexo.
- Is the binary format architecture dependent, OS dependent or both?
Depende do formato, na verdade. Alguns formatos assumem uma arquitetura específica. Outros permitem que você selecione a arquitetura de uma lista de "números mágicos" especificados no cabeçalho. Outros ainda são completamente independentes de arquitetura (por exemplo, bytecode Java e .NET / CIL).
Da mesma forma, o formato geralmente não impõe restrições ao sistema operacional, embora o sistema operacional seja restrito em quais formatos ele pode (nativamente) reconhecer e executar. É claro que as camadas de compatibilidade na parte superior do sistema operacional central podem executar outros formatos (por exemplo, JVM, .NET / CLR, WSL e WINE etc.) que o sistema operacional central talvez não reconheça.
- Does binary format applicable to only executable files or it is applicable to the operating system code as well?
Uma grande parte dos sistemas operacionais mais modernos é apenas uma coleção de arquivos executáveis "normais". No entanto, algumas partes do sistema operacional são "especiais" e não necessariamente usarão o mesmo formato que o restante. Geralmente, isso se aplica apenas ao bootloader e ao kernel.
Para extrair um exemplo específico e muito comum, o carregador de inicialização do BIOS legado não estará nos formatos ELF ou PE usados pelo Linux e pelo Windows. O kernel do Linux é geralmente construído em um formato derivado da ELF que o bootloader GRUB pode carregar , mas pode estar em um formato diferente para ser compatível com o gerenciador de inicialização usado. O kernel do Linux também suporta um modo EFI Stub , que contém um cabeçalho PE / COFF mínimo a ser compatível com inicialização UEFI direta.