armv8 qemu bios uart hello world 实现

uart

uart.h

#if !defined(_UART_H)
#define  _UART_H 
#include <stdint.h>

void uart_putc(const char c);
void uart_puthex(uint64_t n);
void uart_puts(const char *s);

#endif  /*  _UART_H   */

uart.c

#include "uart.h"

volatile unsigned int * const UART0DR = (unsigned int *) 0x09000000;
volatile unsigned int * const UART0FR = (unsigned int *) 0x09000018;


void uart_putc(const char c)
{
   
	// Wait for UART to become ready to transmit.
	while ((*UART0FR) & (1 << 5)) {
    }
	*UART0DR = c; /* Transmit char */
}

void uart_puthex(uint64_t n)
{
   
	const char *hexdigits = "0123456789ABCDEF";

	uart_putc('0');
	uart_putc('x');
	for (int i = 60; i >= 0; i -= 4){
   
		uart_putc(hexdigits[(n >> i) & 0xf]);
		if (i == 32)
			uart_putc(' ');
	}
}

void uart_puts(const char *s)
{
   
	for (int i = 0; s[i] != '\0'; i ++)
		uart_putc((unsigned char)s[i]);
}

测试uart打印

test.c

#include "uart.h"

void printf_hello_world()
{
   
    uart_puts("hello world\n");
}

entry | 设置栈 && 调用打印

reset.S

.global	 reset
reset:
    msr		spsel, #0
	ldr		x0, =runtime_sp
	mov		sp, x0
    bl      printf_hello_world
    b       .

链接脚本

main.ld.S

ENTRY(reset)

MEMORY {
   
	rom (rx) : org = 0x0, len = 16M
	runtime_ram (rwx) : org = 0x60000000, len = 512M
}

SECTIONS {
   
	.text : {
   
		reset.o (.text);
		uart.o (.text);
		test.o (.text);
	} > rom

	runtime_sp = ORIGIN(runtime_ram) + LENGTH(runtime_ram);
}

Makefile

AS=aarch64-linux-gnu-as
LD=aarch64-linux-gnu-ld
CC=aarch64-linux-gnu-gcc
OBJCOPY=aarch64-linux-gnu-objcopy
DD=dd


AS_SOURCES=reset.S
AS_OBJS=$(subst .S,.o,$(AS_SOURCES))
LD_SCRIPT=main.ld.S

C_SOURCES=$(wildcard *.c)
C_OBJS=$(subst .c,.o,$(C_SOURCES))


ELF=test.elf
BIN=test.bin
FLASH=flash.bin

$(BIN): $(ELF)
	$(OBJCOPY) -O binary $< $@

$(ELF): $(AS_OBJS) $(C_OBJS)
	$(LD) -T $(LD_SCRIPT) $^ -o $@ -N

$(AS_OBJS):%.o:%.S
	$(CC) -o $@ -c $< -DDEBUG

$(C_OBJS):%.o:%.c
	$(CC) -o $@ -c $<


flash: $(BIN)
	rm -rf $(FLASH)
	dd if=/dev/zero of=$(FLASH) bs=16M count=1
	dd if=$< of=$(FLASH) conv=notrunc

run: flash
	qemu-system-aarch64 -machine virt,secure=on -cpu cortex-a53 -bios flash.bin -m 1024 -nographic 

clean:
	rm -rf $(AS_OBJS) $(ELF) $(BIN) $(C_OBJS)

.PHONY: flash run clean

在这里插入图片描述

测试

$ make flash
aarch64-linux-gnu-gcc -o reset.o -c reset.S -DDEBUG
aarch64-linux-gnu-gcc -o test.o -c test.c
aarch64-linux-gnu-gcc -o uart.o -c uart.c
aarch64-linux-gnu-ld -T main.ld.S reset.o test.o uart.o -o test.elf -N
aarch64-linux-gnu-objcopy -O binary test.elf test.bin
rm -rf flash.bin
dd if=/dev/zero of=flash.bin bs=16M count=1
1+0 records in
1+0 records out
16777216 bytes (17 MB, 16 MiB) copied, 0.0141096 s, 1.2 GB/s
dd if=test.bin of=flash.bin conv=notrunc
1+1 records in
1+1 records out
560 bytes copied, 0.000171749 s, 3.3 MB/s

在这里插入图片描述

相关推荐

  1. armv8-a 介绍

    2024-02-11 18:48:01       30 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-11 18:48:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-11 18:48:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-11 18:48:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-11 18:48:01       20 阅读

热门阅读

  1. Qt 实现无边框窗口1.0

    2024-02-11 18:48:01       27 阅读
  2. 面试高频知识点:2线程 2.1.6线程之间如何通信

    2024-02-11 18:48:01       28 阅读
  3. 力扣94-二叉树的中序遍历

    2024-02-11 18:48:01       32 阅读
  4. 2.3 Binance_interface APP 现货行情-实时行情

    2024-02-11 18:48:01       31 阅读
  5. 1.1 Binance_interface安装与介绍

    2024-02-11 18:48:01       34 阅读
  6. 数据结构入门(2)时间复杂度与空间复杂度

    2024-02-11 18:48:01       30 阅读
  7. Leetcode 121 买卖股票的最佳时机

    2024-02-11 18:48:01       33 阅读
  8. 94 . 二叉树的中序遍历 -- 2024.2.10 LeetCode每日一题

    2024-02-11 18:48:01       39 阅读
  9. 完全背包总结二

    2024-02-11 18:48:01       30 阅读
  10. Elasticsearch中的模板:定义、作用与实践

    2024-02-11 18:48:01       35 阅读
  11. 计算机网络(第六版)复习提纲29

    2024-02-11 18:48:01       29 阅读