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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Tiny4412裸机程序之代码重定位初体验

發(fā)布時間:2023/12/14 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Tiny4412裸机程序之代码重定位初体验 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載:http://www.techbulo.com/1412.html

從前面一節(jié)Exynos 4412的啟動過程分析?,我們知道:一上電,exynos4412首先執(zhí)行固化在IROM中的代碼,iROM首先設(shè)置程序運(yùn)行環(huán)境 (比如關(guān)看門狗、關(guān)中斷、關(guān)MMU 、設(shè)置棧 、設(shè)置棧 、啟動PLL等 ),然后根據(jù)OM引腳確定啟動設(shè)備 (NAND Flash/SD 卡/其他 ),把 BL1從里面讀出存入iRAM的0x02021400地址處,最后啟動 BL1;?BL1從SD卡適當(dāng)?shù)奈恢米x入14K 字節(jié)的數(shù)據(jù),存在iRAM地址0x02023400處,所以BL2不能大于(14K – 4) 字節(jié),這里引出了為什么寫這一節(jié)的原因:如果我們的程序很大,大于14K怎么辦????

下面我們先來介紹兩個概念:

一是程序當(dāng)前所處的地址,即程序在運(yùn)行時,所處的當(dāng)前地址;二是程序的鏈接地址,即程序運(yùn)行時應(yīng)該位于的運(yùn)行地址。編譯程序時,可以指定程序的鏈接地址。

什么是重定位

對于Tiny4412而言,前面我們已經(jīng)說過:啟動時BL1只會從sd等啟動設(shè)備中拷貝14K的代碼到IRAM中,那么當(dāng)我們的程序超過14K怎么辦?那就需要我們在前14K的代碼中將整個程序完完整整地拷貝到DRAM等其他更大存儲空間,然后再跳轉(zhuǎn)到DRAM中繼續(xù)運(yùn)行我們的代碼,這個拷貝然后跳轉(zhuǎn)的過程就叫重定位。

本章中我們主要學(xué)習(xí)如何重定位,但是并不會涉如何使用到DRAM,而是簡單地將代碼從IRAM的0x02023400處拷貝到IRAM的0x0202a000處,然后跳轉(zhuǎn)到0x0202a000處繼續(xù)運(yùn)行我們的代碼。

?

一、程序說明

基于上一個實(shí)驗(yàn)的代碼進(jìn)行修改,修改了start,S文件以及鏈接腳本文件:

在start.S文件中增加如下代碼:

1234567891011121314151617181920212223242526272829//重定位 - 將代碼從0x02023400處拷貝到鏈接地址0x0202a000處(在鏈接腳本里指定的),并跳轉(zhuǎn)到這個地址去執(zhí)行adr r0, _start //adr指令用于讀取_start在當(dāng)前的運(yùn)行的物理地址,即0x02023400ldr r1, =_start //讀取_start的鏈接地址,即0x0202a000ldr r2, =bss_start // 讀取bss段的起始地址,用于計算需要拷貝的字節(jié)多少cmp r0, r1beq clean_bss //如果r0=r1,則跳轉(zhuǎn)到clean_bss,說明此時已經(jīng)在鏈接地址處了//如果r0!=r1,則進(jìn)行如下的拷貝copy_loop:ldr r3, [r0], #4 // 源str r3, [r1], #4 // 目的cmp r1, r2 // 判斷是否已經(jīng)拷貝完bne copy_loop // 如果沒有拷貝完就繼續(xù)拷貝// 清bss段clean_bss:ldr r0, =bss_start //r0保存bss段的起始地址ldr r1, =bss_end //r1保存bss段的起始地址cmp r0, r1beq run_on_dram //如果r0=r1,則跳轉(zhuǎn)到run_on_dram,說明bss段里邊沒有變量mov r2, #0clear_loop:str r2, [r0], #4cmp r0, r1bne clear_loop// 跳轉(zhuǎn)run_on_dram:ldr pc, =main //執(zhí)行完這句話之后,PC就指向了main的鏈接地址

這段代碼主要實(shí)現(xiàn)了代碼重定位、清除BSS段、以及跳轉(zhuǎn)到鏈接地址繼續(xù)運(yùn)行,注釋說的已經(jīng)很明白了,有什么的不熟悉的,大家可以留言共同探討。

鏈接腳本reload.lds修改為如下:

123456789101112131415SECTIONS {. = 0x0202a000;.text : {start.o* (.text)}.data : {* (.data)}bss_start = .;.bss : {* (.bss)}bss_end = .;}

主要增加了bss段的起始bss_start及結(jié)束bss_end 的定義,這兩個標(biāo)號在start.S中被用到。

二、編譯、燒寫、運(yùn)行

1.編譯

通過FTP或者其他工具將文件上傳到服務(wù)器上去,輸入make命令進(jìn)行編譯將得到reload.bin文件。

2.燒寫

將SD卡插入電腦,并讓VmWare里的Ubuntu識別出來,然后執(zhí)行如下命令:

1sudo ./sd_fusing.sh /dev/sdb ../8_reload/reload.bin

將SD卡插入Tiny4412開發(fā)板,上電,你會看到和上一節(jié)的運(yùn)行效果一樣(因?yàn)槲覀儧]有修改LED的顯示效果,只是修改了程序的運(yùn)行地址,這個對外是看不出區(qū)別的)。

三、反匯編文件分析

將反匯編文件reload.dis,從服務(wù)器上下載下來,我們進(jìn)行簡單分析一下:

反匯編文件1

從上圖可以看出,程序的鏈接地址確實(shí)是我們在連接腳本里指定的0x0202a000

反匯編文件2

我們再來看看跳轉(zhuǎn)的那條指令;

1202a064: e59ff01c ldr pc, [pc, #28] ; 202a088 <halt_loop+0x18>

將當(dāng)前PC的值加上28后的地址的內(nèi)容賦給PC,即:

0x202a064 + 8 + 28 = 0x202a088

將0x202a088這個地址的值賦給PC

反匯編文件3

即PC指向0x0202a22c這個地址,我們繼續(xù)往下看,發(fā)現(xiàn):

反匯編文件4

0x0202a22c這個地址正是main函數(shù)的入口地址。

?

上一張運(yùn)行的圖片:

運(yùn)行效果

?

完整的程序下載地址(解壓密碼:WWW.techbulo.Com):

下載地址

總結(jié)

以上是生活随笔為你收集整理的Tiny4412裸机程序之代码重定位初体验的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。