當前位置:首頁 » 操作系統 » uboot源碼分析

uboot源碼分析

發布時間: 2022-05-09 21:47:35

『壹』 在uboot源碼中 CONFIG_NAND_U_BOOT = y是什麼意思

uboot的編譯控制,具體要看代碼才行,字面上面的意思是Nand命令有關。

『貳』 ARM匯編中的ldr和adr的區別及其在uboot中相關源碼的分析

ARM匯編有ldr指令以及ldr、adr偽指令,它們都可以將標號表達式作為操作數,下面通過分析一段代碼以及對應的反匯編結果來說明它們的區別。
ldr r0, _start
adr r0, _start
ldr r0, =_start
_start:
b _start
編譯的時候設置 RO 為 0x30000000,下面是反匯編的結果:
0x00000000: e59f0004 ldr r0, [pc, #4] ; 0xc
0x00000004: e28f0000 add r0, pc, #0 ; 0x0
0x00000008: e59f0000 ldr r0, [pc, #0] ; 0x10
0x0000000c: eafffffe b 0xc
0x00000010: 3000000c andcc r0, r0, ip
1.ldr r0, _start

這是一條指令,從內存地址 _start 的位置把值讀入。在這里_start是一個標號(是一個相對程序的表達式),匯編程序計算相對於 PC 的偏移量,並生成相對於 PC的前索引的指令:ldr r0, [pc, #4]。執行指令後,r0 =0xeafffffe。
ldr r0, _start是根據_start對當前PC的相對位置讀取其所在地址的值,因此可以在和_start標號的相對位置不變的情況下移動。
2.adr r0, _start

這是一條偽指令,總是會被匯編程序匯編為一個指令。匯編程序嘗試產生單個 ADD或 SUB 指令來裝載該地址。如果不能在一個指令中構造該地址,則生成一個錯誤,並且匯編失敗。在這里是取得標號_start 的地址到 r0,因為地址是相對程序的,因此ADR產生依賴於位置的代碼,在此例中被匯編成:add r0, pc, #0。因此該代碼可以在和標號相對位置不變的情況下移動;假如這段代碼在 0x30000000 運行,那麼 adr r0, _start 得到 r0 = 0x3000000c;如果在地址 0 運行,就是 0x0000000c 了。
通過這一點可以判斷程序在什麼地方運行。U-boot中那段relocate代碼就是通過adr實現當前程序是在RAM中還是flash中,下面進行簡要分析。

『叄』 從SD boot還需要注意什麼

從網上可以下載到IROM_Fusing_tools的源碼,在按下這個軟體的start控制項後,先是
讀取這個SD卡的第一個扇區,也就是這個磁碟的MBR 扇區,判斷是不是FAT32格式的
磁碟(這也是為什麼用來做啟動的SD必須格式化為FAT32格式),接著獲取總的扇區
數目TOTAl_SECOTR,並將所要燒寫的bin文件燒寫到磁碟的這個扇區:TOTAL_SECTOR –
2 - SIZE_OF_IMAGE/512。其中TOTAl_SECTOR是這個磁碟總的扇區數目;
SIZE_OF_IMAGE/512是這個bin文件將要佔據的扇區數(這里是以512為扇區大小的,
因此對於扇區更大的SD卡也就沒辦法使用了,而現在的大容量SD都可能使用了2K甚至
4K的扇區,除非修改這個程序,並同步地在uboot中修改程序);至於2則是保留的2
個扇區,至於為什麼要保留這2個扇區,需要分析uboot的源碼情況。

『肆』 source insight怎麼查看uboot代碼

對於嵌入式學習經常就要和Uboot和內核打交道,Source Insight便是我認為非常好的源碼查看工具。對於Uboot和內核源碼的查看,它有著非常好的索引方式,且擁有非常方便的快捷鍵操作方式。對於龐大的源碼樹最好就是建立一個工程來管理。但當你查找一個關鍵詞的時候,會出現許多與之相關的文件,不同的CPU和單板會有著同名的文件,很明顯並不是所有的文件都是我們需要查看的。那麼如何建立一個「節約」且合適的工程呢?在這里分享下我的經驗。
一、建立工程文件夾
最好建立一個自己的管理Source Insight所有工程文件夾(例如在D:\建立文件夾 D:\SourInProject),然後分別創建單獨的工程文件夾。在這里我們建的是Uboot-2010.03工程,那麼就建立一個文件夾名為:Uboot-2010.03Pro,在裡面放置Uboot-2010.03源碼包,和一個准備放置Source Insight所創建的Uboot-2010.03工程包SourInPro。這樣就很清晰,源碼和工程包單獨放在一個命名為Uboot-2010.03Pro下,即不同的工程都帶有一個源碼包和一個創建後的工程包。

二、如何創建工程
(1)、首先打開Source Insight軟體,配置好軟體所認識的文件後綴,點擊菜單欄上Options->Document Options,在Document Type下拉列表中,選擇C Source File,然後在右邊File filter:文本框中添加一些重要文件後綴;*.S;*.lds;*defconfig;Makefile等(否則點擊Add Tree添加目錄樹時,一些重要文件不被加入到工程,則要手動一個個加入,當然最簡單的辦法就是加個 ;*.* 就好)。然後再點擊菜單欄上的Project->New Project,在彈出的New Project對話窗口,New project name:(工程名)在這填Uboot-2010.03,Where do you want to store the project data files?(你想把你的工程文件存放在哪裡),在這我們填在上一步創建的D:\SourInProject\Uboot-2010.03Pro\SourInPro。然後一路OK,出現一個名為:Add and Remove Project Files對話框,下面我們就針對此對話窗口操作;

『伍』 uboot源碼怎麼查看nandflash分區表

你只能通過NandFlash控制器訪問NandFlash,即是只要知道Nand控制器的寄存器地址即可。NandFlash 不是一個RamLike的器件。Uboot放入nand中,在nand的0地址開始存放,移植時候需要注意頁對齊,這樣Uboot才可以可以通過StepingStone引導。

『陸』 關於C語言重復定義的問題-uboot

#include 相當於把.h文件的內容原樣放到.C文件相應的#include位置,
#define只在定義它的c文件中起作用
多個c文件可以使用#define定義相同名稱的宏,
但是,多個C文件定義相同名稱的全局變數的話,就會出問題了,全局變數在整個工程中起作用;也就是說:
a.c中定義了全局變數 int memory;
b.c中就不能定義全局變數 int memory;
同樣,你下面的做法是不行的
---------------------------------
//ss.h
#ifndef comand
#define comand 1
int memory;
#endif
--------------------------------
一般來講,.h文件中只能聲明變數,而不要定義變數,如果多個c文件公用一個變數的話,可以在其中一個c文件中定義該變數int memory;,並在頭文件中使用extern int memory;聲明該變數。

----------------------------------------------------------------------------------------------
#ifndef __COMMON_H_
#define __COMMON_H_ 1
這樣寫只是為了避免同一個c文件中多次引用同一個頭文件,
假設有個a.h文件中,#include了common.h
如果c文件同時#include "a.h" 和<common.h>的話,
#ifndef __COMMON_H_
#define __COMMON_H_ 1
就會起作用了

『柒』 android 源碼里有u-boot嗎

本人用的android平台用的bootloader用的是uboot,貌似大多數手持設備平台都不用這個,因為功能過於強大用不上,反而顯得太復雜了。不知道這個平台開發者是怎麼想的。既然用了那就來分析一下,順便修改一下其中的幾個小問題,以符合我們的要求。
uboot等同於其他所有的bootloader程序,從根本上講是一個稍復雜的裸機程序,是最底層的東西,要分析裸機程序我們要從它的連接文件開始。連 接文件(.lds文件)定義了程序編譯之後整個連接過程,這樣我們就可以找到這個程序的第一句匯編代碼,進而來下一步分析。uboot的鏈接文件代碼在 android\bootable\bootloader\uboot-imx\u-boot.lds
[cpp] view plain
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") //文件輸出格式
OUTPUT_ARCH(arm)
ENTRY(_start) //首地址標示符
SECTIONS
{
. = 0x00000000; //其實地址0
. = ALIGN(4); //4位元組對齊
.text : //代碼段
{
board/freescale/mx6q_sabresd/flash_header.o (.text.flasheader) //第一個文件是board/freescale/mx6q_sabresd/flash_header.o
cpu/arm_cortexa8/start.o //第二個cpu/arm_cortexa8/start.o
board/freescale/mx6q_sabresd/libmx6q_sabresd.a (.text)
lib_arm/libarm.a (.text)
net/libnet.a (.text)
drivers/mtd/libmtd.a (.text)
drivers/mmc/libmmc.a (.text)
. = DEFINED(env_offset) ? env_offset : .;
common/env_embedded.o(.text)
*(.text) //剩餘的所有代碼
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } //readonly data 段
. = ALIGN(4);
.data : { *(.data) } //所有的readonly data
. = ALIGN(4);
.got : { *(.got) }
. = .;
__u_boot_cmd_start = .; //u_boot_cmd段,裡面是所有uboot命令的一個列表
.u_boot_cmd : { *(.u_boot_cmd) }
__u_boot_cmd_end = .;
. = ALIGN(4);
_end_of_ = .;
__bss_start = .; //bss段 就是內存數據段
.bss : { *(.bss) }
_end = .;
}

從上面的代碼可以看出我們編譯生成的二進制應用程序組成是:代碼段->rodata段->uboot命令列表->bss段。我們啟動這個應用程序時候是從,0地址開始的,因此我們來看
board/freescale/mx6q_sabresd/flash_header.s這個文件。
這個文件中除了分配內存和宏定義的偽匯編指令以外,真正執行的命令有一條

[cpp] view plain
.section ".text.flasheader", "x"
b _start
.org CONFIG_FLASH_HEADER_OFFSET
也就是說,這個文件一執行就直接跳到_start 位置處。_start 在android\bootable\bootloader\uboot-imx\cpu\arm_cortexa8\ start.S中,因此我們來看這個文件代碼
[cpp] view plain
.globl _start
_start: b reset
這里直接跳轉的reset中接下來看
[csharp] view plain
reset:
/*
* set the cpu to SVC32 mode cpu設置成32位管理模式
*/
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr,r0

#if (CONFIG_OMAP34XX) //因為我們的cpu不是ompa的 所以這段不會編譯
.............................
#endif
/* the mask ROM code should have PLL and others stable */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
這里接下來執行cpu_init_crit
[csharp] view plain
/*************************************************************************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************************************/
cpu_init_crit:
/*
* Invalidate L1 I/D
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache

/*
* disable MMU stuff and caches //關閉mmu
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB
mcr p15, 0, r0, c1, c0, 0

/*
* Jump to board specific initialization...
* The Mask ROM will have already initialized
* basic memory. Go here to bump up clock rate and handle
* wake up conditions.
*/
mov ip, lr @ persevere link reg across call
bl lowlevel_init @ go setup pll,mux,memory//執行lowlevel_init這個函數代碼在
@\bootloader\uboot-imx\board\freescale\mx6q_sabresd\lowlevel_init.S中
@主要對時鍾,外部ram,rom等進行了初始化代碼不貼了。
mov lr, ip @ restore link
mov pc, lr @ back to my caller
初始化完成後,接下來執行
[csharp] view plain
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: @ relocate U-Boot to RAM 將uboot重新定位到內存中
adr r0, _start @ r0 <- current position of code
ldr r1, _TEXT_BASE @ test if we run from flash or RAM
cmp r0, r1 @ don't reloc ring debug測試當前代碼是否已經在內存中
beq stack_setup @如果在的話就直接跳轉到stack_setup

ldr r2, _armboot_start @如果不在的話,載入_armboot_start地址到r2中。_armboot_start是uboot執行的主體c函數。
ldr r3, _bss_start
sub r2, r3, r2 @ r2 <- size of armboot計算bss_start-armboot_start 保存到R2中,也就是uboot的總大小
add r2, r0, r2 @ r2 <- source end address 計算出uboot代碼和rodata地址

_loop: @ 32 bytes at a time //開始拷貝
ldmia r0!, {r3 - r10} @ from source address [r0]
stmia r1!, {r3 - r10} @ to target address [r1]
cmp r0, r2 @ until source end addreee [r2]
ble _loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

『捌』 在mini2440中把uboot放到norflash,內核,根文件系統,應用程序放在nandflash,系統如何啟動

非常簡單,mini2440從Nor啟動後,CPU運行在0x00000000地址,這片地址實際對應NorFlash,因為NorFlash是一個Ramlike器件,所以讀取數據方法更內存一樣,在Uboot的啟動文件start.s中,有一個一段代碼實現NorFlash復制到SRAM的功能,復制代碼完成後,通過指令,使用CPU跳到內存執行。這時候,Uboot通過另外的代碼,實際是Nand subsystem部分,把kernel從Nand讀到內存上,再通過指令,然後CPU跳到Kernel入口地址執行。
一旦Kernel跑起來,Kernel通過Uboot傳遞CMDLINE就可發現到根文件系統的分區了。所以根文件再通過一些列復雜的機制,最終把文件系統掛入系統中。
要完全了解這個過程,必須要完完整整地把Uboot和Kernel移植一遍才知道。
最後補充一下,mini2440上使用Uboot、supervivi,vivi之類的Bootloader實際功能都差不多。

熱點內容
pod內部修改配置如何生效 發布:2024-10-08 20:25:33 瀏覽:234
重慶伺服器託管市場低價雲主機 發布:2024-10-08 20:23:39 瀏覽:361
運維接觸源碼 發布:2024-10-08 19:55:44 瀏覽:485
python怎麼輸出換行 發布:2024-10-08 19:42:19 瀏覽:416
dhcp伺服器源碼 發布:2024-10-08 19:42:07 瀏覽:737
Sql88 發布:2024-10-08 19:01:55 瀏覽:969
汽車參數配置怎麼看乾式離合 發布:2024-10-08 18:57:47 瀏覽:796
編譯器設計圖 發布:2024-10-08 18:53:36 瀏覽:189
x7買哪個配置的比較好 發布:2024-10-08 18:48:25 瀏覽:772
android區域網視頻 發布:2024-10-08 18:35:29 瀏覽:695