first commit
This commit is contained in:
commit
ef58d5b07e
34 changed files with 2210 additions and 0 deletions
37
rv_tests/hello_world/Makefile
Normal file
37
rv_tests/hello_world/Makefile
Normal file
|
@ -0,0 +1,37 @@
|
|||
# RISC-V toolchain
|
||||
CC = riscv64-unknown-elf-gcc
|
||||
AS = riscv64-unknown-elf-as
|
||||
LD = riscv64-unknown-elf-ld
|
||||
OBJCOPY = riscv64-unknown-elf-objcopy
|
||||
QEMU = qemu-system-riscv64
|
||||
|
||||
# Compilation flags
|
||||
ARCH_FLAGS = -march=rv64imac -mabi=lp64
|
||||
LDSCRIPT = linker.ld
|
||||
|
||||
# Output files
|
||||
ELF = hello.elf
|
||||
BIN = hello.bin
|
||||
OBJ = hello.o
|
||||
SRC = hello.S
|
||||
|
||||
# Default rule
|
||||
all: $(BIN)
|
||||
|
||||
# Assemble and link to ELF
|
||||
$(ELF): $(SRC) $(LDSCRIPT)
|
||||
$(AS) $(ARCH_FLAGS) -o $(OBJ) $(SRC)
|
||||
$(LD) -T $(LDSCRIPT) -o $(ELF) $(OBJ)
|
||||
|
||||
# Convert ELF to raw binary
|
||||
$(BIN): $(ELF)
|
||||
$(OBJCOPY) -O binary $(ELF) $(BIN)
|
||||
|
||||
# Run in QEMU
|
||||
run: $(BIN)
|
||||
echo "Press CTRL+A then X to exit QEMU"
|
||||
$(QEMU) -machine virt -nographic -bios none -kernel $(BIN) -device loader,file=$(BIN),addr=0x80000000
|
||||
|
||||
# Clean up generated files
|
||||
clean:
|
||||
rm -f $(OBJ) $(ELF) $(BIN)
|
8
rv_tests/hello_world/build.sh
Normal file
8
rv_tests/hello_world/build.sh
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Assemble the code
|
||||
riscv64-unknown-elf-as -march=rv64imac -mabi=lp64 -o hello.o hello.S
|
||||
|
||||
# Link with our linker script to create an ELF file
|
||||
riscv64-unknown-elf-ld -T linker.ld -o hello.elf hello.o
|
||||
|
||||
# Convert ELF to a raw binary
|
||||
riscv64-unknown-elf-objcopy -O binary hello.elf hello.bin
|
23
rv_tests/hello_world/hello.S
Normal file
23
rv_tests/hello_world/hello.S
Normal file
|
@ -0,0 +1,23 @@
|
|||
.section .text.init
|
||||
.global _start
|
||||
|
||||
.equ UART_BASE, 0x10000000 # QEMU's UART base address
|
||||
|
||||
_start:
|
||||
# Load address of the string into a1
|
||||
la a1, message
|
||||
|
||||
loop:
|
||||
lbu a0, 0(a1) # Load a byte from the string
|
||||
beqz a0, exit # If null terminator, exit
|
||||
li t0, UART_BASE # Load UART address
|
||||
sb a0, 0(t0) # Store character to UART (8-bit write)
|
||||
addi a1, a1, 1 # Move to next character
|
||||
j loop # Repeat
|
||||
|
||||
exit:
|
||||
j exit # Infinite loop
|
||||
|
||||
.section .rodata
|
||||
message:
|
||||
.asciz "Hello, world!\n"
|
BIN
rv_tests/hello_world/hello.elf
Executable file
BIN
rv_tests/hello_world/hello.elf
Executable file
Binary file not shown.
25
rv_tests/hello_world/linker.ld
Normal file
25
rv_tests/hello_world/linker.ld
Normal file
|
@ -0,0 +1,25 @@
|
|||
OUTPUT_ARCH(riscv)
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Start execution at 0x80000000 */
|
||||
. = 0x80000000;
|
||||
|
||||
.text : {
|
||||
*(.text.init)
|
||||
*(.text)
|
||||
}
|
||||
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
}
|
||||
|
||||
.data : {
|
||||
*(.data)
|
||||
}
|
||||
|
||||
.bss : {
|
||||
*(.bss)
|
||||
}
|
||||
}
|
Reference in a new issue