想要为 qemu 模拟器添加键盘输入。我有 UART 逻辑的 C 文件:
void uart_puts(const char *str);
void uart_putc(char c);
void notmain(void) {
volatile char *uart = (char *)0x1c090000; // UART базова адреса
char c;
uart_puts("UART test...\n");
while (1) {
c = *uart; // Читаємо символ з UART
if (c != 0) { // Перевіряємо, чи є дані
uart_putc(c); // Виводимо символ на екран
}
}
}
void uart_puts(const char *str) {
while (*str) {
uart_putc(*str++);
}
}
void uart_putc(char c) {
volatile char *uart = (char *)0x1c090000;
*uart = c; // Виведення символа в UART
}
这里的 .s 文件:
.globl _start
_start:
mov sp, #0x20000 // Встановлюємо стековий вказівник
bl notmain // Викликаємо C-функцію notmain
hang:
b hang // Безкінечний цикл
.globl PUT32
PUT32:
str w1, [x0] // Записуємо значення з регістра w1 в адресу, на яку вказує x0
ret // Повертаємося з функції
因此,在 C 代码中,当我从键盘上按下 btns 时,我编写了可视化符号的逻辑。我使用 aarch64-linux-gnu 来编译所有文件。编译asm文件的命令如下:
aarch64-linux-gnu-as --warn --fatal-warnings -march=armv8-a strap.s -o strap.o
这里编译C文件:
aarch64-linux-gnu-gcc -c -Wall -O2 -nostdlib -nostartfiles -ffreestanding -march=armv8-a notmain.c -o notmain.o
我还使用链接器链接所有文件,其代码是:
/*memmap*/
MEMORY
{
ram :ORIGIN = 0x10000, LENGTH = 32K
}
SECTIONS
{
.text : { *(.text*)} > ram
.bss : { *(.bss*)} > ram
}
以及链接命令:
aarch64-linux-gnu-ld strap.o notmain.o -T memmap -o notmain.elf
为了使用对象,我使用 objcopy 命令:
aarch64-linux-gnu-objcopy notmain.elf -O binary os.bin
当我想象时,当我按下按钮时,我没有在控制台中看到任何符号:
qemu-system-aarch64 -M virt -cpu cortex-a53 -m 128 -serial mon:stdio -kernel os.bin
我用的是WSL ubuntu系统
那么我需要解决什么:
您能否更新问题以澄清可视化“bin”文件的含义,该文件只是指令和数据的列表,没有任何结构?
我认为“回答”你的意思是回显你输入的键。
我无法确定您的情况是否特殊(并且 QEMU 确实出于某种原因将 UART 设备基地址放在那里),因为终端被部分遮挡(QEMU
-serial mon:stdio
标志将串行输出重定向到终端),所以我看不到是否 UART test...
是否正在打印(请更新屏幕截图,使其完全包含终端)
假设
0x1c090000
确实是错误的基地址,那么正确的 UART 基地址应该是 0x9000000
对于您的模拟板(QEMU 的虚拟板,我转储了设备树 blob 并在我的 QEMU 9.0.2 上搜索该地址)