4

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.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
Jet Blue
  • 5,109
  • 7
  • 36
  • 48

2 Answers2

9

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.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
4

Simply use -kernel option:

qemu-system-i386 -kernel kernel.elf
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • when I use command: qemu-system-arm -machine connex -kernel kernel.elf I get the output, just a line.. A flash image must be given with the 'pflash' parameter I have no idea what kind of flash image is it asking for. – MSharq Jun 03 '19 at 13:01
  • 1
    @MSharq: You may create a new question post, and describe your problem there. (Do not forget to include to the post the **exact error message**). If you think that this question or answer are related to your problem, you may add appropriate link to your question post. – Tsyvarev Jun 03 '19 at 13:43
  • @MSharq please see https://lists.nongnu.org/archive/html/qemu-discuss/2021-03/msg00046.html . but I don't know how to do it if the .bin size is bigger than 64MB. Especially when the .bin contains big space between sections (like ROM and RAM very much apart) the .bin file gets too big. There must be a way of loading .elf to each address space without conflict. I'll try to find the method. – Chan Kim Mar 22 '21 at 08:45