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

u-boot启动之第2阶段浅析

发布时间:2020-12-15 06:17:37 所属栏目:百科 来源:网络整理
导读:??????????在第一阶段分析中已经知道,经过一系列板级初始化后最后是调用函数start_armboot (void),这个告诉我们第2阶段应该是从这个函数开始进行分析,这个函数是在/lib_arm/board.c文件中。 /* Pointer is writable since we allocated a register for it

??????????在第一阶段分析中已经知道,经过一系列板级初始化后最后是调用函数start_armboot (void),这个告诉我们第2阶段应该是从这个函数开始进行分析,这个函数是在/lib_arm/board.c文件中。

  1. /* Pointer is writable since we allocated a register for it */
  2. ?gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));??? //这里的gd_t*是一个结构体的指针,直接给它分配一段内存,在完全手册的图
  3. ?/* compiler optimization barrier needed for GCC >= 3.4 */
  4. ?__asm__ __volatile__("": : :"memory");
  5. ?memset ((void*)gd,sizeof (gd_t));
  6. ?gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));???????????????? //分配内存块大小??????????
  7. ?memset (gd->bd,sizeof (bd_t));
  8. ?monitor_flash_len = _bss_start - _armboot_start;
  9. ?for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {?????? //调用函数初始化指针
  10. ???????????????? ??if ((*init_fnc_ptr)() != 0)
  11. ???????????????????????????? ?{
  12. ?????????????????????????????????????? ?????hang ();
  13. ??????????????????????????????}

?????????????????????????????????????????????


这个结构体gd_t*在u-boot内存中的指向就是在128? Bytes的内存CFG_GBL_DATA_SIZE。函数init_sequence是一系列函数指针:

  1. init_fnc_t *init_sequence[] = {

  2. ????????????? ?cpu_init,??/* basic cpu dependent setup */?????????????????????

  3. ????????????? ?board_init,??/* basic board dependent setup */???????????????? //单板初始化

  4. ???????????????interrupt_init,??/* set up exceptions */

  5. ????????????? env_init,??/* initialize environment */??????????????????????????????????? //环境变量初始化

  6. ???????????? ?init_baudrate,??/* initialze baudrate settings */

  7. ?????????? ? ?serial_init,??/* serial communications setup */

  8. ?????????? ?? console_init_f,??/* stage 1 init of console */

  9. ???????? ?? ?display_banner,??/* say that we are here */

  10. #if defined(CONFIG_DISPLAY_CPUINFO)

  11. ????????? ?? print_cpuinfo,??/* display cpu info (and speed) */

  12. #endif

比如CPU的初始化就是在cpu/arm920t/cpu.c中:

  1. int cpu_init (void)
  2. {
  3. ?/*
    ? * setup up stacks if necessary
    ? */
  4. #ifdef CONFIG_USE_IRQ
  5. ??????????? ?IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4;
  6. ??????????? ?FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
  7. ???????????? FREE_RAM_END = FIQ_STACK_START - CONFIG_STACKSIZE_FIQ - CONFIG_STACKSIZE;
  8. ???????????? FREE_RAM_SIZE = FREE_RAM_END - PHYS_SDRAM_1;
  9. #else?
    ?
    ????????? ? FREE_RAM_END = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4 - CONFIG_STACKSIZE;
  10. ????????????FREE_RAM_SIZE = FREE_RAM_END - PHYS_SDRAM_1;
  11. #endif
  12. ?????????? ?return 0;
  13. }

?单板初始化函数?board_init()就是在board/open24x0/open24x0.c中:

?/*
?* Miscellaneous platform dependent initialisations
?*/

  1. int board_init (void)
  2. ????????????{
  3. ???????????????????????? S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
  4. ?????????????????? ??? ? S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
  5. ??? /* set up the I/O ports */
  6. ??????????????????? ? ? gpio->GPACON = 0x007FFFFF;????? //参考数据手册来设置
  7. ????????????????????? ? gpio->GPBCON = 0x00044555;
  8. ???????????????????? ?? gpio->GPBUP = 0x000007FF;
  9. ????????????????????? ? gpio->GPCCON = 0xAAAAAAAA;
  10. ???????????????????? ?? gpio->GPCUP = 0x0000FFFF;
  11. ??????????????????? ??? gpio->GPDCON = 0xAAAAAAAA;
  12. ????????????????????? ? gpio->GPDUP = 0x0000FFFF;
  13. ???????????????????? ?? gpio->GPECON = 0xAAAAAAAA;
  14. ?????????????????????? ?gpio->GPEUP = 0x0000FFFF;
  15. ??????????????????????? gpio->GPFCON = 0x000055AA;
  16. ?????????????????????? ?gpio->GPFUP = 0x000000FF;
  17. ?????????????????????? ?gpio->GPGCON = 0xFF95FFBA;
  18. ????????????????????? ? gpio->GPGUP = 0x0000FFFF;
  19. ????????????????????? ? gpio->GPHCON = 0x002AFAAA;
  20. ???????????????????? ?? gpio->GPHUP = 0x000007FF;
  21. ??? /* support both of S3C2410 and S3C2440,by www.arm9.net */
  22. ????????????????????? ? if ((gpio->GSTATUS1 == 0x32410000) || (gpio->GSTATUS1 == 0x32410002))
  23. ?????????????????????????????? ?{
  24. ??????? /* arch number of SMDK2410-Board */
  25. ??????????????????????????????????????? ? gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
  26. ?????????????????????????????? ? }
  27. ??? else
  28. ??????????? ??? {
  29. ??????? /* arch number of SMDK2440-Board */
  30. ?????????????????????? ? gd->bd->bi_arch_number = MACH_TYPE_S3C2440;???????? //arch_number 架构数字就是机器码,显然这个在启动内核时要传递给内核才能正确启动
  31. ????????????? ?? }????????????????????????????????????????????????????????????????????????????????????????????????????????????? //否则会有提示start? kernel..........就停在这里不动
  32. ??? /* adress of boot parameters */
  33. ??????????????????? ??? gd->bd->bi_boot_params = 0x30000100;????????? //启动参数在启动内核时也要传递给内核,0x30000100就是存放地址,内核从这里读取参数
  34. ??????????????????? ??? icache_enable();
  35. #if 0
    ???????????????????? ?dcache_enable();
    #endif
  36. ?????????????????? ?? return 0;
  37. ????????????? }

这些寄存器的初化都是跟板级的处理器有非常密切关系,不同的开发板不同处理器一般会有不同的参数,在移植的时候可以借鉴这个思路,参考相关的手册就可以移植。回到我们主题,要想从Nand Flash中读取内核数据,首先是要能够执行读操作,也就是u-boot必须支持读命令这样才能正常读取数据。现在很多的u-boot为了方便开发,在其中加了了可以写的功能函数。

?

2.?? 对Flash 初始化,在Board.c中

  1. #ifndef CFG_NO_FLASH
  2. ?/* configure available FLASH banks */
  3. ?????????????????? ?size = flash_init ();?????????????????????????????????? //对flash的初化函数???????????????????
  4. ?????????????????? ?display_flash_config (size);
  5. #endif /* CFG_NO_FLASH */

下面的代码是具体的初始化代码,在drivers/cfi_flash.c中:

这个函数可以识别不同的Flash,具体的实现过程参考相关手册。

  1. /*-----------------------------------------------------------------------
    ?*/
    unsigned long flash_init (void)
  2. ??????????? {
  3. ??????????????????? ?unsigned long size = 0;
  4. ?????????????????????int i;
  5. #ifdef CFG_FLASH_PROTECTION
  6. ???????????????????? char *s = getenv("unlock");
  7. #endif
  8. ?/* Init: no FLASHes known */
  9. ?????????????????? ?for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) {
  10. ????????????????? ??flash_info[i].flash_id = FLASH_UNKNOWN;
  11. ??????????????????? size += flash_info[i].size = flash_get_size (bank_base[i],i);
  12. ??if (flash_info[i].flash_id == FLASH_UNKNOWN) {??????????????????????????? //用于识别不同的Flash
  13. #ifndef CFG_FLASH_QUIET_TEST
  14. ???printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MBn",
    ????i,flash_info[i].size,flash_info[i].size << 20);
  15. #endif /* CFG_FLASH_QUIET_TEST */
    ??????????? ??}
    #ifdef CFG_FLASH_PROTECTION
  16. ??else if ((s != NULL) && (strcmp(s,"yes") == 0)) {
  17. ???/*
    ??? * Only the U-Boot image and it's environment is protected,
    ??? * all other sectors are unprotected (unlocked) if flash
    ??? * hardware protection is used (CFG_FLASH_PROTECTION) and
    ??? * the environment variable "unlock" is set to "yes".
    ??? */
  18. ????????????????? ?if (flash_info[i].legacy_unlock) {
  19. ???????????????????int k;
  20. ????/*
    ???? * Disable legacy_unlock temporarily,since
    ???? * flash_real_protect would relock all other sectors
    ???? * again otherwise.
    ???? */
  21. ???????????????? ??flash_info[i].legacy_unlock = 0;
  22. ????/*
    ???? * Legacy unlocking (e.g. Intel J3) -> unlock only one
    ???? * sector. This will unlock all sectors.
    ???? */
  23. ???????????????? ???flash_real_protect (&flash_info[i],0);
  24. ????????????????? ??flash_info[i].legacy_unlock = 1;
  25. ????/*
    ???? * Manually mark other sectors as unlocked (unprotected)
    ???? */
  26. ????????????????? ??for (k = 1; k < flash_info[i].sector_count; k++)
  27. ?????????????????? ?flash_info[i].protect[k] = 0;
  28. ???????????????? ???} else {
  29. ????/*
    ???? * No legancy unlocking -> unlock all sectors
    ???? */
  30. ???????????????????????????????????? ? ??flash_protect (FLAG_PROTECT_CLEAR,
  31. ????????????????????????????????????? ?? flash_info[i].start[0],
  32. ???????????????????????????????? ??? ??? flash_info[i].start[0] + flash_info[i].size - 1,
  33. ???????????????????????????????????????? &flash_info[i]);
  34. ???????????????????????????? ???}
  35. ??? ??}
  36. #endif /* CFG_FLASH_PROTECTION */
  37. ????????????? ?}
  38. ?/* Monitor protection ON by default */
  39. #if (CFG_MONITOR_BASE >= CFG_FLASH_BASE)
  40. ???????????????????? ?flash_protect (FLAG_PROTECT_SET,
  41. ??????????????????????????? ??? CFG_MONITOR_BASE,
  42. ???????????????????????????? ?? CFG_MONITOR_BASE + monitor_flash_len? - 1,
  43. ?????????????????????????? ???? flash_get_info(CFG_MONITOR_BASE));
  44. #endif
  45. ?/* Environment protection ON by default */
  46. #ifdef CFG_ENV_IS_IN_FLASH
  47. ?????????????????? ?flash_protect (FLAG_PROTECT_SET,
  48. ???????????????????????????????CFG_ENV_ADDR,
  49. ?????????????????????????????? CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
  50. ???????????????????????????? ? flash_get_info(CFG_ENV_ADDR));
  51. #endif
  52. ?/* Redundant environment protection ON by default */
  53. #ifdef CFG_ENV_ADDR_REDUND
  54. ??????????????? ?flash_protect (FLAG_PROTECT_SET,
  55. ???????????????????????????? ?CFG_ENV_ADDR_REDUND,
  56. ????????????????????????????? CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
  57. ????????????????????????????? ?flash_get_info(CFG_ENV_ADDR_REDUND));
  58. #endif
  59. ?????????????????????? ?return (size);
  60. ????????? }

