<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > uboot之relocate代碼的深入理解

          uboot之relocate代碼的深入理解

          作者: 時間:2016-11-29 來源:網絡 收藏
          在讀網絡原理時,發(fā)現Dave Clark說的一句話“我們拒絕國王,總統(tǒng)和選舉。我們信奉的是是大體的一致意見和正在執(zhí)行的代碼”

          在讀linux0.11內核時,發(fā)現linus說的一句話,“要了解系統(tǒng)真正的運行機制,一切盡在源代碼中”。

          本文引用地址:http://www.ex-cimer.com/article/201611/323260.htm

          在讀眾多的關于uboot移植的文檔如,大家卻在說“第一階段~~~~第二階段~~~~~”,“ 這一段完成~~~~”卻很少見到講解過start_armboot()函數是怎么實現的,只是籠統(tǒng)的說完成神馬神馬的初始化~~

          在今天之前看了那么多文檔,發(fā)現自己對uboot說的是頭頭是道,“第一階段~~第二階段~~”,然后移植到自己板子上,則是兩眼一摸黑,神馬都不知道~~~

          然而就是今天,就在寫這篇文檔之前。我才發(fā)現了uboot真正的執(zhí)行與實現原理。而達到這一步的最初動力就是:要看看uboot到底是怎么執(zhí)行的,而不光是知道它“應該”是怎么執(zhí)行的和它的流程。在不懂得代碼操作過程而只知道執(zhí)行流程的時候,知道的執(zhí)行流程只能是浮云~~~而要根根據自己的板子實際的改動uboot中的代碼那就更別談了。于是,深入到uboot的代碼中去,盡管有些代碼很難懂,盡管有些函數,宏定義根本不知道放在哪,但總是能找到的,總是能看懂的~只要方向正確,哪怕多走點路,也總能是到達目的地的~~

          至此,才真正算是明白學習之道:多看,多想,多寫~~~

          還是那句話:除了代碼,神馬都是浮云! 這兩天天氣突然轉冷,就剛才由大雪籽轉而飄起了大雪,手也開始不聽使喚的抖動起來了。自己的對uboot的理解也逐漸深入了,下面就一段段的寫下,加深印象吧

          這兩天天氣突然轉冷,就剛才由大雪籽轉而飄起了大雪,手也開始不聽使喚的抖動起來了。自己的對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

          最初看到這個代碼的時候,發(fā)現功能還是很簡單的,就是判斷uboot是放在哪里的,flash? or SDRAM?如果放在SDRAM中,就不需要再把uboot代碼從flash中搬移到SDRAM中,直接跳到stack_setup;如果是放在flash里的話,則要把代碼從flash中搬移到指定的SDRAM地址(TEXT_BASE)中。細看之下,又發(fā)現了點問題:它是怎么知道uboot到底放在哪呢;又要把uboot放到SDRAM的什么地址去呢,也即TEXT_BASE是多少。

          先說TEXT_BASE吧。TEXT_BASE在功能上是指示uboot將要SDRAM中存放的起始地址。(理解這個很重要)在ubootcpus3c44b0start.S中有如下聲明和定義:_TEXT_BASE:。word TEXT_BASE 而在ubootoardB2config.mk文件中有如下賦值:TEXT_BASE = 0x0c100000。在基于daveB2板子的uboot是把uboot放在SDRAM中的0x0c100000處的。(個人暫時認為這個TEXT_BASE應該是可以修改的,比如TEXT_BASE=0x0c100004)再說這個_start:當uboot在flash中運行的時候,_start是程序的開始,也即地址0。而當uboot在SDRAM的時候,這個_start應該是多少呢??經過反復想,反復想之后,才發(fā)現,這個_start就應該是TEXT_BASE。

           由于_start是整個uboot的開頭處,所以_start在uboot中的偏移地址_start_offset=0,這個無疑義。當uboot在flash中的時候,_start=0x00000000很好理解:flash映射起始地址為0x00000000。uboot放在flash當中的話,uboot起始地址就應該為0x00000000,而_start在uboot中的偏移地址為0,所以_start的絕對物理地址就應該是0x00000000。當uboot處于SDRAM中的時候,_start=??那么它為什么又會等于TEXT_BASE=0x0c1000000呢???原因就在于,我們要把(注意:是將要把,打算把)uboot搬到TEXT_BASE=0x0c100000(這個位置屬于SDRAM的映射)處。那么uboot的絕對地址就應該是TEXT_BASE,而_start在uboot中的偏移地址是0,所以_start的絕對地址就是TEXT_BASE+0=TEXT_BASE。在ldr r1,_TEXT_BASE執(zhí)行之后,r1=TEXT_BASE的;而adr r0,_start執(zhí)行之后呢??adr指令是基于PC的相對尋址,執(zhí)行之后r0=PC+_star_offset=PC。如果uboot放在SDRAM中的話,那么_start的絕對地址是TEXT_BASE,也即PC=TEXT_BASE。

           至此,才明白了是如何判斷是否要進行代碼搬移的。

          總結:開始一直以為,uboot在SDRAM中的話,其開始地址應該是SDRAM的映射開始地址,即0x0c000000,也即_start的絕對地址應該是0x0c000000。后來才發(fā)現,uboot放在SDRAM中的位置是由程序控制的,即放在TEXT_BASE處。這才明白上面那幾行代碼是怎么回事了~~~

           話外音::突然間想到---TEXT_BASE是uboot在SDRAM的開始處,所以在SDRAM中的時候_start=TEXT_BASE。只有這樣才能判斷正確~~



          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();