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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

U-Boot 启动过程笔记

發布時間:2023/12/31 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 U-Boot 启动过程笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
[1] 規則 目標: 依賴 [TAB]命令(命令名 參數 依賴 目標) [2] 難點 1. 自動變量 作用域在當前規則中, Make給它自動賦值 $@ ? 目標 注意: 每一條規則只有一個目標 test test.o: test.c [TAB]$(CC) $(CFLAGS) $< -o $@ 等價于 test: test.c [TAB]$(CC) $(CFLAGS) $< -o $@ test.o: test.c [TAB]$(CC) $(CFLAGS) $< -o $@ $< ? 第一個依賴 $^ ? 所有依賴 2. 模式規則 目標和依賴使用%匹配符的規則 %.o: %.c [TAB]$(CC) $(CFLAGS) $< -o $@ 3. 自動推倒(自動找規則生成目標) (1) 尋找生成目標的顯示規則(自己寫的非模式規則) (2) 尋找生成目標的模式規則 (3) 尋找生成目標的隱式規則(make程序默認的模式規則) [3] ARM工程 1. 目錄 board ? ? ? ? ? 跟主板相關的配置文件和源代碼(主板的初始化代碼) common ? ? ? ? ?主程序 cpu ? ? ? ? ? ? cpu的啟動代碼 drivers ? ? ? ? 通用設備驅動 include ? ? ? ? 頭文件 lib ? ? ? ? ? ? 庫(通用算法)的源代碼 2. 源文件 *.S ? ? ? ? ? ? 匯編源碼 *.c ? ? ? ? ? ? C源碼 *.h ? ? ? ? ? ? 頭文件 config.mk ? ? ? 編譯命令和編譯參數 Makefile ? ? ? ?make腳本 map.lds ? ? ? ? 鏈接腳本 3. 編譯 $ make 4. 目標文件 fs4412.bin ? ? ?binary格式的可執行文件 fs4412 ? ? ? ? ?ELF格式的可執行文件 fs4412.dis ? ? ?反匯編文件 fs4412.map ? ? ?詳細符合表文件(鏈接過程文件) System.map ? ? ?符合表文件 5. 編譯原理 1. 主Makefile OBJS ? ? ? ? 啟動代碼編譯出來的目標文件(*.o) LIBS ? ? ? ? 非啟動代碼編譯出來的靜態庫(lib*.a)(多個目標文件的打包) 2. 子Makefile LIB ? ? ? ? ?子目錄下的源代碼編譯出來的目標文件,打包成的靜態庫文件 START ? ? ? ?啟動代碼編譯出來的目標文件 SOBJS ? ? ? ?匯編代碼編譯出來的目標文件 COBJS ? ? ? ?C代碼編譯出來的目標文件 6. 如何添加模塊到工程? 1. 添加源代碼 2. 添加子目錄 3. 添加源代碼到子目錄 4. 給子目錄添加Makefile 拷貝別的子目錄下的Makefile,修改如下變量的值: LIB ? ? ? ? ?子目錄下的源代碼編譯出來的目標文件,打包成的靜態庫文件 START ? ? ? ?啟動代碼編譯出來的目標文件 SOBJS ? ? ? ?匯編代碼編譯出來的目標文件 COBJS ? ? ? ?C代碼編譯出來的目標文件 5. 修改頂層目錄下的Makefile, 添加新的子目錄生成的目標到工程: OBJS ? ? ? ? 啟動代碼編譯出來的目標文件(*.o) LIBS ? ? ? ? 非啟動代碼編譯出來的靜態庫(lib*.a)(多個目標文件的打包) [4] u-boot工程 1. 目錄 cpu(cpu/cpu名稱(arm_cortexa8)/...) ? ? ? ? ? ? ? ?CPU的啟動代碼 board(board/芯片廠家(samsung)/主板名(fsc100)/... ?啟動代碼中需要使用的核心硬件的驅動(內存初始化、flash的讀驅動、soc中部分硬件的初始化) common ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?主程序和命令實現代碼 lib_arm(lib_generic) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?某個架構的CPU需要使用的公共代碼(校驗算法CRC 壓縮算法 標準C庫) net ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 網絡協議代碼 drivers ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 通用設備驅動 fs ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?文件系統實現代碼 disk ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?磁盤分區驅動 tools ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 工具 doc ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 文檔(作者寫的) 2. 源文件 Makefile ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?make腳本文件 config.mk ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 編譯命令和編譯參數 README ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?整個工程的說明 mkconfig ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?工程配置的shell腳本 rules.mk ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?產生Makefile規則(hello.o: hello.c hello.h stdio.h) 3. 特點 1. 支持多個CPU 2. 支持多個主板 3. 支持非常多的設備驅動 4. 工程管理和代碼比較混亂 任何一款產品,都不可能用到u-boot提供的所有代碼, 所以編譯過程應該分成: 1. 選擇需要的源代碼--配置 2. 編譯需要的源代碼--編譯 4. 編譯 1. 配置 $ make fsc100(主板名)_config 2. 編譯 $ make 3. 清除編譯 $ make clean 4. 清除配置 $ make clobber 5. 目標文件 u-boot ? ? ? ? ? ? ? ? ?ELF格式的可執行程序 u-boot.bin ? ? ? ? ? ? ?binary格式的可執行程序 u-boot.map ? ? ? ? ? ? ?詳細符號表(有鏈接過程) System.map ? ? ? ? ? ? ?符號表文件 6. 配置原理 1. 過程 《u-boot配置流程圖.bmp》 注意:2010版本的u-boot沒有boards.cfg 2. 結果 include/config.mk ? ? ? ? ? ? ? ? ? ? ? ? ?選擇源代碼目錄 include/config.h ? ? ? ? ? ? ? ? ? ? ? ? ? 選取目錄下的源代碼文件和從選取的源代碼文件中選取一部分源代碼 ? ? ? ? ? ? #include <configs/fsc100.h> ? ? ? ? ? ? 主板的配置文件(通過宏定義配置) #include <config_cmd_default.h> ? ? ?通過里面的宏定義控制命令是否編譯到最終的u-boot可執行文件 (config_cmd_all.h) ? ? ? ? ? ? ? ? ? u-boot支持的所有命令的配置項(宏定義) 3. 原理 ? 1. $ make fsc100_config命令的實現原理 根據配置命令($ make fsc100_config),來看主Makefile,即在主Makefile中尋找目標為fsc100_config規則: ? ? ? ? ? ? ?SRCTREE ? ? := $(CURDIR) ? ? ? ? ? ? ?... ? ? ? ? ? ? ?MKCONFIG ? ?:= $(SRCTREE)/mkconfig ? ? ? ? ? ? ?... ? ? ? ? ? ? ?fsc100_config: ?unconfig ? ? ? ? ? ? ?[tab]@$(MKCONFIG) $(@:_config=) arm arm_cortexa8 fsc100 samsung s5pc1xx ? ? ? ? ? ? ? ? ? ?mkconfig ?fsc100 arm arm_cortexa8 fsc100 samsung s5pc1xx 2. 選擇目錄 include include/config.mk (.... CPU = arm-cortex_a8(目錄名) ) .... LIBS += cpu/$(CPU)/lib$(CPU).a ? ? ? ? ? ?選擇arm-cortex_a8 cpu目錄

3. 選擇目錄中的源代碼文件 例: 在include/configs/fsc100.h定義: #define ? CONFIG_DRIVER_DM9000 1 ? ? ?如果宏定義不存在, 就不會被轉換成相應的Makefile變量
在make時, 它會被轉換成Makefile變量,存放在include/autoconf.mk中: CONFIG_DRIVER_DM9000 = y
在主Makefile中,會包含include/autoconf.mk,因此在子Makefile中也可以見到CONFIG_DRIVER_DM9000變量
在driver/net/Makefile中,會按照如下方式使用: LIB = libnet.a ... ... COBJS-$(CONFIG_DRIVER_DM9000) += dm9000x.o ... ... COBJS = $(COBJS-y) ... OBJS = $(COBJS) ... $(LIB): .depend $(OBJS) [TAB]$(AR) $(ARFLAGS) $@ $(OBJS)

4. 選取文件中的部分源碼(條件編譯) 例: 在include/configs/fsc100.h頭文件中,存在如下宏定義: #define CONFIG_CMD_PING 1 ? ? ? ?(注意: 命令配置項最好放入include/config_cmd_default.h)
在common/cmd_net.c文件中,存在如下代碼: #if defined(CONFIG_CMD_PING) ...(ping命令實現代碼) #endif

5. 給源代碼提供數據(宏替換) 例: 在include/configs/fsc100.h頭文件中,存在如下宏定義: #define CONFIG_DM9000_BASE 0X88000000
在driver/net/dm9000x.c文件中會使用這個宏定義: ... dm9000_probe(void) { ... printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE, id_val); ... } ...

