红联Linux门户
Linux帮助

墩子学嵌入式-入门之路

发布时间:2015-05-26 15:27:49来源:红联作者:xuanxuan170
少年易老学难成, 一寸光阴不可轻。
未觉池塘春草梦, 阶前梧叶已秋声。

《劝学》 朱熹


都说万事开头难,作为一名大学只接触过单片机,且多年未用的选手,我对这个难字深有感触。毕业以来一直都在做整体设计方案,对大学用过的单片机已放下多时,最近由于项目需要,俺要自己去使用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源码的过程中可以深入理解。
不知不觉就看完了韦东山老师视频的第一期,回头看看第二期视频的目录,主要讲驱动的,非常吸引人,并且和目前的项目需求比较贴近。于是我迫不及待的购买了第二期视频好好学习一下。
最后聊聊韦东山老师的讲解风格吧,韦老师边讲解边写代码的风格非常棒,对于嵌入式高手来说些代码也许比较容易,但对于新手来说绝对是授人以渔方式的教学。以前经常在一些帖子里面仅仅只能看到“重要”代码,对于初学者来说这是很无奈的,因为你往往面对着大量代码的移植和修改工作,如无人指导的话,绝对是个噩梦的开始。但现在对于新手来说,咱们有了更好的选择。
文章评论

共有 6 条评论

  1. STC89C51 于 2015-07-21 23:09:02发表:

    谢谢分享!

  2. 852741963 于 2015-07-19 23:56:53发表:

    感谢

  3. 15100499406 于 2015-07-17 11:54:31发表:

    谢谢

  4. 15100499406 于 2015-07-17 11:54:28发表:

    谢谢

  5. 15100499406 于 2015-07-17 11:54:25发表:

    谢谢

  6. zhang454579195 于 2015-05-27 21:43:06发表:

    (6)m:b