歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> 如何在ubuntu下開發ARM裸機程序

如何在ubuntu下開發ARM裸機程序

日期:2017/3/3 15:47:44   编辑:關於Linux

在本文中,我們使用匯編跳轉到C代碼,來實現點亮led,其中注意的一點是sp的設置,其他就比較簡單。

bootsect代碼如下:

@******************************************************************************  
@ File:bootsect.s  
@ 功能:  
@******************************************************************************  
.equ        WATCHDOGCON,    0x7e004000  
.equ        LEDCON,         0x7f008800  
.equ        LEDDAT,         0X7f008808  
      
.text  
.global _start  
_start:       
            bl      setup_peri_port  
            bl      disable_watch_dog  
            bl      setup_sp  
            bl      display_led  
      
            bl      main  
MAIN_LOOP:  
            b       MAIN_LOOP  
      
      
disable_watch_dog:  
            @往WATCHDOG寄存器寫0即可  
            ldr r0,=WATCHDOGCON  
            mov r1,#0x0  
            str r1,[r0]  
            mov pc,lr  
          
setup_sp:  
            ldr sp, =1024*8         @ 設置堆棧,注意:不能大於8k, 因為現在可用的內存只有8K  
                                    @ nand flash中的代碼在復位後會移到內部ram中,此ram只有8K  
            mov pc,lr  
      
setup_peri_port:  
            ldr r0,=0x70000013      @base addres:0x70000000,size:256MB  
            mcr p15,0,r0,c15,c2,4  
            mov pc,lr  
display_led:  
            ldr r0,=LEDCON          @ R0設為LEDCON,即GPKCON0寄存器。此寄存器  
                                    @ 用於選擇端口K各引腳的功能:  
                                    @ 是輸出、是輸入、還是其他  
            mov r1,#0x110000          
            str r1,[r0]             @ 設置GPK4,5為輸出口  
            ldr r0,=LEDDAT          @ R0設為GPKDAT寄存器。此寄存器  
                                     @ 用於讀/寫端口B各引腳的數據  
            mov r1,#0x00000000      @ 此值為0x000000,低電平點亮led  
            str r1,[r0]             @ GPK4,5輸出0,LED4,5點亮  
            mov pc,lr

main.c文件如下:

#define rGPKCON0        (*(volatile unsigned *)(0x7F008800))  
#define rGPKCON1        (*(volatile unsigned *)(0x7F008804))  
#define rGPKDAT         (*(volatile unsigned *)(0x7F008808))  
#define rGPKPUD         (*(volatile unsigned *)(0x7F00880C))  
      
void Port_Init(void)  
{  
    rGPKCON0 = (rGPKCON0 & ~(0xffffU<<16))|(0x1111U<<16);  
    rGPKPUD  = (rGPKPUD  & ~(0xffU << 8))|(0x00U<<8);  
}  
      
void Led_Display(int data)  
{  
    rGPKDAT = (rGPKDAT & ~(0xf<<4)) | ((data & 0xf)<<4);  
}  
      
static void LedDelay(void)  
{  
        volatile unsigned int k;  
        for(k = 0; k < 200000; k++);  
}  
int main()  
{  
    Port_Init();      
    for(;;) {  
        Led_Display(0x1); //  
    LedDelay();  
        Led_Display(0x2); //   
    LedDelay();  
    Led_Display(0x4); //   
    LedDelay();  
    Led_Display(0x8); //   
    LedDelay();  
    }  
      
    return 0;  
}

Makefile文件如下:

led_on_c.bin : bootsect.s  main.c  
    arm-linux-gcc -g -c -o bootsect.o bootsect.s  
    arm-linux-gcc -g -c -o main.o main.c  
    arm-linux-ld -Ttext 0x0000000 -g  bootsect.o main.o -o linux_kernel_elf  
    arm-linux-objcopy -O binary -S linux_kernel_elf linux_kernel.bin  
    arm-linux-objdump -D -b binary -m arm  linux_kernel.bin > linux_kernel.dis  
clean:  
    rm -f *.dis *.bin *elf *.o

本欄目更多精彩內容:http://www.bianceng.cn/OS/Linux/

Copyright © Linux教程網 All Rights Reserved