???????????? /* armboot_start is defined in the board-specific linker script */

????????????? ?mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);???????? //这个是给内存分配空间,对应上面内存图中192K字节空间-----CFG_MALLOC_LEN.在这里实现

?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? //堆空间的分配和释放?

?

?继续往下看:

  1. #if (CONFIG_COMMANDS & CFG_CMD_NAND)
  2. ?puts ("NAND:? ");
  3. ?nand_init();????????????????? ?/* go init the NAND */
  4. #endif

nand_init();的具体代码是在drivers/nand/nand.c中,它可以识别在单板中的Nand Flash。

  1. void nand_init(void)
  2. {
  3. ?int i;
  4. ?unsigned int size = 0;
  5. ?for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) {
  6. ??nand_init_chip(&nand_info[i],&nand_chip[i],base_address[i]);
  7. ??size += nand_info[i].size;
  8. ??if (nand_curr_device == -1)
  9. ???nand_curr_device = i;
  10. ?}
  11. ?printf("%lu MiBn",size / (1024 * 1024));
  12. #ifdef CFG_NAND_SELECT_DEVICE
  13. ?/*
    ? * Select the chip in the board/cpu specific driver
    ? */
  14. ?board_nand_select_device(nand_info[nand_curr_device].priv,nand_curr_device);
  15. #endif
  16. }

