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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

16.U-boot的工作流程分析-2440

發布時間:2023/11/30 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 16.U-boot的工作流程分析-2440 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

16.U-boot的工作流程分析-2440

分析的流程:

  • 程序入口
  • 第一階段程序分析
  • 第二階段程序分析
  • 2440開發板:

    1.uboot的入口:

    要看uboot工程的入口,首先打開頂層目錄的Makefile:

    Uboot所支持的開發板,在頂層的Makefile中都會有一個配置選項。比如2440,在Makefile中的配置選項是smdk2440_config:在vim的命令模式按下/,然后輸入smdk6410_config回車會定位到這里:

    這是Makefile里的一個目標。這是來配置2440開發板的。看到上圖第二行的smdk2440,這個參數決定了開發板的名稱。這個名稱是有作用的。接下來看看他的作用。

    首先是找一下目錄:

    可以看到這里有很多smdk的子目錄,也包括smdk2440,這兩個是對應的。該目錄存放的就是2440開發板相關的文件。里面有一個叫uboot.lds的文件,前面知道lds文件是連接器腳本。Uboot的整個過程的鏈接,是通過該腳本來鏈接控制的。打開該鏈接器腳本:

    OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

    OUTPUT_ARCH(arm)

    ENTRY(_start)

    SECTIONS

    {

    ????. = 0x00000000;

    ????. = ALIGN(4);

    ????.text :

    ????{

    ???? cpu/s3c24xx/start.o????(.text) //1可以看到位于代碼段前端的文件是start.o,對應的是一個匯編文件。這個匯編文件會最先被運行。但是這個匯編代碼里最先執行的代碼是哪些呢?

    ???? cpu/s3c24xx/s3c2440/cpu_init.o????(.text)

    ???? *(.text)

    ????}

    ????. = ALIGN(4);

    ????.rodata : { *(.rodata) }

    ????. = ALIGN(4);

    ????.data : { *(.data) }

    ????. = ALIGN(4);

    ????.got : { *(.got) }

    ?

    ????. = .;

    ????__u_boot_cmd_start = .;

    ????.u_boot_cmd : { *(.u_boot_cmd) }

    ????__u_boot_cmd_end = .;

    ?

    ????. = ALIGN(4);

    ????.mmudata : { *(.mmudata) }

    ?

    ????. = ALIGN(4);

    ????__bss_start = .;

    ????.bss : { *(.bss) }

    ????_end = .;

    }

    首先是找到該文件:

    上面u-boot-lds文件里,在sections的標識之上,有一行:ENTRY(_start)是整個程序的入口。所以就找找start.S文件里有沒_start這個標識呢?一搜會馬上看到該標號:

    到這里,看到這個_start才是整個uboot工程的入口。

    ?

    接下來是第一階段的代碼:

    在Linux里,打開上一節創建好的,Source Insight里的uboot工程:

    然后找到smdk2440的start.S:

    接下來看uboot做了什么事,主要是通過注釋來分析:

    開發板一上電,它會跳轉到start.S的中斷向量表的開始處執行:

    從它的注釋:

    所以1,:知道上電后是跳到中斷向量表來執行。執行的第一條指令是b start_code。

    Start_code的實在start.S的下面定義的:

    從注釋知道,這是actual start code。進入之后,set the cpu to svc32 mode,設置cpu為SVC模式。

    接著執行的代碼是:

    3.刷新I/D caches。

    4.然后是關閉MMU和cache:

    后加

    關閉系統時鐘,在lowlevel _init函數里bl system_clock_init函數。進入該函數:

    可以看到2440是在初始化系統時鐘里關閉看門狗。

    下面還有屏蔽中斷的操作:

    ?

    后加

    5.接著是運行的是一個函數:看看是定義在那個文件的。

    點擊:,然后在Symbol里輸入:lowlevel_init:

    會看到出現很多,然后在下面可以看到它們各自的目錄。其實每一個開發板都對應一個lowlevel_init.S:

    進入該文件:

    5看到系統進入該文件做的第一件事是:初始化系統時鐘:

    6.接著初始化串口:

    7.對nand進行簡單初始化:

    8.接下來的代碼很重要:

    由前面的學習知道,當我們開發一個uboot在開發階段,就是在調試uboot的時候,不用燒到NandFlash去運行,可以下載到內存里面去調試運行。這時候就不需要代碼搬移bl0,bl1,bl2的過程。就不需要進行拷貝工作了。所以上面的代碼就是判斷,判斷uboot代碼是在內存運行,還是在NandFlash運行。如果沒有運行在內存當中,就是從NandFlash啟動。就需要對內存進行初始化,就是跳轉到mem_con_init處執行,進行內存初始化。執行完內存初始化之后就要返回了。

    返回到:

    接著往下執行:

    9.判斷是NandFlash啟動還是Nor Flash啟動:

    如果是NandFlash啟動這是執行下面的:把代碼從NandFlash拷貝到內存去。

    NorFlash這執行下面,把代碼從NorFlash拷貝到內存。

    這里講NandFlash啟動,所以跳轉到nand_copy:

    ?

    10,接著是設置堆棧:

    ?

    11.接著清除BSS段:

    ?

    到這里第二階段的代碼就執行完了。

    三:

    執行完上面,程序跳轉到_start_armboot處執行:

    上面的代碼,通過偽指令ldr把_start_armboot的值裝入pc指針,程序就會跳轉到_start_armboot處執行。而此處的地址是start_armboot的地址。就是,程序會跳轉到start_armboot函數處執行。就是把我們的pc指針跳轉到內存去執行了

    下面看看start_armboot的地址是不是在內存中。

    配置uboot:make smdk2440_config,然后執行make。

    然后看到生成的文件:

    ?

    其中,u-boot是elf文件,u-boot.bin是二進制文件。

    接下來對u-boot的elf文件,進行反匯編,看看start_armboot函數的地址:

    arm-linux-objdump -D -S u-boot >dump

    查看:

    看到函數的其實地址30009100的地址是在內存里的。所以start.S里的:

    實現了從墊腳石跳轉到內存。但是,此時會發現在這里的起始地址被變為了30008000:

    在第一階段里,不是說啟動地址是在0嗎?為什么這里是30008000呢?還有就是為什么是這個地址。

    ?

    前面的學習知道,當去鏈接一個程序的時候,程序由多個文件構成,起始地址是由鏈接器腳本決定的。在/home/samba/uboot/Uboot/2440/uboot/board/samsung/smdk2440里的u-boot.lds:

    起始地址是0:

    這里是0,為什么那里會是30008000呢?我們回到uboot的頂層目錄,打開config.mk:

    搜索text_base:

    找到:

    在這里-T $(LDSCRIPT)就是定義使用鏈接器腳本。后面的-Ttext 是制定代碼段的基地址的。$(TEXT_BASE)。這里有兩個起始地址,然而程序運行的時候以后面的TEXT_BASE的地址為準。它會覆蓋掉LDSCRIPT這個地址。

    ?

    TEXT_BASE是在board/Samsung/smdk2440/config.mk里定義的。最后一行:

    ?

    接下來就是測試驗證一下,把他修改為30005000。然后程序編譯:

    Make smdk2440_config->make:

    反匯編:

    arm-linux-objdump -D -S u-boot >dump

    上面的起始地址變了,剛才制定的。

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    ?

    那起始地址為什么不是0呢?下圖:

    從上圖可以看到,ldr PC,=start_armboot的跳轉,把地址從墊腳石跳轉到內存里。在前面的代碼里,有用到b reset等跳轉指令,為什么這不會跳轉到內存去執行,而是還在墊腳石里呢?

    例如:

    上面的跳轉,bl lowlevel_init的跳轉地址:

    為什么PC指針還是在墊腳石中呢?

    ?

    這就得講兩個詞了。絕對跳轉和相對跳轉

    B和bl是相對跳轉。

    ?

    ?

    ?

    ?

    ?

    Ldr偽指令是絕對跳轉:

    ?

    第三階段:

    是從此函數Start_armboot進入的。主要完成的硬件和軟件的初始化,只是一些基礎的初始化。

    該函數里有一個for循環:

    在for里首先是讓一個指針數組,把里面的函數指針依次調用一次,if里的判斷語句就是函數指針。那么指針數組里有哪些函數指針呢。

    ?

    指針數組:

    可以看到里面都是函數指針。這里軟件的初始化就不看了,我們只看硬件的初始化。在這些函數指針里,硬件初始化的有串口初始化。Serial_init。接著是lcd的初始化:

    初始化網卡:

    初始化led:

    接著進入一個主循環:

    執行用戶輸入的命令。例如tftp命令。這里是一個死循環。老是等待執行用戶繼續輸入命令。在第一個階段,每個開發板可能有不同的地方,但是在這個地方都是一樣的。就是,在第二階段都是跳到start_armboot處執行代碼。2440的第一階段是在start.S的b reset開始。

    轉載于:https://www.cnblogs.com/FORFISH/p/5188716.html

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的16.U-boot的工作流程分析-2440的全部內容,希望文章能夠幫你解決所遇到的問題。

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