查看: 2067|回复: 1

[经验] 墩子学嵌入式-入门之路

[复制链接]
  • TA的每日心情
    奋斗
    2019-1-9 11:07
  • 签到天数: 77 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2015-5-22 10:13:40 | 显示全部楼层 |阅读模式
    分享到:
    少年易老学难成,   一寸光阴不可轻。
    未觉池塘春草梦,   阶前梧叶已秋声。

    《劝学》   朱熹


        都说万事开头难,作为一名大学只接触过单片机,且多年未用的选手,我对这个难字深有感触。毕业以来一直都在做整体设计方案,对大学用过的单片机已放下多时,最近由于项目需要,俺要自己去使用arm A9构架的嵌入式板卡。无奈之下只得拿着该开发板的使用手册依葫芦画瓢瞎操作一番,由于手册并没有详细说明指令的意思,自己只能一个个baidu它们,经常出现缺少符号或者字母操作失败的情况。
    后来机缘巧合看到了韦东山老师的视频,学了几课以后,顿觉脑子不在一桶浆糊。韦东山老师讲得非常透彻,我激动不已于是一口气下载了视频的全部三期(后来才知道2,3期是需要付费的)。手机里一份,家里电脑里一份,经常在公交车上看看,在家里看看。对于uboot和内核、文件系统这三课看了有三四遍,慢慢的对这三部分有了一些意识和理解,并且学会操作他们。
        原来uboot的最终目的是为了启动内核kernel,但是在启动之前需要完成初始化时钟、关看门狗、初始化串口以及读写flash等操作,具体操作流程如下:
    对于uboot的编译操作只需要执行:
          make100ask24x0.config      配置文件
          make                     编译文件
    解释:
    make 100ask24x0.config
    相当于执行@$(MKCONFIG)$(@:_config=) arm arm920t 100ask24x0 NULL s3c24x0
    uboot启动流程:
        第一阶段:
    板卡上电执行uboot第一个程序start.S,该uboot的入口程序才用汇编编写,代码如下:
    /* a, 设置CPU为SVC32模式 */
           mrs  r0,cpsr
           bic  r0,r0,#0x1f
           orr  r0,r0,#0xd3
           msr  cpsr,r0
    /* b, 关闭看门狗 */
    /* c, 关中断 */
    /* d, CPU初始化,初始化SDRAM */
           adr  r0, _start
           ldr  r1, _TEXT_BASE
           cmp      r0,r1
           blne     cpu_init_crit
    /* e, 设置stack */
    stack_setup:
           ldr  r0, _TEXT_BASE  /* 顶部128 KiB重定位的u-boot */
           sub  r0, r0, #CFG_MALLOC_LEN  /* 向下是内存分配空间 */
           sub  r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo结构体地址空间 */
    #ifdef CONFIG_USE_IRQ
           sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
    #endif
           sub sp, r0, #12     /* 预留3个字   */
    /* f, 时钟初始化  */      
    bl  clock_init      
    /* g, 重定位,代码从Flash拷贝到SDRAM中 */
    /* h, 清bss段 */
    clear_bss:
           ldr  r0, _bss_start      /*  bss段起始地址 */
           ldr  r1, _bss_end        /*  bss段末尾地址  */
           mov  r2, #0x00000000     /* 清零 */
    clbss_l:str r2, [r0]      /* bss段地址空间清零循环... */
           add  r0, r0, #4
           cmp  r0, r1
           bne  clbss_l
    /* i, 调用start_armboot */
           ldr  pc, _start_armboot
           _start_armboot: .word start_armboot

    第二阶段:
        start_armboot是uboot执行的第一个C语言函数,完成系统初始化工作,基本的初始化函数指针保存在init_sequence[]数组中。
        函数void start_armboot (void)
    {
                mem_malloc_init(_armboot_start - CONFIG_SYS_MALLOC_LEN);
    /*配置Flash */
    display_flash_config(flash_init ());
               /* 配置环境变量*/
    env_relocate();
    ......
    /*main_loop()循环不断执行 */
    for(;;)
    {
                   main_loop();      /* 主循环函数处理执行用户命令*/
    }
    }
    该程序通过main_loop函数一直等待用户在控制台输入命令,接收到命令后进行命令解析。
    启动内核:      
    s=getenv(“bootcmd”)
    run_command(s)
    环境变量中bootcmd参数有一条bootm 0x30007F00指令,表示内核在该地址处启动。
        当有启动命令bootm时,会调用do_bootm函数。这个函数专门用来引导各种操作系统映像,可以支持引导Linux、QNX等操作系统,该函数会调用do_bootm_linux()。
        最终do_bootm_linux()函数会调用
        theKernel(0, bd->bi_arch_number, bd->bi_boot_params)函数来启动内核,传递启动参数。
        uboot就先写这么多吧,好多地方我也不是很清楚,希望以后在分析uboot源码的过程中可以深入理解。
        不知不觉就看完了韦东山老师视频的第一期,回头看看第二期视频的目录,主要讲驱动的,非常吸引人,并且和目前的项目需求比较贴近。于是我迫不及待的购买了第二期视频好好学习一下。
        最后聊聊韦东山老师的讲解风格吧,韦老师边讲解边写代码的风格非常棒,对于嵌入式高手来说些代码也许比较容易,但对于新手来说绝对是授人以渔方式的教学。以前经常在一些帖子里面仅仅只能看到“重要”代码,对于初学者来说这是很无奈的,因为你往往面对着大量代码的移植和修改工作,如无人指导的话,绝对是个噩梦的开始。但现在对于新手来说,咱们有了更好的选择。
    回复

    使用道具 举报

  • TA的每日心情
    擦汗
    2016-5-9 12:20
  • 签到天数: 350 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2015-5-22 10:17:01 | 显示全部楼层
    支持楼主!把学习历程都总结出来吧。
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-6-3 08:54 , Processed in 0.119858 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.