uboot之relocate代碼的深入理解
在讀linux0.11內(nèi)核時(shí),發(fā)現(xiàn)linus說的一句話,“要了解系統(tǒng)真正的運(yùn)行機(jī)制,一切盡在源代碼中”。
本文引用地址:http://cafeforensic.com/article/201611/323260.htm在讀眾多的關(guān)于uboot移植的文檔如,大家卻在說“第一階段~~~~第二階段~~~~~”,“ 這一段完成~~~~”卻很少見到講解過start_armboot()函數(shù)是怎么實(shí)現(xiàn)的,只是籠統(tǒng)的說完成神馬神馬的初始化~~
在今天之前看了那么多文檔,發(fā)現(xiàn)自己對(duì)uboot說的是頭頭是道,“第一階段~~第二階段~~”,然后移植到自己板子上,則是兩眼一摸黑,神馬都不知道~~~
然而就是今天,就在寫這篇文檔之前。我才發(fā)現(xiàn)了uboot真正的執(zhí)行與實(shí)現(xiàn)原理。而達(dá)到這一步的最初動(dòng)力就是:要看看uboot到底是怎么執(zhí)行的,而不光是知道它“應(yīng)該”是怎么執(zhí)行的和它的流程。在不懂得代碼操作過程而只知道執(zhí)行流程的時(shí)候,知道的執(zhí)行流程只能是浮云~~~而要根根據(jù)自己的板子實(shí)際的改動(dòng)uboot中的代碼那就更別談了。于是,深入到uboot的代碼中去,盡管有些代碼很難懂,盡管有些函數(shù),宏定義根本不知道放在哪,但總是能找到的,總是能看懂的~只要方向正確,哪怕多走點(diǎn)路,也總能是到達(dá)目的地的~~
至此,才真正算是明白學(xué)習(xí)之道:多看,多想,多寫~~~
還是那句話:除了代碼,神馬都是浮云! 這兩天天氣突然轉(zhuǎn)冷,就剛才由大雪籽轉(zhuǎn)而飄起了大雪,手也開始不聽使喚的抖動(dòng)起來了。自己的對(duì)uboot的理解也逐漸深入了,下面就一段段的寫下,加深印象吧
這兩天天氣突然轉(zhuǎn)冷,就剛才由大雪籽轉(zhuǎn)而飄起了大雪,手也開始不聽使喚的抖動(dòng)起來了。自己的對(duì)uboot的理解也逐漸深入了,下面就一段段的寫下,加深印象吧
先貼上代碼吧:
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* dont reloc during debug */
beq stack_setup
最初看到這個(gè)代碼的時(shí)候,發(fā)現(xiàn)功能還是很簡單的,就是判斷uboot是放在哪里的,flash? or SDRAM?如果放在SDRAM中,就不需要再把uboot代碼從flash中搬移到SDRAM中,直接跳到stack_setup;如果是放在flash里的話,則要把代碼從flash中搬移到指定的SDRAM地址(TEXT_BASE)中。細(xì)看之下,又發(fā)現(xiàn)了點(diǎn)問題:它是怎么知道uboot到底放在哪呢;又要把uboot放到SDRAM的什么地址去呢,也即TEXT_BASE是多少。
先說TEXT_BASE吧。TEXT_BASE在功能上是指示uboot將要SDRAM中存放的起始地址。(理解這個(gè)很重要)在ubootcpus3c44b0start.S中有如下聲明和定義:_TEXT_BASE:。word TEXT_BASE 而在ubootoardB2config.mk文件中有如下賦值:TEXT_BASE = 0x0c100000。在基于daveB2板子的uboot是把uboot放在SDRAM中的0x0c100000處的。(個(gè)人暫時(shí)認(rèn)為這個(gè)TEXT_BASE應(yīng)該是可以修改的,比如TEXT_BASE=0x0c100004)再說這個(gè)_start:當(dāng)uboot在flash中運(yùn)行的時(shí)候,_start是程序的開始,也即地址0。而當(dāng)uboot在SDRAM的時(shí)候,這個(gè)_start應(yīng)該是多少呢??經(jīng)過反復(fù)想,反復(fù)想之后,才發(fā)現(xiàn),這個(gè)_start就應(yīng)該是TEXT_BASE。
由于_start是整個(gè)uboot的開頭處,所以_start在uboot中的偏移地址_start_offset=0,這個(gè)無疑義。當(dāng)uboot在flash中的時(shí)候,_start=0x00000000很好理解:flash映射起始地址為0x00000000。uboot放在flash當(dāng)中的話,uboot起始地址就應(yīng)該為0x00000000,而_start在uboot中的偏移地址為0,所以_start的絕對(duì)物理地址就應(yīng)該是0x00000000。當(dāng)uboot處于SDRAM中的時(shí)候,_start=??那么它為什么又會(huì)等于TEXT_BASE=0x0c1000000呢???原因就在于,我們要把(注意:是將要把,打算把)uboot搬到TEXT_BASE=0x0c100000(這個(gè)位置屬于SDRAM的映射)處。那么uboot的絕對(duì)地址就應(yīng)該是TEXT_BASE,而_start在uboot中的偏移地址是0,所以_start的絕對(duì)地址就是TEXT_BASE+0=TEXT_BASE。在ldr r1,_TEXT_BASE執(zhí)行之后,r1=TEXT_BASE的;而adr r0,_start執(zhí)行之后呢??adr指令是基于PC的相對(duì)尋址,執(zhí)行之后r0=PC+_star_offset=PC。如果uboot放在SDRAM中的話,那么_start的絕對(duì)地址是TEXT_BASE,也即PC=TEXT_BASE。
至此,才明白了是如何判斷是否要進(jìn)行代碼搬移的。
總結(jié):開始一直以為,uboot在SDRAM中的話,其開始地址應(yīng)該是SDRAM的映射開始地址,即0x0c000000,也即_start的絕對(duì)地址應(yīng)該是0x0c000000。后來才發(fā)現(xiàn),uboot放在SDRAM中的位置是由程序控制的,即放在TEXT_BASE處。這才明白上面那幾行代碼是怎么回事了~~~
話外音::突然間想到---TEXT_BASE是uboot在SDRAM的開始處,所以在SDRAM中的時(shí)候_start=TEXT_BASE。只有這樣才能判斷正確~~
評(píng)論