QEMU AArch64 Virt Bare Bones: Difference between revisions
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 === |
||
< |
<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 === |
||
< |
<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 === |
||
< |
<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 */ |
|||
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. |
||
< |
<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 |
||
< |
<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!