u-boot代碼分析

1.命令nand read 執行流程分析
 common/main.c 中  main_loop()          主要執行read_line()讀取命令行
read_line()               調用common/main.c中  run_command()
run_command()    調用common/command.c中 find_cmd() .u_boot_cmd段中尋找該命令的cmd_tbl_t結構
     ( 命令的結構是通過定義在include/command.h中的宏定義U_BOOT_CMD登記進.u_boot_cmd段中的)

run_command()找到該命令的cmd_tbl_t結構後則執行該命令對應的函數.對於本情景是nand命令對應的函數do_nand()。
6.do_nand()有兩個版本,一個是定義了CFG_NAND_LEGACY。另一個是未定義CFG_NAND_LEGACY。這兩個版本都定義在 common/cmd_nand.c文件中。對於本情景使用未定義CFG_NAND_LEGACY的do_nand()函數。要使用do_nand()還 必須定義宏CONFIG_COMMANDS&CFG_CMD_NAND。(若未定義CFG_NAND_LEGACY則在這個情景中的 do_nand()函數調用的函數都定義在drivers/nand_legacy/nand_legacy.c文件中)。
7.對於我們的情景do_nand()會調用定義在include/nand.h文件中的nand_read()。
8.nand_read()則調用本nand芯片對應的nand_info_t結構的read指針。而read指針在nand_scan()中被指向了同文件(drivers/nand/nand_base.c)中的nand_read()函數。
9.nand_read()函數最終會調用nand_chip結構中的cmdfunc指針,通過這個指針指向的函數向nand flash芯片發送命令。最終完成整個命令的執行。


2.下面對nand flash的初始化代碼nand_init()進行分析:
1.如果定義(CONFIG_COMMANDS & CFG_CMD_NAND)沒定義(CFG_NAND_LEGACY) 則start_armboot()調用driver/nand/nand.c中的nand_init(),否則如果定義(CONFIG_COMMANDS & CFG_CMD_NAND)並且有定義了CFG_NAND_LEGACY,則調用自己定義的nand_init()。在我當前的情景中是使用 driver/nand/nand.c中的nand_init()。
2.nand_init()調用本文件中的nand_init_chip()對nand進行初始化。
3.nand_init_chip()首先調用board_nand_init()。
4.board_nand_init()是需要自己添加的函數,這個函數的主要功能是對struct nand_chip結構體的函數指針賦值,讓它們指向自己爲nand驅動編寫的一些函數,對未賦值的指針,uboot會在後面爲其賦上通用nand驅動函數指針。
5.nand_init_chip()接着調用nand_scan().
6.nand_scan()定義在drivers/nand/nand_base.c文件中。它首先對struct nand_chip結構體中在board_nand_init()函數中未賦值的指針賦上通用nand驅動函數指針。
7.通用nand驅動函數nand_select_chip()賦值給struct nand_chip結構體的函數指針用於打開或關閉nand芯片,0爲打開,1爲關閉。在這個函數中會調用nand_chip結構體中的 hwcontrol函數指針,這個指針指向的函數是需要自己編寫的。這個函數指針在board_nand_init()函數中被賦值。主要作用是向 nand flash發送一些nand flash開啓與關閉命令。
8.nand_scan()剩餘部分初始化nand_chip和mtd_info結構體。
9.nand_scan()最後在返回時調用drivers/nand/nand_bbt.c文件中的nand_default_bbt()。
10.nand_default_bby()選擇一個壞塊描述表,返回時調用本文件中的nand_scan_bbt()。
11.nand_scan_bbt()尋找建立一個壞塊描述表。
12.最後返回到nand_init(),這樣nand驅動的初始化完成了。
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章