其实我们的u-boot就是通过调用这两个函数flash_init (void)和nand_init(void)来实现对内核的数据的读取的,代码过程可以不用理它,只要把它作为一个接口调用即可。

?

  1. #ifdef CONFIG_HAS_DATAFLASH
  2. ?AT91F_DataflashInit();
  3. ?dataflash_print_info();
  4. #endif
  5. ?/* initialize environment */
  6. ?env_relocate ();?????????????????? //环境变量初始化,一种是在代码中写好了的默认值,一种是在Flash中保存的,这个是修改后的值,启动时先到Flash中看是否有

?????????????????????????????????????????????????????????? //要是有就用最新的环境变量值,没有就用默认的值

?

?

?

下现是网卡和USB等等的一些IP等的初始化:

  1. ?/* IP Address */
  2. ??????????????? ?gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
  3. ?/* MAC Address */
  4. ?????????????????????? ?{
  5. ????????????????????????????????? ?int i;
  6. ??????????????????????????????? ? ?ulong reg;
  7. ?????????????????????????????????? char *s,*e;
  8. ???????????????????????????????? ??char tmp[64];
  9. ???????????????????????????????? ??i = getenv_r ("ethaddr",tmp,sizeof (tmp));
  10. ???????????????????????????????? ??s = (i > 0) ? tmp : NULL;
  11. ???????????????????????????????? ??for (reg = 0; reg < 6; ++reg) {
  12. ????????????????????????????????? gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s,&e,16) : 0;
  13. ???????????????????????????????????if (s)
  14. ?????????????????????????????????????????? ??s = (*e) ? e + 1 : e;
  15. ????????????????????? ?}
  16. #ifdef CONFIG_HAS_ETH1
  17. ??????????????????????????????? ?i = getenv_r ("eth1addr",sizeof (tmp));
  18. ?????????????????????????????? ??s = (i > 0) ? tmp : NULL;
  19. ?????????????????????????????? ??for (reg = 0; reg < 6; ++reg) {
  20. ??????????????????????????????? gd->bd->bi_enet1addr[reg] = s ? simple_strtoul (s,16) : 0;
  21. ????????????????????????????? ???if (s)
  22. ?????????????????????????????????s = (*e) ? e + 1 : e;?????????????????? //网卡的初始化
  23. ????????????????????????? ?}
  24. #endif
  25. ???????????????????? ?}
  26. ?????????????????????????????? ?devices_init ();?????????????????????????? /* get the devices list going. */
  27. #ifdef CONFIG_CMC_PU2
  28. ?????????????????????????????? ?load_sernum_ethaddr ();
  29. #endif /* CONFIG_CMC_PU2 */
  30. ?????????????????????????????? ?jumptable_init ();
  31. ????????????????????????????? ?console_init_r ();??????????????????????????? ?/* fully init console as a device */
  32. #if defined(CONFIG_MISC_INIT_R)
  33. ?/* miscellaneous platform dependent initialisations */
  34. ????????????????????????????? ?misc_init_r ();
  35. #endif
  36. ????????????????????????????? ?Port_Init();
  37. ????????????????????????????? ?if (!PreLoadedONRAM) {????????????????????????? //如果用调试器下载的话这个PreLoadedONRAM被制成1
  38. ??/* enable exceptions */
  39. ?????????????????????????????? enable_interrupts ();
  40. ???? /* add by www.arm9.net */
  41. ????????????????????????????? ?usb_init();????????????????????????????????????? //USB设备初始化
  42. ?}
  43. ??? /* Perform network card initialisation if necessary */
  44. #ifdef CONFIG_DRIVER_CS8900
  45. ?????????????????????????????? ?cs8900_get_enetaddr (gd->bd->bi_enetaddr);
  46. #endif
  47. #if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
  48. ????????????????????????????? ?if (getenv ("ethaddr")) {????????????????????????????????????????????????????
  49. ????????????????????????????????????? ??smc_set_mac_addr(gd->bd->bi_enetaddr);???????????????? //获取MAC地址
  50. ?}
  51. #endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */
  52. ?/* Initialize from environment */
  53. ????????????????????????????? ?if ((s = getenv ("loadaddr")) != NULL) {
  54. ????????????????????????????? ?load_addr = simple_strtoul (s,NULL,16);
  55. ?}
  56. #if (CONFIG_COMMANDS & CFG_CMD_NET)
  57. ???????????????????????????? ?if ((s = getenv ("bootfile")) != NULL) {
  58. ??????????????????????????????????? ??copy_filename (BootFile,s,sizeof (BootFile));
  59. ?}
  60. #endif?/* CFG_CMD_NET */
  61. #ifdef BOARD_LATE_INIT
  62. ????????????????????????????? ?board_late_init ();
  63. #endif
  64. #if (CONFIG_COMMANDS & CFG_CMD_NET)
  65. #if defined(CONFIG_NET_MULTI)
  66. ????????????????????????????? ?puts ("Net:?? ");
  67. #endif
  68. ????????????????????????????? ?eth_initialize(gd->bd);
  69. #endif
  70. ?/* main_loop() can return to retry autoboot,if so just run it again. */
  71. ?????????????????????????????????for (;;) {
  72. ????????????????????????????????????????? ??main_loop ();????????????????????? //最终进入这个C语言函数,进行循环,就像在等待输入命令,一个死循环
  73. ?????????????????? ?}
  74. ?/* NOTREACHED - no way out of command loop except booting */
    ?????????????????}

