加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

uboot源码分析(4)

发布时间:2020-12-15 06:45:44 所属栏目:百科 来源:网络整理
导读:? main_loop()函数 main_loop()函数做的都是 与具体平台无关 的工作,主要包括初始化启动次数限制机制、设置软件版本号、打印启动信息、解析命令等。 (1) 设置启动次数有关参数。在进入main_loop()函数后,首先是根据配置加载已经保留的启动次数,并且根据
? main_loop()函数

main_loop()函数做的都是与具体平台无关的工作,主要包括初始化启动次数限制机制、设置软件版本号、打印启动信息、解析命令等。

(1)设置启动次数有关参数。在进入main_loop()函数后,首先是根据配置加载已经保留的启动次数,并且根据配置判断是否超过启动次数。代码如下:

  1. 295?void?main_loop?(void) ?
  2. 296?{ ?
  3. 297?#ifndef?CFG_HUSH_PARSER ?
  4. 298???static?char?lastcommand[CFG_CBSIZE]?=?{?0,?}; ?
  5. 299???int?len; ?
  6. 300???int?rc?=?1; ?
  7. 301???int?flag; ?
  8. 302?#endif ?
  9. 303???
  10. 304?#if?defined(CONFIG_BOOTDELAY)?&&?(CONFIG_BOOTDELAY?>=?0) ?
  11. 305???char?*s; ?
  12. 306???int?bootdelay; ?
  13. 307?#endif ?
  14. 308?#ifdef?CONFIG_PREBOOT??
  15. 309???char?*p; ?
  16. 310?#endif ?
  17. 311?#ifdef?CONFIG_BOOTCOUNT_LIMIT ?
  18. 312???unsigned?long?bootcount?=?0; ?
  19. 313???unsigned?long?bootlimit?=?0; ?
  20. 314???char?*bcs; ?
  21. 315???char?bcs_set[16]; ?
  22. 316?#endif? ?
  23. 317? ?
  24. 318?#if?defined(CONFIG_VFD)?&&?defined(VFD_TEST_LOGO) ?
  25. 319???ulong?bmp?=?0;???? ?
  26. 320???extern?int?trab_vfd?(ulong?bitmap); ?
  27. 321? ?
  28. 322?#ifdef?CONFIG_MODEM_SUPPORT ?
  29. 323???if?(do_mdm_init) ?
  30. 324?????bmp?=?1;?? ?
  31. 325?#endif ?
  32. 326???trab_vfd?(bmp); ?
  33. 327?#endif?? ?
  34. 328? ?
  35. 329?#ifdef?CONFIG_BOOTCOUNT_LIMIT ?
  36. 330???bootcount?=?bootcount_load();?????????//?加载保存的启动次数 ?
  37. 331???bootcount++;????????????????????????? //?启动次数加1 ?
  38. 332???bootcount_store?(bootcount);??????????//?更新启动次数 ?
  39. 333???sprintf?(bcs_set,?"%lu",?bootcount);??//?打印启动次数 ?
  40. 334???setenv?("bootcount",?bcs_set); ?
  41. 335???bcs?=?getenv?("bootlimit"); ?
  42. 336???bootlimit?=?bcs???simple_strtoul?(bcs,?NULL,?10)?:?0; ?
  43. ??????????????????????????????????????????? //?转换启动次数字符串为UINT类型 ?
  44. 337?#endif??

第329~337行是启动次数限制功能,启动次数限制可以被用户设置一个启动次数,然后保存在Flash存储器的特定位置,当到达启动次数后,U-Boot无法启动。该功能适合一些商业产品,通过配置不同的License限制用户重新启动系统。

?

(2)程序第339~348行是Modem功能。如果系统中有Modem,打开该功能可以接受其他用户通过电话网络的拨号请求。Modem功能通常供一些远程控制的系统使用,代码如下:

  1. 339?#ifdef?CONFIG_MODEM_SUPPORT ?
  2. 340???debug?("DEBUG:?main_loop:???do_mdm_init=%dn",?do_mdm_init); ?
  3. 341???if?(do_mdm_init)?{???????????????????????????//?判断是否需要初始化Modem ?
  4. 342?????char?*str?=?strdup(getenv("mdm_cmd"));?????//?获取Modem参数 ?
  5. 343?????setenv?("preboot",?str);? ?
  6. 344?????if?(str?!=?NULL) ?
  7. 345???????free?(str); ?
  8. 346?????mdm_init(); ? ?//?初始化Modem ?
  9. 347???} ?
  10. 348?#endif??

(3)接下来设置U-Boot的版本号初始化命令自动完成功能等。代码如下:

  1. 350?#ifdef?CONFIG_VERSION_VARIABLE ?
  2. 351???{ ?
  3. 352?????extern?char?version_string[]; ?
  4. 353? ?
  5. 354?????setenv?("ver",?version_string);??? ?
  6. ?????????????????????????????????????????????//?设置版本号 ?
  7. 355???} ?
  8. 356?#endif? ?
  9. 357? ?
  10. 358?#ifdef?CFG_HUSH_PARSER ?
  11. 359???u_boot_hush_start?();????????????????//?初始化Hash功能 ?
  12. 360?#endif ?
  13. 361? ?
  14. 362?#ifdef?CONFIG_AUTO_COMPLETE ?
  15. 363???install_auto_complete();??????????????//?初始化命令自动完成功能 ?
  16. 364?#endif ?
  17. 365? ?
  18. 366?#ifdef?CONFIG_PREBOOT ?
  19. 367???if?((p?=?getenv?("preboot"))?!=?NULL)?{ ?
  20. 368?#?ifdef?CONFIG_AUTOBOOT_KEYED ?
  21. 369?????int?prev?=?disable_ctrlc(1);???
  22. ??????????????????????????????????????????//?关闭Crtl+C组合键?
  23. 370?#?endif ?
  24. 371? ?
  25. 372?#?ifndef?CFG_HUSH_PARSER ?
  26. 373?????run_command?(p,?0);?//?运行Boot参数 ?
  27. 374?#?else ?
  28. 375?????parse_string_outer(p,?FLAG_PARSE_SEMICOLON?| ?
  29. 376?????????????FLAG_EXIT_FROM_LOOP); ?
  30. 377?#?endif ?
  31. 378? ?
  32. 379?#?ifdef?CONFIG_AUTOBOOT_KEYED ?
  33. 380?????disable_ctrlc(prev);?? ?
  34. ??????????????????????????????????????????//?恢复Ctrl+C组合键 ?
  35. 381?#?endif ?
  36. 382???} ?
  37. 383?#endif??

程序第350~356行是动态版本号功能支持代码,version_string变量是在其他文件定义的一个字符串变量,当用户改变U-Boot版本的时候会更新该变量。打开动态版本支持功能后,U-Boot在启动的时候会显示最新的版本号。

程序第363行设置命令行自动完成功能,该功能与Linux的shell类似,当用户输入一部分命令后,可以通过按下键盘上的Tab键补全命令的剩余部分

main_loop()函数不同的功能使用宏开关控制不仅能提高代码模块化,更主要的是针对嵌入式系统Flash存储器大小设计的。在嵌入式系统上,不同的系统Flash存储空间不同。对于一些Flash空间比较紧张的设备来说,通过宏开关关闭一些不是特别必要的功能如命令行自动完成,可以减小 U-Boot编译后的文件大小。

?

(4)在进入主循环之前,如果配置了启动延迟功能,需要等待用户从串口或者网络接口输入。如果用户按下任意键打断,启动流程,会向终端打印出一个启动菜单。代码如下:

  1. 385?#if?defined(CONFIG_BOOTDELAY)?&&?(CONFIG_BOOTDELAY?>=?0) ?
  2. 386???s?=?getenv?("bootdelay"); ?
  3. 387???bootdelay?=?s???(int)simple_strtol(s,?10)?:?CONFIG_BOOTDELAY; ?
  4. ????????????????????????????????????????????????????????//?启动延迟 ?
  5. 388? ?
  6. 389???debug?("###?main_loop?entered:?bootdelay=%dnn",?bootdelay); ?
  7. 390? ?
  8. 391?#?ifdef?CONFIG_BOOT_RETRY_TIME ?
  9. 392???init_cmd_timeout?();????? ? //?初始化命令行超时机制 ?
  10. 393?#?endif ? ?
  11. 394? ?
  12. 395?#ifdef?CONFIG_BOOTCOUNT_LIMIT??????? //一般不会检查这破玩意。
  13. 396???if?(bootlimit?&&?(bootcount?>?bootlimit))?{ ?//?检查是否超出启动次数限制 ?
  14. 397?????printf?("Warning:?Bootlimit?(%u)?exceeded.?Using?altbootcmd.n",?
  15. 398?????????????(unsigned)bootlimit); ?
  16. 399?????s?=?getenv?("altbootcmd"); ?
  17. 400???} ?
  18. 401???else ?
  19. 402?#endif ? ?
  20. 403?????s?=?getenv?("bootcmd"); ?//?获取启动命令参数 ?
  21. 404? ?
  22. 405???debug?("###?main_loop:?bootcmd="%s"n",?s???s?:?"<UNDEFINED>"); ?
  23. 406? ?
  24. 407???if?(bootdelay?>=?0?&&?s?&&?!abortboot?(bootdelay))?{?? ?
  25. ??????????????????????????????????????????????????? ?//检查是否支持启动延迟功能 ?
  26. 408?#?ifdef?CONFIG_AUTOBOOT_KEYED ?
  27. 409?????int?prev?=?disable_ctrlc(1);???? ?
  28. ?????????????????????????????????????????????????? ? //?关闭Ctrl+C组合键 ?
  29. 410?#?endif ?
  30. 411? ?
  31. 412?#?ifndef?CFG_HUSH_PARSER ?
  32. 413?????run_command?(s,?0);????? //?运行启动命令行 ?
  33. 414?#?else ?
  34. 415?????parse_string_outer(s,?FLAG_PARSE_SEMICOLON?| ?
  35. 416?????????????FLAG_EXIT_FROM_LOOP); ?
  36. 417?#?endif ?
  37. 418? ?
  38. 419?#?ifdef?CONFIG_AUTOBOOT_KEYED ?
  39. 420?????disable_ctrlc(prev);?? ?
  40. ???????????????????????????????????????????????????? //?打开Ctrl+C组合键 ?
  41. 421?#?endif ?
  42. 422???} ?
  43. 423? ?
  44. 424?#?ifdef?CONFIG_MENUKEY ?
  45. 425???if?(menukey?==?CONFIG_MENUKEY)?{? ?//?检查是否支持菜单键 ?
  46. 426???????s?=?getenv("menucmd"); ?
  47. 427???????if?(s)?{ ?
  48. 428?#?ifndef?CFG_HUSH_PARSER ?
  49. 429?????run_command?(s,?0); ?
  50. 430?#?else ?
  51. 431?????parse_string_outer(s,?FLAG_PARSE_SEMICOLON?| ?
  52. 432?????????????FLAG_EXIT_FROM_LOOP); ?
  53. 433?#?endif ?
  54. 434???????} ?
  55. 435???} ?
  56. 436?#endif? ?
  57. 437?#endif?? ?
  58. 438? ?
  59. 439?#ifdef?CONFIG_AMIGAONEG3SE ?
  60. 440???{ ?
  61. 441???????extern?void?video_banner(void); ?
  62. 442???????video_banner();???????????????//?打印启动图标 ?
  63. 443???} ?
  64. 444?#endif

(5)在各功能设置完毕后,程序第454行进入一个for死循环,该循环不断使用readline()函数(第463行)从控制台(一般是串口)读取用户的输入,然后解析。有关如何解析命令请参考U-Boot代码中run_command()函数的定义,

  1. 446????
  2. 449?#ifdef?CFG_HUSH_PARSER ?
  3. 450???parse_file_outer(); ?
  4. 451??? ?
  5. 452???for?(;;); ?
  6. 453?#else ?
  7. 454???for?(;;)?{????????????????????????//?进入命令行循环?
  8. 455?#ifdef?CONFIG_BOOT_RETRY_TIME ?
  9. 456?????if?(rc?>=?0)?{ ?
  10. 457??????? ?
  11. 460???????reset_cmd_timeout();??????????//?设置命令行超时 ?
  12. 461?????} ?
  13. 462?#endif ?
  14. 463?????len?=?readline?(CFG_PROMPT);????//?读取命令 ?
  15. 464? ?
  16. 465?????flag?=?0;? ?
  17. 466?????if?(len?>?0) ?
  18. 467???????strcpy?(lastcommand,?console_buffer);?
  19. 468?????else?if?(len?==?0) ?
  20. 469???????flag?|=?CMD_FLAG_REPEAT; ?
  21. 470?#ifdef?CONFIG_BOOT_RETRY_TIME ?
  22. 471?????else?if?(len?==?-2)?{ ?
  23. 472??????? ?
  24. 474???????puts?("nTimed?out?waiting?for?commandn"); ?
  25. 475?#?ifdef?CONFIG_RESET_TO_RETRY ?
  26. 476??????? ?
  27. 477???????do_reset?(NULL,?0,?NULL); ?
  28. 478?#?else ?
  29. 479???????return;??? ?
  30. 480?#?endif?
  31. 481?????} ?
  32. 482?#endif ?
  33. 483? ?
  34. 484?????if?(len?==?-1) ?
  35. 485???????puts?("<INTERRUPT>n"); ?
  36. 486?????else ?
  37. 487???????rc?=?run_command?(lastcommand,?flag);????//?运行命令?
  38. 488? ?
  39. 489?????if?(rc?<=?0)?{ ?
  40. 490??????? ?
  41. 491???????lastcommand[0]?=?0; ?
  42. 492?????} ?
  43. 493???}??// dead loop
  44. 494?#endif? ?
  45. 495?}

U-BOOT的功能设计 基本就在这里

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读