7. 編譯原理 1. 總體編譯過程 見《u-boot編譯過程圖2013.01.bmp》 2. 頂層目錄下的Makefile OBJS ? ? ? ? ? ?啟動代碼編譯出來的目標文件 LIBS ? ? ? ? ? ?非啟動代碼編譯出來的目標文件 3. 子目錄下的Makefile LIB ? ? ? ? ? ? 最終生成的lib*.a文件(只有非啟動代碼會被打包到這個文件) COBJS ? ? ? ? ? *.C編譯出來的目標文件 SOBJS ? ? ? ? ? *.S編譯出來的目標文件 8. 如何添加模塊到工程? # 包含編譯命令和編譯參數 include $(TOPDIR)/config.mk
# 總目標(非啟動代碼) LIB := $(obj)libuart.a
# COBJS-$(CONFIG_USB_TTY) += usbtty.o
# C語言源代碼編譯出來的目標文件 COBJS := uart.o ?#$(sort $(COBJS-y))
# 匯編代碼編譯出來的目標文件 #SOBJS := ...
# 源代碼文件,用在rules.mk中 SRCS := $(COBJS:.o=.c)
# 等價于COBJS OBJS := $(addprefix $(obj),$(COBJS)) # $(addprefix $(obj),$(SOBJS))
# 防止LIB變量中有多個目標 all: $(LIB)
# 將目標文件打包成靜態庫 $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS)
#########################################################################
# 產生.depend文件 # defines $(obj).depend target include $(SRCTREE)/rules.mk
# 包含.depend文件(*.o : *.c *.h 規則) sinclude $(obj).depend
######################################################################### 1. 添加源代碼 2. 添加子目錄 3. 添加源代碼到子目錄 4. 給子目錄添加Makefile 拷貝別的子目錄下的Makefile,修改如下變量的值: LIB ? ? ? ? ?子目錄下的源代碼編譯出來的目標文件,打包成的靜態庫文件 START ? ? ? ?啟動代碼編譯出來的目標文件 SOBJS ? ? ? ?匯編代碼編譯出來的目標文件 COBJS ? ? ? ?C代碼編譯出來的目標文件 5. 修改頂層目錄下的Makefile, 添加新的子目錄生成的目標到工程: OBJS ? ? ? ? 啟動代碼編譯出來的目標文件(*.o) 注意: 有些版本,不支持將啟動代碼放置的cpu以外目錄,這時需要修改如下規則: $(OBJS): depend # $(MAKE) -C cpu/$(CPU) $(if $(REMOTE_BUILD),$@,$(notdir $@)) $(MAKE) -C $(dir $(subst $(obj),,$@)) $(if $(REMOTE_BUILD),$@,$(notdir $@)) # $(dir $(subst $(obj),,$@)) $(dir A) ? ? ? ? ? ? ? ? ? ?求A的路徑,如: A是"drivers/uart/uart.o" 路徑為"drivers/uart" $(subst $(obj),,$@) ? ? ? ? obj指定目標代碼的路徑(當源代碼和目標代碼不放在同一目錄時) 將@中的每個值的$(obj)部分,替換成空 # $(if $(REMOTE_BUILD),$@,$(notdir $@)) 當REMOTE_BUILD變量值非空時,整個函數的值為@變量的值 .... ? ? ? ? ? ? ? ? 空時, ? ? ? ? ? ? ? $(notdir $@)的結果 LIBS ? ? ? ? 非啟動代碼編譯出來的靜態庫(lib*.a)(多個目標文件的打包) 注意: 1. 如何控制源代碼文件是否編譯到u-boot? 2. 如何空源代碼文件的一部分編譯到u-boot? 3. 如何為源代碼文件提供數據? 開關或數據都必須在include/configs/主板名.h 9. 源代碼閱讀軟件 vi(編輯或查看) + ctags(搜索定義) 1. 建立ctags索引文件 $ ctags -R ? ? (在工程的頂層目錄下執行) 2. 查找定義 把光標移動到要查找定義的標識符,然后按ctrl + ] 3. 回退 ctrl + O sourceinside 先建立工程, 添加所有文件到工程 10. 源代碼分析 1. 自啟動 1.1 核心硬件(初始化或驅動) 1.1.1 CPU(A8) 異常中斷向量表(包含配置異常中斷向量表的位置) cpu/arm-cortex_A8 35 - 56行 (ALU + 控制器)傳統的CPU ? ? 關閉中斷, 進入SVC模式 cpu/arm-cortex_A8 106 - 109行 MMU 和 cache ? ? ? ? ? ? ? ?關閉? ? ? ? ? ? ? ? ?? cpu/arm_cortexa8/start.S 227 ? ? /* 228 ? ? ?* 關閉tlb和icache 229 ? ? ?*/ 230 ? ? mov r0, #0 ? ? ? ? ?@ set up for MCR 231 ? ? mcr p15, 0, r0, c8, c7, 0 ? @ invalidate TLBs 232 ? ? mcr p15, 0, r0, c7, c5, 0 ? @ invalidate icache 233 234 ? ? /* 235 ? ? ?* 關閉mmu和cache 236 ? ? ?*/ 237 ? ? mrc p15, 0, r0, c1, c0, 0 238 ? ? bic r0, r0, #0x00002000 @ clear bits 13 (--V-) 239 ? ? bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM) 240 ? ? orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align 241 ? ? orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB 242 ? ? mcr p15, 0, r0, c1, c0, 0 1.1.2 SOC 如果有看門狗 ? ? ? ? ? ? ? ?關閉或喂狗 board/samsung/fsc100/lowlevel_init.S 57 ? ? /* 關閉看門狗 */ 58 ? ? ldr r0, =S5PC100_WATCHDOG_BASE ? ? ?@0xEA200000 59 ? ? orr r0, r0, #0x0 60 ? ? str r5, [r0]

