下面是接著第二節往下的:
@ 對下面這些位址的理解其實還是很麻煩,但有篇文件寫得很清楚《about textaddr, ztextaddr,
@ page_offset etc...》。下面程式的意義就是保證解壓位址和當前程式的位址不重疊。上面分配了64kb的空間來做解壓時的資料快取。
cmp
r4, r2
bhswont_overwrite
addr0, r4, #4096*1024
@ 4mb largest kernel size
cmpr0, r5
blswont_overwrite
@ 如果空間不夠了,只好解壓到緩衝區位址後面。呼叫decompress_kernel進行解壓縮,這段**是用c實現的,和架構無關。
mov
r5, r2
@ decompress after malloc space
movr0, r5
movr3, r7 bl
decompress_kernel
@ decompress_kernel共有4個引數,解壓的核心位址、快取區首位址、快取區尾位址、和晶元id,返回解壓縮**的長度。注意r5會在其中改變的
ulgdecompress_kernel(ulg output_start, ulg free_mem_ptr_p, ulg free_mem_ptr_end_p,
int arch_id)
add
r0, r0, #127
bicr0, r0, #127
@ align the kernel length對齊核心長度
@ 完成了解壓縮之後,由於空間不夠,核心也沒有解壓到正確的位址,最後必須通過**搬移來搬到指定的位址0x30008000。搬運過程中有
@ 可能會覆蓋掉現在執行的這段**,所以必須將有可能會執行到的**搬運到安全的地方,
@ 這裡幫運到的位址是解壓縮了的**的後面r5+r0=0x3047d91c的位置。
addr1, r5, r0
@ end of decompressed kernel
adrr2, reloc_start
ldrr3, lc1
@ lc1:
.word
reloc_end - reloc_start 表示reloc_start段**的大小
addr3, r2, r3 1:
ldmia
r2!,
@ copy relocation code
stmia
r1!,
ldmia
r2!,
stmia
r1!,
cmpr2, r3
blo1b bl
cache_clean_flush
addpc, r5, r0
@ call relocation code
@ 在此處會呼叫重定位**reloc_start來將image 的**從緩衝區r5幫運到最終的目的地r4:0x30008000處
.align
5reloc_start:
addr9, r5, r0
debug_reloc_start
movr1, r4 1:
.rept
4ldmia
r5!,
@ relocate kernel
stmia
r1!,
.endr
cmpr5, r9
blo1b
debug_reloc_end
call_kernel:
blcache_clean_flush bl
cache_off
movr0, #0
@ must be zero
movr1, r7
@ restore architecture number
movr2, r8
@ restore atags pointer
@ 這個地方就是最終我們從zimage跳轉到image的偉大一跳了,跳之前準備好r0,r1,r2
movpc, r4
@ call kernel
arm linux 啟動流程分析
arm linux啟動總體過程 bootloader kernel rootfs.bootloader 一般的soc中一般會有一塊sdram 又叫墊腳石 當soc上電時,soc中固化的 會根據啟動方式從nand,emmc等不同儲存上,載入bootloader到sdram,進而執行。也就是說soc上電...
ARM Linux啟動流程分析
linux核心啟動分三個階段 1 解壓縮 2 檢查架構相關 3 start kernel c 語言環境 關於以下幾篇文章一些名詞 我的理解 1 鏈結位址 虛擬位址 這是乙個虛擬位址,對於32位cpu 虛擬位址空間的範圍 0 4g 通過arch arm kernel vmlinux.lds中開始部分就...
ARM Linux啟動過程分析
5 呼叫 linux核心映像 bootloader完成的最後一項工作便是呼叫 linux核心。如果 linux 核心存放在 flash 中,並且可直接在上面執行 這裡的 flash 指 nor flash 那麼可直接跳轉到核心中去執行。但由於在 flash 中執行 會有種種限制,而且速度也遠不及 r...