在start.S中,经过第一阶段的硬件初始化之后,进入到了u-boot的第二阶段,在这个阶段会对 串口、单板、中断、nand、nor等进行初始化,并设置内核需要的环境变量。
通过函数 start_armboot 进入第二阶段,下面箭头指的 init_sequence是一个函数数组,数组中的函数都是需要初始化的函数,init_fnc_ptr是一个函数指针,一个个执行init_sequence数组中的函数,进而实现初始化的任务。
下面进入init_sequence中
cpu_init是对cpu中的一些参数,点进去后设置的是 栈的空间;
board_init是对单板的初始化,比如设置GPIO口,设置机器ID,设置环境变量存放的位置0x30000100
interrupt_init是对中断的初始化
env_init是对环境变量的初始化
init_baudrate设置串口的波特率 115200
serial_init是对串口的初始化
dram_init是对SDRAM的初始化,设置SDRAM的地址和大小
下面是对其他部分的初始化
① 分配堆的空间
② nand flash的初始化
③ 环境变量的初始化
④ 设置网络地址
⑤ 控制台的设置
⑥ 初始化网卡
最后就是通过函数 main_loop 进入到main的主循环中
进入到 main_loop中后就会发现,很多命令都是对环境变量的处理
关键的函数就是 run_command() 函数
因此需要分析run_command()函数
在run_command()函数中
parse_line函数是对命令的解析,比如mw.d 0
argc = 2
argv[0] = "mw.d" argv[1] = "0"
解析完之后,就会根据argv[0]中的命令,按照查找名字的方式去找命令对应的函数
又,在执行时,都会键入 bootm xxx 命令启动内核,因此我们需要去分析一下bootm命令的作用是什么
这个是u-boot命令的格式,当键入bootm命令时,就会执行 do_bootm函数
将内核文件放入加载地址中
准备启动内核
theKernel指向内核的入口地址
启动内核,其中
bi_arch_number中存放的是机器ID
bi_boot_params中存放的是环境变量的地址,传递给内核
在环境变量中设置了 bootcmd=nand read.jffs2 0x30007FC0 kernel;bootm 0x30007FC0,意思是:
利用bootcmd命令先从nand flash 0x30007FC0中读取内核的位置,在这个地址中存放的是内核的头部uImage,它的大小是64KB,0x30007FC0 + 64 = 0x30008000