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驱动的初始化完成了。
阅读(1614) | 评论(1) | 转发(0) |