• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
一蓑烟雨
C/C++,Linux,语音技术
博客园    首页    新随笔    联系   管理    订阅  订阅
U-Boot移植(8)u-boot的流程

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的执行就进入等待用户输入命令,解析并执行命令的死循环中。

 

参考:http://deshunfan.blog.163.com/blog/static/34244101200972832324749/

posted on 2011-07-14 15:26  lovemu  阅读(468)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3