Estou tentando inicializar um kernel personalizado no QEMU usando UEFI. Isto é para um sistema operacional que estou escrevendo. Quando executo este comando, sou levado ao shell UEFI. Posso estar errado, mas acho que se tudo estiver configurado corretamente, o QEMU deverá inicializar no kernel em vez do shell UEFI. Tentei usar o gerenciador de boot para executar o kernel e alterar a ordem de inicialização, mas não tive sorte.
Suspeito que meu kernel esteja no formato errado. Quando executo o arquivo myKernel.img no Ubuntu, recebo esta saída:
myKernel.img: OpenPGP Secret Key
Eu li sobre stubs UEFI online, mas acho que isso é apenas para kernels Linux. Veja como construo myKernel.img:
aarch64-linux-gnu-objcopy -O binary myKernel.elf myKernel.img
E aqui está o comando QEMU:
qemu-system-aarch64 \
-cpu cortex-a76 \
-machine virt,kernel=myKernel.img \
-display gtk,show-tabs=on -device ramfb -serial vc \
-drive if=pflash,format=raw,unit=0,file=firmware/uefi/AARCH64_OVMF_CODE.fd,readonly=on \
-drive if=pflash,format=raw,unit=1,file=firmware/uefi/AARCH64_OVMF_VARS.fd
Agradeço qualquer sugestão ou conselho! Além disso, deixe-me saber se este não é o lugar certo para esta pergunta. Inicialmente perguntei isso no Stack Overflow, mas não cabia naquele site.
Resposta muito superficial, já que não tenho conhecimento suficientemente profundo:
Isso é o que você normalmente obtém quando o arquivo não está em nenhum formato específico diferente de "blob bruto de código de máquina", ou seja, ele não possui um cabeçalho reconhecível e o
file
comando acaba mostrando seu palpite mais próximo. (Ele toma a maioria de suas decisões com base em alguns bytes iniciais, e o código de máquina ARM provavelmente coincide com um cabeçalho OpenPGP válido.)Então, provavelmente espera que a imagem tenha um cabeçalho semelhante ao Linux que indica em qual endereço base a imagem deve ser carregada, onde está o ponto de entrada, etc.
-O binary
(É semelhante em conceito ao cabeçalho ELF que você está removendo atualmente, embora seja altamente específico do Linux e dependente da plataforma; por exemplo, o Linux no x86 usaria um handshake mais complexo do que no AArch64.)
Embora quando usado em combinação com UEFI, eu quase esperaria que essa opção exigisse um arquivo de imagem no formato EFI em vez de um arquivo do kernel do Linux.
Apenas a parte do stub (ou seja, o conceito de colar um bootloader diretamente na imagem do kernel) é específica do Linux, mas o problema geral que ela resolve é específico da UEFI.
A UEFI não pode aceitar diretamente imagens brutas "carregar em X e pular para Y", como as que você
objcopy -O binary
produz, pois não sabe onde carregá-las e onde está o ponto de entrada. Em vez disso, ele espera receber um.efi
arquivo no formato PE/COFF (também conhecido como literalmente um arquivo .exe com outro nome) que contém essas informações.Tradicionalmente, este teria sido um bootloader dedicado (por exemplo, grubx64.efi ou elilo.efi) que sabe como iniciar um kernel Linux, e isso se aplica igualmente a qualquer sistema operacional que inicialize através de UEFI – por exemplo, o Windows inicia via winload.efi – e o a única parte específica do Linux é a combinação das duas funções em um arquivo .efi "vmlinuz de dupla face, mas com maquiagem PE/COFF".
Portanto, ou a saída da sua compilação é agrupada em um cabeçalho PE/COFF para que se torne um arquivo .efi válido para a execução do UEFI (possivelmente usando elf2efi ), ou você precisa usar um intermediário como GRUB ou U-Boot (ou seja, que já é um programa .efi válido por si só) para carregá-lo.