经过第二阶段的初始化后,最后进入函数?main_loop (),这个函数是在/comman/main.c中:

  1. #ifdef CONFIG_BOOTCOUNT_LIMIT
  2. ?if (bootlimit && (bootcount > bootlimit)) {
  3. ???????????? ??printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.n",
  4. ????????????????????????? ?(unsigned)bootlimit);
  5. ???????????? ?s = getenv ("altbootcmd");
  6. ?}
  7. ?else
  8. #endif /* CONFIG_BOOTCOUNT_LIMIT */
  9. ????????????? ?s = getenv ("bootcmd");
  10. ?debug ("### main_loop: bootcmd="%s"n",s ? s : "<UNDEFINED>");
  11. ??????????????????? ?if (bootdelay >= 0 && s && !abortboot (bootdelay)) {?????????????????? //这里是在u-boot启动时有倒数计时,要是没有空格被按下则会跳到其他分支,下面有说明
  12. # ifdef CONFIG_AUTOBOOT_KEYED
  13. ??????????????????? ??int prev = disable_ctrlc(1);?/* disable Control C checking */
  14. # endif
  15. # ifndef CFG_HUSH_PARSER
  16. #ifdef CONFIG_SURPORT_WINCE
  17. ??????? if (!TOC_Read())
  18. ???????????????? ?? {
  19. ?????????????????????? ?? /* Launch wince */
  20. ????????????????????????? ?? char cmd_buf[16];
  21. ???????????????????????? ??? printf("Booting wince ...n");
    ??????????
    ??????????????????????????? ?strcpy(cmd_buf,"wince");
  22. ??????????????????????? ??? run_command(cmd_buf,0);
  23. ??????? }
  24. ??????? else
  25. #endif
  26. ??????? {
  27. ??????????? printf("Booting Linux ...n");??
    ????????
    ??? ???? run_command (s,0);
  28. ??????? }
  29. # else
  30. ?????????? ?parse_string_outer(s,FLAG_PARSE_SEMICOLON |
  31. ??????????????????? ? FLAG_EXIT_FROM_LOOP);
  32. # endif
  33. # ifdef CONFIG_AUTOBOOT_KEYED
  34. ?????????????????? ?disable_ctrlc(prev);?/* restore Control C checking */
    # endif
  35. ?}
  36. # ifdef CONFIG_MENUKEY
  37. ??????????????????? ?if (menukey == CONFIG_MENUKEY) {????????????????????? //要是空格被按下程序就会跳到这里来执行
  38. ??????????????????????????? ?s = getenv("menucmd");
  39. ?????????????????????? ??? if (s) {
  40. # ifndef CFG_HUSH_PARSER
  41. ???????????????????????????????????????????? ??run_command (s,0);
  42. # else
  43. ????????????????????????????????? ??parse_string_outer(s,FLAG_PARSE_SEMICOLON |
  44. ???????????????????????????????? ?? FLAG_EXIT_FROM_LOOP);
  45. # endif
  46. ???????? ?? }
  47. ??}
  48. #endif /* CONFIG_MENUKEY */
  49. #endif?/* CONFIG_BOOTDELAY */
  50. #ifdef CONFIG_AMIGAONEG3SE
  51. ?????????? ?{
    ??????????????????????? extern void video_banner(void);
  52. ?????????????????????? ?video_banner();
  53. ?}
  54. #endif
  55. ??????????????????? ?? run_command("menu",0);??????????? //u-boot启动时按下空格键时有个菜单的原因就是执行了这个函数
    ?/*
    ? * Main Loop for Monitor Command Processing
    ? */

  56. PROMPT:
  57. #ifdef CFG_HUSH_PARSER
  58. ??????????????? ?parse_file_outer();
  59. ?/* This point is never reached */
  60. ??????????????? ?for (;;);??????????????????????? //进入菜单后又是一个死循环,等待输入命令,有命令输入后它就会解析命令,没有则显示异常提示信息,因此命令就是u-boot的核心
  61. #else
  62. ?????????????? ?for (;;) {
  63. #ifdef CONFIG_BOOT_RETRY_TIME
  64. ????????????? ??if (rc >= 0) {
  65. ???/* Saw enough of a valid command to
    ??? * restart the timeout.
    ??? */
  66. ???????????????????????? ??reset_cmd_timeout();
  67. ??}
  68. #endif
  69. ??????????????????????? ??len = readline (CFG_PROMPT);

  70. ??????????????????????? ??flag = 0;?/* assume no special flags for now */
  71. ???????????????????????????if (len > 0)
  72. ?????????????????????????????????????? ?strcpy (lastcommand,console_buffer);
  73. ????????????????????????????????????? ??else if (len == 0)
  74. ????????????????????????????????????????????? ???flag |= CMD_FLAG_REPEAT;
  75. #ifdef CONFIG_BOOT_RETRY_TIME
  76. ???????????????????????????????????? ??else if (len == -2) {
  77. ???/* -2 means timed out,retry autoboot
    ??? */
  78. ???????????????????????????????????? ???puts ("nTimed out waiting for commandn");
  79. # ifdef CONFIG_RESET_TO_RETRY
  80. ???/* Reinit board to run initialization code again */
  81. ????????????????????????????????????? ?do_reset (NULL,NULL);
  82. # else
  83. ???????????????????????????????????? ??return;??/* retry autoboot */
  84. # endif
  85. ??}
  86. #endif
  87. ??????????????????????????????????? ??if (len == -1)
  88. ???????????????????????????????????????????? ??puts ("<INTERRUPT>n");
  89. ??else
  90. ???????????????????????????????????????????? ??rc = run_command (lastcommand,flag);

  91. ???????????????????????????????????? ?if (rc <= 0) {
  92. ???/* invalid command or not repeatable,forget it */
  93. ?????????????????????????????????????????????? ??lastcommand[0] = 0;
  94. ???????????? ??}
  95. ??? ?}
  96. #endif /*CFG_HUSH_PARSER*/
  97. }
  98. #ifdef CONFIG_BOOT_RETRY_TIME

