搜索
bottom↓
回复: 11

u-boot第二阶段启动流程

[复制链接]

出0入0汤圆

发表于 2014-9-16 20:59:19 | 显示全部楼层 |阅读模式
u-boot 第一阶段启动流程:http://www.amobbs.com/thread-5595629-1-1.html
详细请看:http://m18271260665.blog.163.com/
首先还是来一张图片大致看一下第二阶段完成的任务:

在第一阶段start.S的最后有这样一句代码:

        ldr        pc, _start_armboot        @ jump to C code

当第一阶段的全部任务完成之后,就会调到_start_armboot 处开始执行第二阶段的代码,这里的_start_armboot        是一个标签,是函数void start_armboot (void)的首地址。这个函数在/lib_arm/board.c中。接下来就是按照上图中的步骤开始一步一步进行。
        同样,board.c中,也用到了很多的条件编译,这里把没用编译的都去掉了,方便阅读,精简后的代码如下:
  1. typedef        struct environment_s {
  2.         uint32_t        crc;                /* CRC32 over data bytes        */
  3.         unsigned char        flags;                /* active/obsolete flags        */
  4.         unsigned char        data[ENV_SIZE]; /* Environment data                */

  5. } env_t;

  6. typedef struct bd_info {
  7.         //串口通讯波特率
  8.     int                        bi_baudrate;        /* serial console baudrate */
  9.     //IP 地址
  10.         unsigned long        bi_ip_addr;        /* IP Address */
  11.     //环境变量起始地址
  12.         struct environment_s               *bi_env;
  13.     //开发板的机器码
  14.         ulong                bi_arch_number;        /* unique id for this board */
  15.     //uboot传递给内核参数的起始地址
  16.         ulong                bi_boot_params;        /* where this board expects params */
  17.     //内存信息
  18.         struct                                /* RAM configuration */
  19.     {
  20.            ulong start;//内存的起始地址
  21.            ulong size;//内存大小
  22.     }bi_dram[1];
  23. } bd_t;

  24. typedef        struct        global_data {
  25.         bd_t                *bd;
  26.         unsigned long        flags; //uboot是否重定向的标志
  27.         //串口波特率
  28.         unsigned long        baudrate;
  29.         //是否有一个控制台标志
  30.         unsigned long        have_console;        /* serial_init() was called */
  31.         //环境变量所在的地址
  32.         unsigned long        env_addr;        /* Address  of Environment struct */
  33.         //环境变量是否有效
  34.         unsigned long        env_valid;        /* Checksum of Environment valid? */
  35.         unsigned long        fb_base;        /* base address of frame buffer */
  36.         void                **jt;                /* jump table */
  37. } gd_t;


  38. typedef int (init_fnc_t) (void);
  39. register volatile gd_t *gd asm ("r8");
  40. ulong monitor_flash_len;

  41. init_fnc_t *init_sequence[] = {
  42.         //初始化CPU相关设置:系统时钟操作函数
  43.         arch_cpu_init,                /* basic arch cpu dependent setup */
  44.         //初始化开发板相关设置:开发板的机器码
  45.         board_init,                /* basic board dependent setup */
  46.         //初始化定时器
  47.         timer_init,                /* initialize timer */
  48.         //初始化环境变量
  49.         env_init,                /* initialize environment */
  50.         //初始化波特率
  51.         init_baudrate,                /* initialze baudrate settings */
  52.         //串口初始化
  53.         serial_init,                /* serial communications setup */
  54.         //控制台设备一级初始化
  55.         console_init_f,                /* stage 1 init of console */
  56.         //打印u-boot版本、编译时间
  57.         display_banner,                /* say that we are here */
  58.        
  59.         //打印CPU类型和当前运行频率
  60.         print_cpuinfo,                /* display cpu info (and speed) */
  61.        
  62.         //打印开发板名称
  63.         checkboard,                   /* display board info */
  64.        
  65.         //配置可用的内存
  66.         dram_init,                   /* configure available RAM banks */
  67.         //显示当前内存大小
  68.         display_dram_config,
  69.         NULL,
  70. };

  71. void start_armboot (void)
  72. {
  73.         init_fnc_t **init_fnc_ptr;
  74.         char *s;


  75.         /* Pointer is writable since we allocated a register for it
  76.          * _armboot_start :0x20f00044
  77.          * CONFIG_SYS_MALLOC_LEN:0x120000
  78.          * sizeof(gd_t)   :0x40 [64byte]
  79.          *
  80.          * gd : 0x20de0004
  81.          */
  82.         gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t));
  83.         /* compiler optimization barrier needed for GCC >= 3.4 */
  84.         __asm__ __volatile__("": : :"memory");

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

  86.         //gd->bd :0x20de0004 -  0x38 = 0x20ddffcc
  87.         gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
  88.         memset (gd->bd, 0, sizeof (bd_t));

  89.         gd->flags |= GD_FLG_RELOC;
  90.        
  91.         //uboot去掉bss段的大小
  92.         monitor_flash_len = _bss_start - _armboot_start;
  93.        
  94.         //外围硬件初始化
  95.         for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
  96.                 if ((*init_fnc_ptr)() != 0) {
  97.                         hang ();
  98.                 }
  99.         }
  100.        
  101.         //将堆区初始化为0
  102.         /* armboot_start is defined in the board-specific linker script */
  103.         mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,
  104.                         CONFIG_SYS_MALLOC_LEN);


  105.         puts ("NAND:  ");

  106.         //NAND FALSH 初始化
  107.         nand_init();                /* go init the NAND */

  108.         /*读取Nand Flash的环境变量,然后做CRC校验,如果错误则使用默认的环境变量*/
  109.         env_relocate ();

  110.         /*获得IP 地址*/
  111.         gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
  112.        
  113.         //初始化输入、输出设备列表
  114.         stdio_init ();        /* get the devices list going. */
  115.        

  116.         jumptable_init ();
  117.        
  118.         //初始化标准输入、输出、出错
  119.         console_init_r ();        /* fully init console as a device */

  120.         /* 使能IRQ异常 */
  121.         enable_interrupts ();

  122.         /* Initialize from environment */
  123.         if ((s = getenv ("loadaddr")) != NULL) {
  124.                 load_addr = simple_strtoul (s, NULL, 16);
  125.         }
  126.        
  127.         //初始化网卡设备
  128.         eth_initialize(gd->bd);

  129.         /* main_loop() can return to retry autoboot, if so just run it again. */
  130.         for (;;) {
  131.                 main_loop ();
  132.         }

  133.         /* NOTREACHED - no way out of command loop except booting */
  134. }


  135. void hang (void)
  136. {
  137.         puts ("### ERROR ### Please RESET the board ###\n");
  138.         for (;;);
  139. }
