前面已經把定位的資料通重載入
lc0結構來載入到暫存器裡,已經具備了定位的條件。那麼核心進行重定位主要做些什麼事情呢?要了解整個過程,當然要學習編譯原理,因為進行重定位之後,主要是為了建立
c語言的執行環境的需求。由於
c語言是基於棧式的語言,又有全域性變數,說明記憶體結構至少有兩個,乙個是全域性資料區,乙個是棧。因此,重定位就是修改全域性資料區和棧的訪問。在全域性資料的記憶體的表達方式,
gcc是使用
got(
globaloffset table
)來組織的,所以需要修改
got表裡每一項的資料位址,才可以讓
c語言編譯出來的程式可以訪問到正確的位址。
由於棧的記憶體需要更新和寫入,所以需要棧指向的記憶體是可讀寫的。但
rom不具備隨機寫入的,所以需要棧重定位。
/** we're running at a different address. we need to fix
* up various pointers:
* r5 - zimage base address
* r6 - got start
* ip - got end
*/add r5,r5, r0
add r6,r6, r0
add ip,ip, r0
這段**就是重新計算
got的開始位置和結束位置。
#ifndefconfig_zboot_rom
/** if we're running fully pic === config_zboot_rom = n,
* we need to fix up pointers into the bss region.
* r2 - bss start
* r3 - bss end
* sp - stack pointer
*/add r2,r2, r0
add r3,r3, r0
add sp,sp, r0
這段**是主要重定位堆和棧的位置。
/** relocate all entries in the got table.
*/1: ldr r1,[r6, #0] @ relocate entries in the got
add r1,r1, r0 @ table. this fixes up the
str r1,[r6], #4 @ c references.
cmp r6,ip
blo 1b
#else
/** relocate entries in the got table. we only relocate
* the entries that are outside the (relocated) bss region.
*/1: ldr r1,[r6, #0] @ relocate entries in the got
cmp r1,r2 @ entry < bss_start ||
cmphs r3,r1 @ _end < entry
addlo r1,r1, r0 @ table. this fixes up the
str r1,[r6], #4 @ c references.
cmp r6,ip
blo 1b
#endif
這段**主要就是重新計算got表裡每一項的資料項位址。
Android培訓班 95 核心解壓過程8
核心在上面處理完關閉中斷,並且確認進入系統模式後,就需要解決第乙個問題 解決自己到底在那裡執行的問題。這個問題,就好比乙個人在大海浬航行而沒有指南針,根本找不到北在那裡,急切地想知道方向在那裡。如果在白天還可以靠大陽就知道了方向,在晚上可以靠北斗星,在核心裡是否也有這樣的大自然的指示呢?在核心裡沒有...
Android培訓班 97 核心解壓過程10
經過上面開啟 mmu 之後,就進入了另乙個主要環節,就是把壓縮的核心 解壓出來,變換回原來可執行 的模樣,這樣才可以讓 cpu理解並執行相應的指令。由於載入壓縮的核心就占用了一定的記憶體空間,如果這個壓縮的核心比較大,而物理記憶體比較小,那麼解壓後的核心就會把未解壓部份的核心資料覆蓋,否則就可以採用...
Android培訓班 100 核心解壓過程13
有了檔案的格式,就可以按圖索驥,也就是根據檔案的格式來分析壓縮資料了。但檔案格式只是一種儲存的格式,還需要演算法才可以把資料解壓出來,下面就來理解gzip的壓縮演算法。gzip使用deflate的壓縮演算法來進行壓縮資料,這是一種無損的壓縮演算法,主要組合lz77和huffman的壓縮演算法。lz7...