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

时间:2015-06-15 15:27:12

标签: c assembly arm bare-metal

我试图在QEMU上运行一个小型ARM内核(Versatile Express for Cortex-A15)。目前,它只是将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

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                                ....

1 个答案:

答案 0 :(得分:0)

我可能错过了一些东西,但我没有看到你在哪里启用了中断,或者查看是否可以发送下一个字符。如果您已启用中断并正确设置UART硬件,那么您的驱动程序我有一个错误。如果您没有正确设置UART硬件,它可能不会产生中断,或者它可能没有正确地执行FIFO或任何其他问题。