ARM裸機全集擴充套件--SRAM內部重定位程式碼示例
注:此程式碼來自朱老師ARM裸機課程中,這裡貼出來方便檢視
Makefile
led.bin: start.o led.o
arm-linux-ld -Tlink.lds -o led.elf $^
arm-linux-objcopy -O binary led.elf led.bin
arm-linux-objdump -D led.elf > led_elf.dis
gcc mkv210_image.c -o mkx210
./mkx210 led.bin 210.bin
%.o : %.S
arm-linux-gcc -o $@ $< -c -nostdlib
%.o : %.c
arm-linux-gcc -o $@ $< -c -nostdlib
clean:
rm *.o *.elf *.bin *.dis mkx210 -f
link.lds
SECTIONS
{
. = 0xd0024000;
.text : {
start.o
* (.text)
}
.data : {
* (.data)
}
bss_start = .;
.bss : {
* (.bss)
}
bss_end = .;
}
start.S
/*
* 檔名: led.s
* 作者: 朱老師
* 描述: 演示重定位(在SRAM內部重定位)
*/
#define WTCON 0xE2700000
#define SVC_STACK 0xd0037d80
.global _start // 把_start連結屬性改為外部,這樣其他檔案就可以看見_start了
_start:
// 第1步:關看門狗(向WTCON的bit5寫入0即可)
ldr r0, =WTCON
ldr r1, =0x0
str r1, [r0]
// 第2步:設定SVC棧
ldr sp, =SVC_STACK
// 第3步:開/關icache
mrc p15,0,r0,c1,c0,0; // 讀出cp15的c1到r0中
//bic r0, r0, #(1<<12) // bit12 置0 關icache
orr r0, r0, #(1<<12) // bit12 置1 開icache
mcr p15,0,r0,c1,c0,0;
// 第4步:重定位
// adr指令用於載入_start當前執行地址
adr r0, _start // adr載入時就叫短載入
// ldr指令用於載入_start的連結地址:0xd0024000
ldr r1, =_start // ldr載入時如果目標暫存器是pc就叫長跳轉,如果目標暫存器是r1等就叫長載入
// bss段的起始地址
ldr r2, =bss_start // 就是我們重定位程式碼的結束地址,重定位只需重定位程式碼段和資料段即可
cmp r0, r1 // 比較_start的執行時地址和連結地址是否相等
beq clean_bss // 如果相等說明不需要重定位,所以跳過copy_loop,直接到clean_bss
// 如果不相等說明需要重定位,那麼直接執行下面的copy_loop進行重定位
// 重定位完成後繼續執行clean_bss。
// 用匯編來實現的一個while迴圈
copy_loop:
ldr r3, [r0], #4 // 源
str r3, [r1], #4 // 目的 這兩句程式碼就完成了4個位元組內容的拷貝
cmp r1, r2 // r1和r2都是用ldr載入的,都是連結地址,所以r1不斷+4總能等於r2
bne copy_loop
// 清bss段,其實就是在連結地址處把bss段全部清零
clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
cmp r0, r1 // 如果r0等於r1,說明bss段為空,直接下去
beq run_on_dram // 清除bss完之後的地址
mov r2, #0
clear_loop:
str r2, [r0], #4 // 先將r2中的值放入r0所指向的記憶體地址(r0中的值作為記憶體地址),
cmp r0, r1 // 然後r0 = r0 + 4
bne clear_loop
run_on_dram:
// 長跳轉到led_blink開始第二階段
ldr pc, =led_blink // ldr指令實現長跳轉
// 從這裡之後就可以開始呼叫C程式了
//bl led_blink // bl指令實現短跳轉
// 彙編最後的這個死迴圈不能丟
b .
相關文章
- SRAM的容量擴充套件套件
- 使用擴充套件SRAM設計的存內計算套件
- 重構 - 設計API的擴充套件機制API套件
- kotlin 擴充套件(擴充套件函式和擴充套件屬性)Kotlin套件函式
- django 2.0 擴充套件使用者欄位 示例Django套件
- php擴充套件手機號碼歸屬地PHP套件
- Spring容器擴充套件機制Spring套件
- MOSN 擴充套件機制解析套件
- chrome擴充套件程式開發Chrome套件
- 編寫可擴充套件程式套件
- Wise Menu for MacFinder擴充套件程式Mac套件
- 【Kotlin】擴充套件屬性、擴充套件函式Kotlin套件函式
- 聊聊Dubbo – Dubbo可擴充套件機制原始碼解析套件原始碼
- 「Android」分析EventBus原始碼擴充套件Weex事件機制Android原始碼套件事件
- 程式碼演示Mybatis-Generator 擴充套件自定義生成MyBatis套件
- 擴充套件01:程式碼風格/python規範style套件Python
- 重構聚合支付案例教你如何寫出高擴充套件性易讀的程式碼套件
- laradock 安裝擴充套件程式 pcntl套件
- [外掛擴充套件]返回頂部ReturnTop外掛套件
- 擴充套件推薦:laravel線上程式碼編輯器擴充套件包(純瀏覽器版的vscode)套件Laravel瀏覽器VSCode
- Django內建許可權擴充套件案例Django套件
- docker內給php安裝zmq擴充套件DockerPHPMQ套件
- 擴充套件工具套件
- Sanic 擴充套件套件
- Mybatis擴充套件MyBatis套件
- SpringMVC 擴充套件SpringMVC套件
- ORACLE 擴充套件Oracle套件
- Dubbo原始碼分析(一)Dubbo的擴充套件點機制原始碼套件
- testng擴充套件 失敗的用例重跑套件
- 重學ES6 陣列擴充套件(2)陣列套件
- Apollo 釋出 GraphQL 平臺和 VS 程式碼擴充套件套件
- 使用Kotlin擴充套件函式擴充套件Spring Data案例Kotlin套件函式Spring
- JMeter 擴充套件開發:擴充套件 TCP 取樣器JMeter套件TCP
- Spring系列-XML schema擴充套件機制SpringXML套件
- 聊聊spring的那些擴充套件機制Spring套件
- 1.2 - Laravel 5.6 - Extend 擴充套件機制Laravel套件
- Linux虛擬機器擴充套件磁碟Linux虛擬機套件
- shell擴充套件——免互動指令碼套件指令碼