U-Boot移植(8)u-boot的流程

2023-08-30  

u-boot的启动流程:

  从文件层面上看主要流程是在两个文件中:cpu/arm920t/start.s,lib_arm/board.c, 

  1)start.s 

   在flash中执行的引导代码,也就是bootloader中的stage1,负责初始化硬件环境,把u-boot从flash加载到RAM中去,然后跳到lib_arm/board.c中的start_armboot中去执行。

1.1.6u-boot的start.s流程:

硬件环境初始化:

     进入svc模式;关闭watch dog;屏蔽所有IRQ掩码;设置时钟频率FCLK、HCLK、PCLK;清I/D cache;禁止MMU和CACHE;配置memory control;

重定位:

     如果当前代码不在连接指定的地址上(对smdk2410是0x3f000000)则需要把u-boot从当前位置拷贝到RAM指定位置中;

            建立堆栈,堆栈是进入C函数前必须初始化的。

清.bss区。

跳到start_armboot函数中执行。(lib_arm/board.c)

2)lib_arm/board.c:

   start_armboot是U-Boot执行的第一个C语言函数,完成系统初始化工作,进入主循环,处理用户输入的命令。这里只简要列出了主要执行的函数流程:

   void start_armboot (void)

   {

       //全局数据变量指针gd占用r8。

          DECLARE_GLOBAL_DATA_PTR;

         

          /* 给全局数据变量gd安排空间*/

          gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));

          memset ((void*)gd, 0, sizeof (gd_t));

         

          /* 给板子数据变量gd->bd安排空间*/

          gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));

          memset (gd->bd, 0, sizeof (bd_t));

          monitor_flash_len = _bss_start - _armboot_start;//取u-boot的长度。

         

          /* 顺序执行init_sequence数组中的初始化函数 */

          for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {

                 if ((*init_fnc_ptr)() != 0) {

                         hang ();

                 }

          }

         

          /*配置可用的Flash */

          size = flash_init ();

        ……

          /* 初始化堆空间 */

          mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);

          /* 重新定位环境变量, */

         env_relocate ();

          /* 从环境变量中获取IP地址 */

          gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

          /* 以太网接口MAC 地址 */

          ……

          devices_init ();      /* 设备初始化 */

          jumptable_init ();  //跳转表初始化

          console_init_r ();    /* 完整地初始化控制台设备 */

          enable_interrupts (); /* 使能中断处理 */

          /* 通过环境变量初始化 */

          if ((s = getenv ("loadaddr")) != NULL) {

                  load_addr = simple_strtoul (s, NULL, 16);

          }

          /* main_loop()循环不断执行 */

          for (;;) {

                  main_loop ();      /* 主循环函数处理执行用户命令 -- common/main.c */

          }

   }

初始化函数序列init_sequence[]

  init_sequence[]数组保存着基本的初始化函数指针。这些函数名称和实现的程序文件在下列注释中。

  

  init_fnc_t *init_sequence[] = {

         cpu_init,             /* 基本的处理器相关配置 -- cpu/arm920t/cpu.c */

         board_init,           /* 基本的板级相关配置 -- board/smdk2410/smdk2410.c */

         interrupt_init,       /* 初始化例外处理 -- cpu/arm920t/s3c24x0/interrupt.c */

         env_init,             /* 初始化环境变量 -- common/env_flash.c */

         init_baudrate,        /* 初始化波特率设置 -- lib_arm/board.c */

         serial_init,          /* 串口通讯设置 -- cpu/arm920t/s3c24x0/serial.c */

         console_init_f,       /* 控制台初始化阶段1 -- common/console.c */

         display_banner,       /* 打印u-boot信息 -- lib_arm/board.c */

         dram_init,            /* 配置可用的RAM -- board/smdk2410/smdk2410.c */

         display_dram_config,  /* 显示RAM的配置大小 -- lib_arm/board.c */

         NULL,

  };

整个u-boot的执行就进入等待用户输入命令,解析并执行命令的死循环中。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。