之路(07"/>
XiaomiRouter自学之路(07
XiaomiRouter自学之路(07-U-boot启动过程)
U-boot的环境编译等都正常,后面需要修改U-boot的具体代码,如上面说的修改波特率等,在修改代码前,有必要了解U-boot的执行过程,这样我们就可以快速的定位到代码执行的大概位置,进行修改验证。
1.系统上电后由uboot的链接文件\board/rt2880/u-boot.lds知程序入口点是ENTRY(_start)。
2._start函数位于/cpu/ralink_soc/start.S中。
.globl _start.text
_start:RVECENT(reset,0) /* U-boot entry point */RVECENT(reset,1) /* software reboot */
3._start函数一直往下执行,会看到以下信息,即CPU频率源的选择,各变量的值即05-U-boot配置编译烧录里面提到的CPU PLL配置参数。
#if defined(CPLL_FROM_480MHZ)li a0, 1<<11
#elif defined(CPLL_FROM_XTAL)li a0, 1<<12
#elif defined(CPLL_FROM_CONF)li a0, CPLL_MULTI_RATIO_CFGsll a0, a0, 2ori a0, a0, CPLL_DIV_RATIO_CFGsll a0, a0, 6ori a0, a0, CPLL_SSC_CFG
#endif
#if (defined(CPLL_FROM_480MHZ)||defined(CPLL_FROM_XTAL)||defined(CPLL_FROM_CONF))bal init_cpu_pllnop
#elsela t0, RALINK_SYSCTL_BASE+0x10lw t1, 0(t0)srl t1, t1, 4andi t1, t1, 0x3beqz t1, CPLL_DONEaddiu t2, zero, 3beq t1, t2, CPLL_DONEli a0, CPLL_DEFAULT_CFGbal init_cpu_pllnop
#endif
CPLL_DONE:
4.时钟初始化后接着往下执行,就是DDR的初始化,再往下就可以看到如下语句
la t9, board_init_f
5.board_init_f是一个函数,位于/lib_mips/board.c中,截取部分代码如下:
...timer_init();env_init(); /* initialize environment */init_baudrate(); /* initialze baudrate settings */serial_init(); /* serial communications setup */console_init_f();display_banner(); /* say that we are here */checkboard();init_func_ram();led_init(); /* turn_on_led */gpio_init();
...
6.直接观察代码函数,可以很清楚其意思,但真正的执行过程等,可能需要后期再深入研究
7.board_init_f执行完,回到_start接着往后,又会看到如下语句
la t9, board_init_r
8.board_init_r也是位于/lib_mips/board.c中的一个函数
.../* Initialize devices */devices_init ();jumptable_init ();/* Initialize the console (after the relocation and devices init) */console_init_r ();
...
9.board_init_r函数往下执行可以看到如下信息,有一个DETECT_WPS()的检查,这其实是在开机时长按WPS按键4S以上,使之进入从web更新firware的一个功能,在后面会具体讲解这个功能。
...printf( "\nPress press WPS button for more than 2 seconds to run web failsafe mode\n\n" );printf( "WPS button is pressed for: %2d second(s)", counter );while( DETECT_WPS() ) {// LED ON and wait 0.2sLEDON();udelay( 200000 );// LED OFF and wait 0.8sLEDOFF();udelay( 800000 );counter++;// how long the WPS button is pressed?printf("\b\b\b\b\b\b\b\b\b\b\b\b%2d second(s)", counter);if ( !DETECT_WPS() ){break;}if ( counter >= 4 ){break;}}
...
10.board_init_r函数往下执行
...OperationSelect();while ( timer1 > 0 ) {--timer1;/* delay 100 * 10ms */for ( i=0; i<100; ++i ) {if ( ( my_tmp = tstc() ) != 0 ) { /* we got a key press */timer1 = 0; /* no more delay */BootType = getc();if ( ( BootType < '0' || BootType > '5' ) && ( BootType != '7' ) && ( BootType != '8' ) && ( BootType != '9' ) )BootType = '3';printf( "\n\rYou choosed %c\n\n", BootType );break;}udelay(10000);}printf ("\b\b\b%2d ", timer1);}
...
11.从上面的代码可以看出,该处就是u-boot倒计时的地方,timer1默认为5,倒计时为5s。在倒计时的过程获取键盘的字符,将输入的数值保存在BootType中,默认或输入其他字符则BootType=3。当BootType有值后,就对BootType的值进行判断处理,如下:
switch(BootType) {case '1':break;case '2':break;case '4':printf(" \n%d: System Enter Boot Command Line Interface.\n", SEL_ENTER_CLI);printf ("\n%s\n", version_string);/* main_loop() can return to retry autoboot, if so just run it again. */for (;;) {main_loop ();}break;...
12.对于每个数值的具体功能这边进行概念性介绍,更深入的实现代码将在下一章节进行说明,如下:
- 0: System Load Linux then write to Flash via Serial.
通过串口将系统更新到Flash. - 1: Load system code to SDRAM via TFTP.
通过TFTP将系统更新到SDRAM上. - 2:Load system code then write to Flash via TFTP. 通过TFTP将系统下载到SDRAM上,然后更新到Flash
- 3: Boot system code via Flash (default).
从Flash的特定位置读取系统然后启动 - 4: Entr boot command line interface.
进入命令行操作模式 - 7: Load Boot Loader code then write to Flash via Serial.
通过串口将u-boot下载到SDRAM上,然后更新到Flash - 8: System Load UBoot to SDRAM via TFTP.
通过TFTP将u-boot更新到SDRAM上. - 9: Load Boot Loader code then write to Flash via TFTP.
通过TFTP将u-boot下载到SDRAM上,然后更新到Flash
我们从_start开始粗略分析了U-boot的启动流程,这样在后面代码修改的过程中应该能直观些。
U-boot启动过程的分析就到这边,有感悟时会持续会更新。
注:以上内容都是本人在学习过程积累的一些心得,难免会有参考到其他文章的一些知识,如有侵权,请及时通知我,我将及时删除或标注内容出处,如有错误之处也请指出,进行探讨学习。文章只是起一个引导作用,详细的数据解析内容还请查看XiaomiRouter相关教程,感谢您的查阅。
更多推荐
XiaomiRouter自学之路(07
发布评论