QEMU AArch64 Virt Bare Bones: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
m (Reverted edits by Leapofazzam (talk) to last revision by Klange)
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
(5 intermediate revisions by 4 users not shown)
Line 12: Line 12:


=== boot.s ===
=== boot.s ===
<source lang="asm">
<syntaxhighlight lang="asm">
.global _start
.global _start
_start:
_start:
Line 19: Line 19:
bl kmain
bl kmain
b .
b .
</syntaxhighlight>
</source>


=== kernel.c ===
=== kernel.c ===
<source lang="c">
<syntaxhighlight lang="c">
#include <stdint.h>
#include <stdint.h>


Line 41: Line 41:
print("Hello world!\n");
print("Hello world!\n");
}
}
</syntaxhighlight>
</source>


=== linker.ld ===
=== linker.ld ===
<source lang="text">
<syntaxhighlight lang="text">
ENTRY(_start)
ENTRY(_start)
SECTIONS {
SECTIONS {
. = 0x40100000; /* RAM starts at 0x40000000 but if we ask to load the kernel there, QEMU will not load a DTB */
. = 0x40000000;
.startup . : { boot.o(.text) }
.startup . : { boot.o(.text) }
.text : { *(.text) }
.text : { *(.text) }
Line 53: Line 53:
.bss : { *(.bss COMMON) }
.bss : { *(.bss COMMON) }
. = ALIGN(8);
. = ALIGN(8);
. = . + 0x1000; /* 4kB of stack memory */
. += 0x1000; /* 4kB of stack memory */
stack_top = .;
stack_top = .;
}
}
</syntaxhighlight>
</source>


== Compiling the kernel ==
== Compiling the kernel ==
Now, we'll need to compile our kernel so we can boot it.
Now, we'll need to compile our kernel so we can boot it.
<source lang="bash">
<syntaxhighlight lang="bash">
$ aarch64-elf-as boot.s -o boot.o
$ aarch64-elf-as boot.s -o boot.o
$ aarch64-elf-gcc -ffreestanding -c kernel.c -o kernel.o
$ aarch64-elf-gcc -ffreestanding -c kernel.c -o kernel.o
$ aarch64-elf-ld -nostdlib -Tlinker.ld boot.o kernel.o -o kernel.elf
$ aarch64-elf-ld -nostdlib -Tlinker.ld boot.o kernel.o -o kernel.elf
</syntaxhighlight>
</source>


== Booting our kernel ==
== Booting our kernel ==
Since our kernel is now compiled, we'll boot it with QEMU
Since our kernel is now compiled, we'll boot it with QEMU
<source lang="bash">
<syntaxhighlight lang="bash">
$ qemu-system-aarch64 -machine virt -cpu cortex-a57 -kernel kernel.elf -nographic
$ qemu-system-aarch64 -machine virt -cpu cortex-a57 -kernel kernel.elf -nographic
Hello world!
Hello world!
</syntaxhighlight>
</source>


== See also ==
== See also ==
* [[ARM Overview]]
* [[ARM Overview]]
* [[Raspberry Pi Bare Bones]]
* [[Raspberry Pi Bare Bones]]

[[Category:ARM]]
[[Category:Bare bones tutorials]]
[[Category:QEMU]]

Latest revision as of 05:46, 9 June 2024

QEMU is a free and open source hardware emulator that supports multiple architecture, including ARM. QEMU has its own generic board mainly for virtualization usages, called virt. virt supports ARM and RISC-V architecture.

In this tutorial, we'll write a basic kernel for QEMU virt board, specifically Aarch64.

Prerequisites

For this tutorial, you'll need

  • An ARM cross-compiler toolchain
  • QEMU, of course you'll need QEMU because this tutorial designed for QEMU virt.

Code

Now we'll need to write some code for our little kernel.

boot.s

.global _start
_start:
    ldr x30, =stack_top
    mov sp, x30
    bl kmain
    b .

kernel.c

#include <stdint.h>

volatile uint8_t *uart = (uint8_t *) 0x09000000;

void putchar(char c) {
    *uart = c;
}

void print(const char *s) {
    while(*s != '\0') {
        putchar(*s);
        s++;
    }
}

void kmain(void) {
     print("Hello world!\n");
}

linker.ld

ENTRY(_start)
SECTIONS {
    . = 0x40100000; /* RAM starts at 0x40000000 but if we ask to load the kernel there, QEMU will not load a DTB */
    .startup . : { boot.o(.text) }
    .text : { *(.text) }
    .data : { *(.data) }
    .bss : { *(.bss COMMON) }
    . = ALIGN(8);
    . += 0x1000; /* 4kB of stack memory */
    stack_top = .;
}

Compiling the kernel

Now, we'll need to compile our kernel so we can boot it.

$ aarch64-elf-as boot.s -o boot.o
$ aarch64-elf-gcc -ffreestanding -c kernel.c -o kernel.o
$ aarch64-elf-ld -nostdlib -Tlinker.ld boot.o kernel.o -o kernel.elf

Booting our kernel

Since our kernel is now compiled, we'll boot it with QEMU

$ qemu-system-aarch64 -machine virt -cpu cortex-a57 -kernel kernel.elf -nographic
Hello world!

See also