如果需要加快代碼的執行速度 ?初始化PLL board/samsung/fsc100/lowlevel_init.S 96 ? ? bl ?system_clock_init
UART ? ? ? ? ? ? ? ? ? ? ? ?初始化(驅動)發送即可 board/samsung/fsc100/lowlevel_init.S 101 ? ? bl ?uart_asm_init
如果需要用到DMA ? ? ? ? ? ? 初始化(驅動)DMA board/samsung/fsc100/lowlevel_init.S 104 ? ? bl ?dma_init
如果從Nandflash啟動 ? ? ? ? 初始化nandflash控制器管腳 board/samsung/fsc100/lowlevel_init.S ? 106 ? ? bl ?nand_pin_mux 108 ? ? bl ?nand_asm_init
1.1.3 BOARD 初始化DDR board/samsung/fsc100/lowlevel_init.S ? 118 ? ? bl ?mem_ctrl_asm_init
如果從Nandflash啟動 ? ? ? ? 驅動nandflash的讀 cpu/arm_cortexa8/start.S 158 ldr sp, =(0x22000000) 159 bl copy_uboot_to_ram
1.2 軟件(創建C語言執行環境) 1.2.1 自拷貝到DDR cpu/arm_cortexa8/start.S 158 ldr sp, =(0x22000000) 159 bl copy_uboot_to_ram
1.2.2 棧內存分配(需要給SVC、abort、undefined instruction 三個模式分配棧空間) 1.2.3 .BSS段清空 1.2.4 跳轉到內存運行 1.2.5 預留內存給malloc函數 1.2.6 預留內存給全局數據結構 2. 命令執行 2.1 接收命令輸入 2.2 解析命令 2.3 執行命令 協議棧(網絡協議棧(net)/USB協議棧(drivers/usb)/...) 文件系統(fs) 分區驅動(disk) 硬件驅動(drivers)
3. OS啟動(bootm) 建立linux系統的啟動環境: 3.1 關閉中斷, 進入SVC 3.2 關閉MMU和cache 3.3 R0 ? ? ? ? ? 0 R1 ? ? ? ? ? arch number(mach type id) 主板id R2 ? ? ? ? ? 內核參數指針(atags list) 3.4 傳參給內核 3.5 跳轉到內核的運行地址去啟動

總結

以上是生活随笔為你收集整理的U-Boot 启动过程笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

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