日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

    歡迎訪問 生活随笔!

    生活随笔

    當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

    编程问答

    Tiny6410之重定位代码到SRAM+4096

    發布時間:2023/12/14 编程问答 55 豆豆
    生活随笔 收集整理的這篇文章主要介紹了 Tiny6410之重定位代码到SRAM+4096 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

    重定位代碼
      兩個不同的地址概念:
      對于程序而言,需要理解兩個地址,一個是程序當前所處的地址,即程序運行時所處的當前地址。二是程序應該位于的運行地址,即編譯程序時所指定的程序的鏈接地址。在Tiny6410中板子上電啟動時只會從NAND Flash/MMC等啟動設備中拷貝前8K的代碼到SRAM中,然后跳轉到SRAM中運行代碼。那么問題就來了,如果我們的程序超過8K會出現什么問題呢?程序拷貝不完整運行當然出錯。所以就需要我們在前8K的代碼中實現將整個程序完整的拷貝到DRAM等其他更大的存儲空間,然后在跳轉到DRAM中運行我們的程序。這個拷貝然后跳轉的過程就叫重定位。前幾次的實驗都是直接將.bin文件下載到DRAM中運行所以不需要重定位,而這一次,將通過NAND啟動然后通過重定位的方式來運行程序。

    第一步:編寫連接腳本
      鏈接腳本就是程序鏈接的參考文件其主要目的是描述如何把輸入文件中的段(SECTION)映射到輸出文件中,并控制輸出文件的存儲布局鏈接腳本的基本命令是SECTION命令,一個SECTION命令包含一個或多個段,段(SECTION)是鏈接腳本的基本單元,他表示輸入文件中每個段是、如何防止的。

      1)鏈接腳本中單獨的(.)代表當前位置 .=0x1000;表示代碼的運行地址是0x1000;
      2)link.dls中的.text/.data/.bss分別是text段,data段和bss段。.text段包含的是start.o和其他代碼中的所有text段,.data段包含的是其他代碼中的所有.data段,.bss段包含的是其他代碼中的所有.bss段
      3)bss_start和bss_end分別保存bss斷的的起始和結束地址,在start.S 中將會用到。

    data段:
      數據段(data segment)通常是指用來存放程序中已初始化的全局變量的一塊內存區域。數據段屬于靜態內存分配。

    text段:
      代碼段(code segment/text segment)通常是用來存放程序執行代碼的的一塊內存區域,這部分的內存大小在程序運行前就已經確定并且內存區域通常屬于只讀,某些架構也代碼段為可寫。,即允許修改程序。在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。

    bss段:
      BSS段(bss segment)通常是指用來存放程序中未初始化的全局變量的一塊內存區域。BSS是英文Block Started by Symbol的簡稱。BSS段屬于靜態內存分配。

    堆(heap):

      堆是用于存放進程運行中被動態分配的內存段,它的大小并不固定,可動態擴張或縮減。當進程調用malloc等函數分配內存時,新分配的內存就被動態添加到堆上(堆被擴張);當利用free等函數釋放內存時,被釋放的內存從堆中被剔除(堆被縮減)

    棧(stack):

      棧又稱堆棧, 是用戶存放程序臨時創建的局部變量,也就是說我們函數括弧“{}”中定義的變量(但不包括static聲明的變量,static意味著在數據段中存放變量)。除此以外,在函數被調用時,其參數也會被壓入發起調用的進程棧中,并且待到調用結束后,函數的返回值也會被存放回棧中。由于棧的先進后出特點,所以棧特別方便用來保存/恢復調用現場。從這個意義上講,我們可以把堆棧看成一個寄存、交換臨時數據的內存區。它是由操作系統分配的,內存的申請與回收都由OS管理。

    第二步:編寫代碼
      該章節的代碼與前幾次的大同小異,主要區別在start.S link.lds 和Makefile
    start.S存在四個需要注意的地方
      1)設置SP
        將棧頂sp 指向8*1024 Nand Flash 啟動時Tiny6410的內部8K的SRAM被映射到0x0而ARM默認的棧是遞減的,所以可以將SP指向881024
      2)增加重定位代碼
        首先獲取_start標號的當前地址(即0x0)然后取_start的鏈接地址(即0x100)因為bin文件不需要保存bss段,所以拷貝長度為bss_start的地址減去_start的地址。
      3)清bss段
        首先獲取bss_start的鏈接地址,然后獲取bss_end 的鏈接地址,然后將該部分的內存清零。bss_start和bss_end的地址有Link.dls決定
      4)跳轉
        ldr pc ,=main
      由于ldr指令獲取的是main函數的連接誒地址,所以執行該句后程序就跳轉到0x1000+main函數的offset的地址處

    1 //start.S 2 // 啟動代碼 3 .global _start 4 5 _start: 6 7 // 把外設的基地址告訴CPU 8 ldr r0, =0x70000000 9 orr r0, r0, #0x13 10 mcr p15,0,r0,c15,c2,4 11 12 // 關看門狗 13 ldr r0, =0x7E004000 14 mov r1, #0 15 str r1, [r0] 16 17 // 設置棧 18 ldr sp, =8*1024 19 20 // 開啟icaches 21 #ifdef CONFIG_SYS_ICACHE_OFF 22 bic r0, r0, #0x00001000 @ clear bit 12 (I) I-cache 23 #else 24 orr r0, r0, #0x00001000 @ set bit 12 (I) I-cache 25 #endif 26 mcr p15, 0, r0, c1, c0, 0 27 28 // 設置時鐘 29 bl clock_init 30 31 //重定位 32 adr r0,_start //_start的當前地址 33 ldr r1, =_start //_start的連接地址 34 ldr r2, =bss_start 35 cmp r0,r1 36 beq clean_bss 37 //搬移代碼 38 copy_loop: 39 ldr r3,[r0],#4 40 str r3,[r1],#4 41 cmp r1,r2 42 bne copy_loop 43 44 //清bss段 45 clean_bss: 46 ldr r0, =bss_start 47 ldr r1, =bss_end 48 mov r2, #0 49 cmp r0, r1 50 beq on_addr 51 clean_loop: 52 str r2, [r0],#4 53 cmp r0, r1 54 bne clean_loop 55 on_addr: 56 ldr pc, =main 57 58 halt: 59 b halt 60 61 //Tiny6410Addr.h 62 #ifndef _Tiny6410Addr_H 63 #define _Tiny6410Addr_H 64 //GPK 65 #define GPKIO_BASE (0x7F008800) 66 #define rGPKCON0 (*((volatile unsigned long *)(GPKIO_BASE+0x00))) 67 #define rGPKDAT (*((volatile unsigned long *)(GPKIO_BASE+0x08))) 68 69 //CLOCK 70 #define APLL_LOCK (*((volatile unsigned long *)0x7E00F000)) 71 #define MPLL_LOCK (*((volatile unsigned long *)0x7E00F004)) 72 #define EPLL_LOCK (*((volatile unsigned long *)0x7E00F008)) 73 #define OTHERS (*((volatile unsigned long *)0x7e00f900)) 74 #define CLK_DIV0 (*((volatile unsigned long *)0x7E00F020)) 75 #define APLL_CON (*((volatile unsigned long *)0x7E00F00C)) 76 #define MPLL_CON (*((volatile unsigned long *)0x7E00F010)) 77 #define CLK_SRC (*((volatile unsigned long *)0x7E00F01C)) 78 79 80 81 //GPA /uart 82 #define ULCON0 (*((volatile unsigned long *)0x7F005000)) 83 #define UCON0 (*((volatile unsigned long *)0x7F005004)) 84 #define UFCON0 (*((volatile unsigned long *)0x7F005008)) 85 #define UMCON0 (*((volatile unsigned long *)0x7F00500C)) 86 #define UTRSTAT0 (*((volatile unsigned long *)0x7F005010)) 87 #define UFSTAT0 (*((volatile unsigned long *)0x7F005018)) 88 #define UTXH0 (*((volatile unsigned char *)0x7F005020)) 89 #define URXH0 (*((volatile unsigned char *)0x7F005024)) 90 #define UBRDIV0 (*((volatile unsigned short *)0x7F005028)) 91 #define UDIVSLOT0 (*((volatile unsigned short *)0x7F00502C)) 92 #define GPACON (*((volatile unsigned long *)0x7F008000)) 93 94 #endif 95 96 //main.c 97 98 #include "Tiny6410Addr.h" 99 #define GPK4_OUT (1<<4*4) 100 #define GPK5_OUT (1<<4*5) 101 #define GPK6_OUT (1<<4*6) 102 #define GPK7_OUT (1<<4*7) 103 //延時函數 104 void delay() 105 { 106 volatile int i = 0x10000; 107 while (i--); 108 } 109 110 int main() 111 { 112 unsigned int i = 0x10; 113 //將GPK4-7設置為輸出 114 rGPKCON0 = GPK4_OUT | GPK5_OUT |GPK6_OUT |GPK7_OUT; 115 //跑馬燈式 116 while (1) 117 { 118 rGPKDAT = i; 119 i++; 120 if(i == 0x100) 121 i=0x10; 122 delay(); 123 } 124 125 return 0; 126 } 127 128 //link.lds 129 SECTIONS 130 { 131 . =0x1000; 132 .text : 133 { 134 start.o 135 *(.text) 136 } 137 . = ALIGN(4); 138 .rodata : 139 { 140 * (.rodata) 141 } 142 . =ALIGN(4); 143 .data : 144 { 145 *(.data) 146 } 147 . = ALIGN(4); 148 bss_start =.; 149 .bss : 150 { 151 *(.bss) 152 *(.common) 153 } 154 bss_end =.; 155 156 } 157 //Makefile 158 link.bin: start.o main.o clock.o uart.o 159 arm-linux-ld -T link.lds -o link_elf $^ 160 arm-linux-objcopy -O binary -S link_elf link.bin 161 arm-linux-objdump -D -m arm link_elf > link.dis 162 163 %.o : %.S 164 arm-linux-gcc -g -c -O2 -o $@ $^ 165 166 %.o : %.c 167 arm-linux-gcc -g -c -O2 -o $@ $^ -fno-builtin 168 .PHONY :clean 169 clean: 170 rm *.o *.elf *.bin *.dis -f View Code

    ?

    轉載于:https://www.cnblogs.com/chenshikun/p/5840128.html

    總結

    以上是生活随笔為你收集整理的Tiny6410之重定位代码到SRAM+4096的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。