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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

tiny4412 裸机程序 六、重定位代码到IRAM+0x8000【转】

發布時間:2023/12/14 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 tiny4412 裸机程序 六、重定位代码到IRAM+0x8000【转】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文轉載自:http://blog.csdn.net/eshing/article/details/37115697

一、重定向

對于程序而言,我們需要理解兩個概念,一是程序當前所處的地址,即程序在運行時,所處的當前地址;二是程序的鏈接地址,即程序運行時應該位于的運行地址。編譯程序時,可以指定程序的鏈接地址。對于Tiny4412而言,啟動時只會從MMC/sd等啟動設備中拷貝前16K的代碼到IRAM中,那么當我們的程序超過16K怎么辦?那就需要我們在前16K的代碼中將整個程序完完整整地拷貝到DRAM等其他更大存儲空間,然后再跳轉到DRAM中繼續運行我們的代碼,這個拷貝然后跳轉的過程就叫重定位。

本章中我們主要學習如何重定位,但是并不會涉如何使用到DRAM,而是簡單地將代碼從IRAM的0x02020010處拷貝到IRAM的0x02028000處,然后跳轉到0x02028000處繼續運行我們的代碼。

二、程序說明

完整代碼見目錄5_link_0x8000,該目錄下的代碼與上一章的代碼的差別在于start.S和使用了

鏈接腳本link.lds,我們首先分析link.lds。

1. link.lds

什么是鏈接腳本?鏈接腳本就是程序鏈接時的參考文件,其主要目的是描述如何把輸入文件中的段(SECTION)映射到輸出文件中,并控制輸出文件的存儲布局。鏈接腳本的基本命令式SECTIONS命令,一個SECTIONS命令內部包含一個或多個段,段(SECTION)是鏈接腳本的基本單元,它表示輸入文件中的某個段是如何放置的。

鏈接腳本的標準格式如下:

SECTIONS

{

sections-command

sections-command

}

下面我們配合link.lds進行具體講解:

SECTIONS

{

. = 0x02028000;

.text : {

start.o

* (.text)

}

.data : {

* (.data)

}

bss_start = .;

.bss : {

* (.bss)

}

bss_end = .;

}

1)? 在鏈接腳本中,單獨的點號(.)代表了當前位置,. =0x02028000;表示程序的鏈接地址是00x02028000;

2)? link.lds中的.text 、 .data 、 .bss分別是text段、data段、bss段的段名(這些段名并不是固定的,是可以隨便起的)。.text 段包含的內容是start.o 和其余代碼中所有的text段;.data段包含的內容是代碼中所有的data段;.bss段包含的內容是代碼中所有的bss段。

3)? bss_start和bss_end保存的是bss段的起始地址和結束地址,在start.S中會被用到。

下面解釋一下什么是data、text、bss段:

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

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

3)? bss段:指用來存放程序中未初始化的全局變量的一塊內存區域。BSS是英文BlockStarted by Symbol的簡稱。當我們的程序有全局變量是,它是放在bss段的,由于全局變量默認初始值都是0,所有我們需要手動清bss段。

2. start.S

在start.S中,我們初始化時鐘后,增加了3個步驟:

第一步重定位,代碼如下:

// _start當前所位于的地址

adr r0, _start??

// _start的鏈接地址

ldr r1, =_start??

ldr r2, =bss_start

cmp r0, r1

beq clean_bss

copy_loop:

ldr r3, [r0], #4

str r3, [r1], #4

cmp r1, r2

bne copy_loop

首先需要知道的是,adr指令獲取的值是代碼當前位于的地址,而ldr指令獲取的值是代碼的鏈接地址。再來看代碼,代碼里首先獲得_start標號的當前地址(即0x02020010),然后獲取_start標號的鏈接地址(即0x02028000),因為bin文件中不需要保存bss段,所有拷貝的代碼長度為bss_start的運行地址-_start的運行地址,使用copy_loop進行拷貝。

第二步清bss,代碼如下:

ldr r0, =bss_start????????

ldr r1, =bss_end

cmp r0, r1

beq run_on_dram

mov r2, #0

clear_loop:

str r2, [r0], #4

cmp r0, r1

bne clear_loop

首先獲得bss段的起始地址(即bss_start),然后獲得bss段的結束地址(即bss_end),最后使用clear_loop將bss段所位于的內存清0,bss_start和bss_end的定義位于link.lds。

第三步跳轉,代碼如下:

run_on_dram:???

ldr pc, =main

由于ldr 指令獲取的是main函數的鏈接地址,所以執行ldrpc, =main 后,程序就跳轉到

0x02020000+main函數的offset的地址處了。

三、完整的燒寫過程

已將SD卡插入電腦,假設Linux識別了SD卡,其識別號為sdb。執行下面命令:

# chmod 777 –R 5_link_0x8000

# cd 5_link_0x8000

# make

# cd sd_fuse

# make

# ./ fast_fuse /dev/sdb

四、上電實驗

將sd卡插入Tiny4412中,選擇sd卡啟動,然后上電,可以看到以下現象:

LED正常閃爍,該現象與前面章節的代碼的運行效果一模一樣,但是程序的運行過程卻有了很大的區別。通過本章的學習,我們已經知道了如何對代碼進行重定位,這為我們下一章節將代碼重定位到DRAM奠定了基礎。

備注:說明一下,代碼已上傳到我的資源里,我要了兩個下載分,不好意思,我的資源分太少了,我得賺點,我相信我的程序是絕對能運行的,覺得值就去下載。

0

總結

以上是生活随笔為你收集整理的tiny4412 裸机程序 六、重定位代码到IRAM+0x8000【转】的全部內容,希望文章能夠幫你解決所遇到的問題。

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