首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

墩子学嵌入式-入门之路

墩子学嵌入式-入门之路

少年易老学难成,   一寸光阴不可轻。

未觉池塘春草梦,   阶前梧叶已秋声。


《劝学》   朱熹



    都说万事开头难,作为一名大学只接触过单片机,且多年未用的选手,我对这个难字深有感触。毕业以来一直都在做整体设计方案,对大学用过的单片机已放下多时,最近由于项目需要,俺要自己去使用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源码的过程中可以深入理解。

    不知不觉就看完了韦东山老师视频的第一期,回头看看第二期视频的目录,主要讲驱动的,非常吸引人,并且和目前的项目需求比较贴近。于是我迫不及待的购买了第二期视频好好学习一下。

    最后聊聊韦东山老师的讲解风格吧,韦老师边讲解边写代码的风格非常棒,对于嵌入式高手来说些代码也许比较容易,但对于新手来说绝对是授人以渔方式的教学。以前经常在一些帖子里面仅仅只能看到“重要”代码,对于初学者来说这是很无奈的,因为你往往面对着大量代码的移植和修改工作,如无人指导的话,绝对是个噩梦的开始。但现在对于新手来说,咱们有了更好的选择。
返回列表