到这里总结一下启动内核是如何调用相关函数的:1.????s = getenv ("altbootcmd");获取环境变量参数

??????????????????????????????????????????????????????????????????????????????????????? 2.????调用?run_command (s,0);函数

?

而在u-boot的控制界面时:1.?? 调用readline()函数,读取串口数据

??????????????????????????????????????????????? 2.?? 还是调用?run_command (s,0);函数

?

?

在common/main.c中readline()函数代码如下:

/****************************************************************************/

  1. /*
    ?* Prompt for input and read a line.
    ?* If? CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0,
    ?* time out when time goes past endtime (timebase time in ticks).
    ?* Return:?number of read characters
    ?*??-1 if break
    ?*??-2 if timed out
    ?*/
    int readline (const char *const prompt)
  2. ???????????? {
  3. #ifdef CONFIG_CMDLINE_EDITING
  4. ???????????????????????? ?char *p = console_buffer;
  5. ???????????????????????? ?unsigned int len=MAX_CMDBUF_SIZE;
  6. ??????????????????????????int rc;
  7. ???????????????????????? ?static int initted = 0;
  8. ???????????????????????? ?if (!initted) {
  9. ???????????????????????????????? ??hist_init();
  10. ???????????????????????????????????initted = 1;
  11. ????????????????????????????????????????????? ?}
  12. ???????????????????????? ?puts (prompt);
  13. ???????????????????????? ?rc = cread_line(p,&len);
  14. ???????????????????????? ?return rc < 0 ? rc : len;
    #else
  15. ??????????????????????? ?char?? *p = console_buffer;
  16. ???????????????????????? ?int?n = 0;????/* buffer index??*/
  17. ??????????????????????? ?int?plen = 0;???/* prompt length?*/
  18. ??????????????????????? ?int?col;????/* output column cnt?*/
  19. ?????????????????????????char?c;
  20. ?/* print prompt */
  21. ?????????????????????? ?if (prompt) {
  22. ?????????????????????????????? ??plen = strlen (prompt);
  23. ?????????????????????????????? ??puts (prompt);
  24. ??????????????????????????????????????????? ?}
  25. ?????????? ?col = plen;
  26. ?????????????for (;;) {
  27. #ifdef CONFIG_BOOT_RETRY_TIME
  28. ???????????????while (!tstc()) {?/* while no incoming data */
  29. ????????????????if (retry_time >= 0 && get_ticks() > endtime)
  30. ?????????????????????? ??return (-2);?/* timed out */
  31. ????????????????????????????????????? ??}
  32. #endif
  33. ??????????????????WATCHDOG_RESET();??/* Trigger watchdog,if needed */

  34. #ifdef CONFIG_SHOW_ACTIVITY
  35. ?????????????? ??while (!tstc()) {
  36. ???????????? ???extern void show_activity(int arg);
  37. ?????????????? ??show_activity(0);
  38. ??}
  39. #endif
  40. ?????????????? ?c = getc();
  41. ??/*
    ?? * Special character handling
    ?? */
  42. ????????????? switch (c) {
  43. ????????????????????????????????? ?case 'r':????/* Enter??*/
  44. ??????????????????????????????? ??case 'n':
  45. ??????????????????????????????? ??*p = '';
  46. ????????????????????????????? ???puts ("rn");
  47. ?????????????????????????????? ??return (p - console_buffer);
  48. ????????????????????case '':????????????????????????????????????? ?/* nul???*/
  49. ???????????????? ????????????? ??continue;
  50. ?????????????????????????????? ??case 0x03:
    ????/* ^C - break??*/
  51. ??????????????????????????? ? ??console_buffer[0] = '';?????????????????????? /* discard input */
  52. ??????????????????????????? ???return (-1);
  53. ???????????????? ??case 0x15:
    ????/* ^U - erase line?*/
    ????????????????????????????? ??while (col > plen) {
  54. ??????????????????????????? ????puts (erase_seq);
  55. ?????????????????????????????????--col;
  56. ??? ???}
  57. ???????????????????????????? ??p = console_buffer;
  58. ???????????????????????????????n = 0;
  59. ??????????????????????????? ???continue;
  60. ?????????????? ??case 0x17:
    ?
    ???/* ^W - erase word ?*/
    ?????????????????????????? ???p=delete_char(console_buffer,p,&col,&n,plen);
  61. ???????????????????????????? ??while ((n > 0) && (*p != ' ')) {
  62. ??????????????????????????? ??p=delete_char(console_buffer,plen);
  63. ???}
  64. ????????????????????????? ???continue;
  65. ?????????????? ??case 0x08:
    ????/* ^H? - backspace?*/
  66. ????????????? ??case 0x7F:????/* DEL - backspace?*/
  67. ??????????????????????????? ?p=delete_char(console_buffer,plen);
  68. ??????????????????????????? ?continue;
  69. ???????????????????????????? ?default:
  70. ???/*
    ??? * Must be a normal character then
    ??? */
  71. ?????????????? ??if (n < CFG_CBSIZE-2) {
  72. ?????????????????????? ??if (c == 't') {???????????????????????????????????????? ?/* expand TABs??*/
  73. #ifdef CONFIG_AUTO_COMPLETE
    ?????/* if auto completion triggered just continue */
  74. ?????*p = '';
  75. ??????????????????????????????????????? ?if (cmd_auto_complete(prompt,console_buffer,&col)) {
  76. ????????????????????????????????????????????????? ???p = console_buffer + n;?????????????????????????????????????????? ?/* reset */
  77. ???????????????????????????????????????????????? ?????continue;
  78. ?????}
  79. #endif
  80. ????????????????????????????????????? ?puts (tab_seq+(col&07));
  81. ????????????????????????????????????? ?col += 8 - (col&07);
  82. ????} else {
  83. ???????????????????????????????????? ??++col;???????????????????????????????????????? ??/* echo input??*/
  84. ???????????????????????????????????? ???putc (c);
  85. ????}
  86. ?????????????????????????????????????? ?*p++ = c;
  87. ????????????????????????????????????? ???++n;
  88. ?????????????????????????????????????? ??} else {???/* Buffer full??*/
  89. ???????????????????????????????????? ???putc ('a');
  90. ???}
  91. ??}
  92. ?}
  93. #endif /* CONFIG_CMDLINE_EDITING */
  94. }

?

?参考韦东山老师的视频教程!

(编辑:李大同)

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

    推荐文章
      热点阅读