Issues with ARMv7-A bare metal call stack

299 views Asked by At

I'm trying to get a small ARM kernel up and running on QEMU (Versatile Express for Cortex-A15). Currently it simply sets sp to the top of a small stack and sends a single character to 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');
}

From GDB, I know that execution progresses through _start into start and successfully sends 'A' to UART_0. printChar gets called and completes, but doesn't seem to print anything to the serial port . When running without GDB, the kernel repeatedly prints 'A', though I'm not sure if this is the processor resetting or jumping incorrectly.

From 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

There are 1 answers

2
sid1138 On

I may have missed something, but I am not seeing where you have enabled interrupts, or poll to see if you can send the next character. If you have enabled the interrupts and set up the UART hardware correctly, your driver my have a bug. If you have not setup the UART hardware correctly, it may not be generating interrupts, or it may not be doing the FIFO correctly, or any number of other problems.