Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run a bare metal ELF file on QEMU?

Tags:

qemu

kernel

elf

How do you run an elf file on QEMU? This is my best guess:

qemu-system-i386 -hda kernel.elf

Does this work? The elf file is a kernel generated from this tutorial.

like image 321
Jet Blue Avatar asked Dec 18 '22 23:12

Jet Blue


2 Answers

Minimal runnable example

Source: https://github.com/cirosantilli/aarch64-bare-metal-qemu/tree/27537fb1dd0c27d6d91516bf4fc7e1d9564f5a40

Run with:

make
qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -kernel test64.elf -serial mon:stdio

Outcome: prints a single character H to the UART and then goes into an infinite loop.

Source:

==> test64.ld <==
ENTRY(_Reset)
SECTIONS
{
    . = 0x40000000;
    .startup . : { startup64.o(.text) }
    .text : { *(.text) }
    .data : { *(.data) }
    .bss : { *(.bss COMMON) }
    . = ALIGN(8);
    . = . + 0x1000; /* 4kB of stack memory */
    stack_top = .;
}

==> test64.c <==
volatile unsigned int * const UART0DR = (unsigned int *) 0x09000000;

void print_uart0(const char *s) {
    while(*s != '\0') {         /* Loop until end of string */
         *UART0DR = (unsigned int)(*s); /* Transmit char */
          s++;                  /* Next char */
    }
}

void c_entry() {
     print_uart0("Hello world!\n");
}

==> startup64.s <==
.global _Reset
_Reset:
    mov x0, 0x48
    ldr x1, =0x09000000
    str x0, [x1]
    b .

==> Makefile <==
CROSS_PREFIX=aarch64-linux-gnu-

all: test64.elf

startup64.o: startup64.s
    $(CROSS_PREFIX)as -g -c $< -o $@

test64.elf: startup64.o
    $(CROSS_PREFIX)ld -Ttest64.ld $^ -o $@

clean:
    rm -f test64.elf startup64.o test64.o

You may change the entry address 0x40000000 to almost anything (as long as it is not mapped to the memory of some device?).

QEMU just parses the entry address from the Elf file, and puts the PC there to start with. You can verify that with GDB:

qemu-system-aarch64 -M virt -cpu cortex-a57 -nographic -kernel test64.elf -S -s &
gdb-multiarch -q -ex 'file test64.elf' -ex 'target remote localhost:1234'

Here I list a few other setups that may be of interest: How to make bare metal ARM programs and run them on QEMU?

Tested on Ubuntu 18.04.


Simply use -kernel option:

qemu-system-i386 -kernel kernel.elf
like image 29
Tsyvarev Avatar answered Apr 28 '23 21:04

Tsyvarev