复制代码

相关的初始化完成之后,会进入到main_loop ();

  1. void main_loop (void)
  2. {
  3.         char *s;
  4.         int bootdelay;

  5.         u_boot_hush_start ();

  6.         s = getenv ("bootdelay");
  7.         bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;

  8.         debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);


  9.         s = getenv ("bootcmd");

  10.         debug ("### main_loop: bootcmd="%s"\n", s ? s : "<UNDEFINED>");

  11.         if (bootdelay >= 0 && s && !abortboot (bootdelay)) {

  12.         parse_string_outer(s, FLAG_PARSE_SEMICOLON |
  13.                                     FLAG_EXIT_FROM_LOOP);

  14.         /*
  15.          * Main Loop for Monitor Command Processing
  16.          */       
  17.         parse_file_outer();
  18.         /* This point is never reached */
  19.         for (;;);
  20. }

  21. static __inline__ int abortboot(int bootdelay)
  22. {
  23.         int abort = 0;

  24.         printf("Hit any key to stop autoboot: %2d ", bootdelay);

  25.         /*
  26.          * Check if key already pressed
  27.          * Don't check if bootdelay < 0
  28.          */
  29.         if (bootdelay >= 0) {
  30.                 if (tstc()) {        /* we got a key press        */
  31.                         (void) getc();  /* consume input        */
  32.                         puts ("\b\b\b 0");
  33.                         abort = 1;        /* don't auto boot        */
  34.                 }
  35.         }

  36.         while ((bootdelay > 0) && (!abort)) {
  37.                 int i;

  38.                 --bootdelay;
  39.                 /* delay 100 * 10ms */
  40.                 for (i=0; !abort && i<100; ++i) {
  41.                         if (tstc()) {        /* we got a key press        */
  42.                                 abort  = 1;        /* don't auto boot        */
  43.                                 bootdelay = 0;        /* no more delay        */
  44.                                 (void) getc();  /* consume input        */
  45.                                 break;
  46.                         }
  47.                         udelay(10000);
  48.                 }

  49.                 printf("\b\b\b%2d ", bootdelay);
  50.         }

  51.         putc('\n');

  52.         return abort;
  53. }
复制代码



最后bootcmd这条命令设置为引导内核气动就OK了。。。


u-boot 第一阶段启动流程:http://www.amobbs.com/thread-5595629-1-1.html
详细请看:http://m18271260665.blog.163.com/

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2014-9-16 21:30:09 | 显示全部楼层
谢谢分享,讲的真详细

出0入0汤圆

发表于 2014-9-16 22:05:38 | 显示全部楼层
还不错哦

出0入8汤圆

发表于 2014-9-16 22:06:20 | 显示全部楼层
图文并茂,把整个流程都很清楚画出来了,容易看懂。谢谢!

出0入0汤圆

发表于 2014-9-16 22:06:29 | 显示全部楼层
讲的真详细,谢谢

出0入0汤圆

发表于 2014-9-16 23:01:43 来自手机 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2014-9-17 15:46:58 | 显示全部楼层
很详细,正在读

出0入0汤圆

发表于 2014-9-17 16:07:05 | 显示全部楼层
大哥,出个PDF的文档吧,,方便收藏。。

出0入12汤圆

发表于 2014-9-23 11:14:16 | 显示全部楼层
不错,呵呵。

出0入0汤圆

发表于 2014-9-23 11:20:58 | 显示全部楼层
多谢了楼主共享啊,赞。。。

出0入0汤圆

发表于 2014-9-23 13:47:13 来自手机 | 显示全部楼层
感谢楼主分享

出0入0汤圆

发表于 2018-2-28 16:52:43 | 显示全部楼层
多谢分享……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 07:41

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表