c - ARMv7-A 裸机调用堆栈的问题

标签 c assembly arm bare-metal

<分区>

我正在尝试在 QEMU(适用于 Cortex-A15 的 Versatile Express)上启动并运行一个小型 ARM 内核。目前它只是将 sp 设置到一个小堆栈的顶部,然后将单个字符发送到 UART0。


_start.arm:

.set stack_size, 0x10000
.comm stack, stack_size

.global _start
_start:
    ldr sp, =stack+stack_size
    bl start
1:
    b 1b
.size _start, . - _start

开始.c:

/* UART_0 is a struct overlaid on 0x1c090000 */

void printChar(char c)
{
    while (UART_0->flags & TRANSMIT_FULL);
    UART_0->data = c;
}

void start()
{
    while (UART_0->flags & TRANSMIT_FULL);
    UART_0->data = 'A';

    printChar('a');
}

从 GDB,我知道执行通过 _start 进入 start 并成功将 'A' 发送到 UART_0。 printChar 被调用并完成,但似乎没有向串行端口打印任何内容。在没有 GDB 的情况下运行时,内核重复打印 'A',但我不确定这是处理器重置还是错误跳转。

来自 objdump:

Disassembly of section .stub:
00010000 <_start>:
   10000:   e59fd004    ldr sp, [pc, #4]    ; 1000c <__STACK_SIZE+0xc>
   10004:   eb000016    bl  10064 <start>
   10008:   eafffffe    b   10008 <_start+0x8>
   1000c:   000200d0    .word   0x000200d0

Disassembly of section .text:
00010010 <printChar>:
   10010:   e52db004    push    {fp}        ; (str fp, [sp, #-4]!)
   10014:   e28db000    add fp, sp, #0
   10018:   e24dd00c    sub sp, sp, #12
   1001c:   e1a03000    mov r3, r0
   10020:   e54b3005    strb    r3, [fp, #-5]
   10024:   e1a00000    nop         ; (mov r0, r0)
   10028:   e3a03000    mov r3, #0
   1002c:   e3413c09    movt    r3, #7177   ; 0x1c09
   10030:   e1d331ba    ldrh    r3, [r3, #26]
   10034:   e6ff3073    uxth    r3, r3
   10038:   e2033020    and r3, r3, #32
   1003c:   e3530000    cmp r3, #0
   10040:   1afffff8    bne 10028 <printChar+0x18>
   10044:   e3a03000    mov r3, #0
   10048:   e3413c09    movt    r3, #7177   ; 0x1c09
   1004c:   e55b2005    ldrb    r2, [fp, #-5]
   10050:   e6ff2072    uxth    r2, r2
   10054:   e1c320b2    strh    r2, [r3, #2]
   10058:   e24bd000    sub sp, fp, #0
   1005c:   e49db004    pop {fp}        ; (ldr fp, [sp], #4)
   10060:   e12fff1e    bx  lr

00010064 <start>:
   10064:   e52db008    str fp, [sp, #-8]!
   10068:   e58de004    str lr, [sp, #4]
   1006c:   e28db004    add fp, sp, #4
   10070:   e1a00000    nop         ; (mov r0, r0)
   10074:   e3a03000    mov r3, #0
   10078:   e3413c09    movt    r3, #7177   ; 0x1c09
   1007c:   e1d331ba    ldrh    r3, [r3, #26]
   10080:   e6ff3073    uxth    r3, r3
   10084:   e2033020    and r3, r3, #32
   10088:   e3530000    cmp r3, #0
   1008c:   1afffff8    bne 10074 <start+0x10>
   10090:   e3a03000    mov r3, #0
   10094:   e3413c09    movt    r3, #7177   ; 0x1c09
   10098:   e5d32002    ldrb    r2, [r3, #2]
   1009c:   e3a02000    mov r2, #0
   100a0:   e3822041    orr r2, r2, #65 ; 0x41
   100a4:   e5c32002    strb    r2, [r3, #2]
   100a8:   e5d32003    ldrb    r2, [r3, #3]
   100ac:   e3a02000    mov r2, #0
   100b0:   e5c32003    strb    r2, [r3, #3]
   100b4:   e3a00061    mov r0, #97 ; 0x61
   100b8:   ebffffd4    bl  10010 <printChar>
   100bc:   e24bd004    sub sp, fp, #4
   100c0:   e59db000    ldr fp, [sp]
   100c4:   e28dd004    add sp, sp, #4
   100c8:   e49df004    pop {pc}        ; (ldr pc, [sp], #4)

000100cc <UART_0>:
   100cc:   1c090000                                ....

最佳答案

我可能遗漏了什么,但我没有看到您在哪里启用了中断,也没有看到您是否可以发送下一个字符。如果您已启用中断并正确设置 UART 硬件,则您的驱动程序可能存在错误。如果您没有正确设置 UART 硬件,它可能不会生成中断,或者它可能没有正确执行 FIFO,或者任何其他问题。

关于c - ARMv7-A 裸机调用堆栈的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30849047/

相关文章:

android - 使用 ARM neon 将短数组转换为 float

C ABI 与 LLVM

c++ - gtk_text_buffer_create_tag 创建警告 : 'GtkTextTag' has no property named '\u0004'

c - 如何使用递归构建螺旋方阵?

c - 将参数传递给 execvp() 时出错

string - 子字符串搜索程序总是返回 false

C & 低级信号量实现

assembly - 如何从一个文件复制到另一个文件?

ARM拆卸

linux - arm和x86之间的迁移过程