Hi,大家好!我是CrazyCatJack,你们可以叫我CCJ或者疯猫。今天我给大家带来的是u-boot的源代码汇编段分析,以后还会给大家讲解后续的C代码,请持续关注哦^_^

  先简单说一下u-boot,在嵌入式开发中,u-boot起着至关重要的作用:读出嵌入式系统内核并启动内核。因此非常有必要对u-boot进行理解,了解其是如何启动内核的,这样我们才能随心所欲地初始化系统,无论基于什么架构,什么开发板,都能够轻松的去启动内核。这一点难道不是最有吸引力的吗?

  如果大家有看到我的前一篇博客,就会对u-boot的启动有一定程度的了解了。执行u-boot,首先是从启动文件start.S开始的。它位于你所用CPU的文件下。比如我的路径就是:“uboot-1.1.6/cpu/arm920t/start.S”。这基于你具体使用的CPU架构。打开它:

 

  首先看第一条语句,跳转到reset语句执行。那我们来看reset。

  根据注释,我们知道是要先让CPU进入SVC32模式,也就是管理模式。具体的汇编代码不再分析,需要大家自己去学习。若是你已经掌握了一定的汇编,则完全可以阅读本篇博客,不然还是建议先学习一下汇编。u-boot代码量还是很大的,再接着往下来看:

  根据注释,我们要关闭看门狗,否则此时CPU会不断地重启重启。。。很明显,在定义了具体的SOC型号后,define寄存器地址。包括看门狗控制寄存器、中断屏蔽寄存器、还有时钟分频。关闭看门狗,关闭所有的中断。

  这里如果你是从NOR Flash启动的,这里的r0就是0。如果你是从下载器或者调试器直接将代码下载到SDRAM的,r0就为你自己设置的SDRAM代码段的启动地址(详情看我的上一篇博客)。这里会比较一下这两个地址是否相同,就可以知道你是从哪里启动的了,是从NOR Flash还是直接从SDRAM。如果你从SDRAM启动,则说明你已经初始化了SDRAM。如果你是从FLASH启动,则这里跳转到 cpu_init_crit函数执行。

  这里是关caches,关MMU,然后跳转到lowlevel_init函数执行开发板相关的配置。

  这一部分程序博主开始很不理解,因为这里涉及到了一个链接地址的概念。博主分不清此刻程序到底是在FLASH还是在RAM上。但是后来在论坛提问,大神给予了解答,博主终于懂了。这里的SMRDATA是即将在SDRAM存储的13个寄存器的链接地址,也就是说此刻这13个寄存器的值并未真正存储到SDRAM,而是在NOR FLASH中。但是我们用这个SDRAM上的寄存器链接地址减去SDRAM代码段开始地址(_TEXT_BASE),就得出了相对地址。又因为NOR FLASH的起始地址是0,所以起始地址+相对地址就是这13个寄存器在NOR FLASH上真正存储的开始地址。这段代码就是因为上述原因而进行的地址转换。目的是得到13个寄存器在NOR FLASH上存储的开始地址。

  

  我们接着分析,下一步根据注释是设置堆栈,将代码段地址给r0,这里我们设置的是0x33F80000.然后设置MALLOC段:分配空间,r0减去此段大小。再设置CFG_GBL_DATA段,同理r0减去此段大小,分配空间。再设置IRQ段、FIQ段。最后r0减去12,留出3个字节的空间。下一步是跳转到clock_init设置时钟。

  relocate这段代码是要将u-boot从FLASH复制到RAM。_start是当前代码的开始地址,_TEXT_BASE是代码段的链接地址,如果二者相等则证明是从RAM启动,无需复制代码。转去执行清BSS段代码。_armboot_start是在当前文件即start.S中定义的第一条指令的运行地址,_bss_start是在board/开发板型号/u-boot.lds中定义的代码段结束地址。结束地址减去开始地址等于代码段长度,赋值给r2。然后就是如果你是从FLASH启动则需进行代码赋值,这里是用C函数实现。

  这里我们设置的是USB48MHZ,总时钟400MHZ.根据代码,再接下来是清BSS段。

  所谓的BSS段就是未初始化的静态变量和全局变量,或者初始化为0的静态变量和全局变量。将他们存入只会浪费空间。所以用到他们的时候再去初始化。这里的清BSS段就是这样的作用。

  清完BSS段就是要复制代码到RAM。这里韦东山老师是自己用C语言实现的从FLASH到RAM程序的复制。因为版权原因,我们不便贴出。其实也是很容易的内存块复制。

  最后是进入到了_start_armboot。这是一个C函数,从这里开始就是用C来实现读出内核,启动内核了。硬件相关的汇编程序讲解结束!

版权声明:

本博客未经允许,禁止转载。

我尊重DENX Software Engineering为开源代码做出的贡献,他们做出u-boot,并将其开源供全世界的人们下载、学习和使用。

博主是跟随韦东山老师学习的嵌入式Linux开发,其中的CopyCode2Ram函数为韦东山老师编写。本文源于对学习成果的总结。

CCJ

2016-11-19   11:14:00

u-boot源码汇编段简要分析的更多相关文章

  1. Spring Boot源码分析-启动过程

    Spring Boot作为目前最流行的Java开发框架,秉承"约定优于配置"原则,大大简化了Spring MVC繁琐的XML文件配置,基本实现零配置启动项目. 本文基于Spring ...

  2. Spring Boot源码分析-配置文件加载原理

    在Spring Boot源码分析-启动过程中我们进行了启动源码的分析,大致了解了整个Spring Boot的启动过程,具体细节这里不再赘述,感兴趣的同学可以自行阅读.今天让我们继续阅读源码,了解配置文 ...

  3. 精尽Spring Boot源码分析 - 序言

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  4. 精尽Spring Boot源码分析 - Jar 包的启动实现

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  5. 精尽Spring Boot源码分析 - 文章导读

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  6. 精尽Spring Boot源码分析 - SpringApplication 启动类的启动过程

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  7. 精尽Spring Boot源码分析 - 内嵌Tomcat容器的实现

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  8. 精尽Spring Boot源码分析 - 支持外部 Tomcat 容器的实现

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  9. 精尽Spring Boot源码分析 - 剖析 @SpringBootApplication 注解

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

随机推荐

  1. web前端基础知识

    #HTML    什么是HTML,和他ML...    网页可以比作一个装修好了的,可以娶媳妇的房子.    房子分为:毛坯房,精装修    毛坯房的修建: 砖,瓦,水泥,石头,石子....    精 ...

  2. SQL Server-聚焦NOT IN VS NOT EXISTS VS LEFT JOIN...IS NULL性能分析(十八)

    前言 本节我们来综合比较NOT IN VS NOT EXISTS VS LEFT JOIN...IS NULL的性能,简短的内容,深入的理解,Always to review the basics. ...

  3. geotrellis使用(二十八)栅格数据色彩渲染(多波段真彩色)

    目录 前言 实现过程 总结 一.前言        上一篇文章介绍了如何使用Geotrellis渲染单波段的栅格数据,已然很是头疼,这几天不懈努力之后工作又进了一步,整清楚了如何使用Geotrelli ...

  4. 代码的坏味道(20)——过度耦合的消息链(Message Chains)

    坏味道--过度耦合的消息链(Message Chains) 特征 消息链的形式类似于:obj.getA().getB().getC(). 问题原因 如果你看到用户向一个对象请求另一个对象,然后再向后者 ...

  5. SOLID 设计原则

    SOLID 原则基本概念: 程序设计领域, SOLID (单一功能.开闭原则.里氏替换.接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期 引入的记忆术首字母缩略字,指代了面向对象编程和面向对象 ...

  6. JQuery实现表格的增加行和删除行

    利用JQuery实现datatables插件的增加和删除行操作 在学习过程中遇到了这个利用JQuery对表格行的增加和删除,特记录下来以供初学者参考. 下面是主要的代码: <meta http- ...

  7. Web开发安全之文件上传安全

    很长一段时间像我这种菜鸡搞一个网站第一时间反应就是找上传,找上传.借此机会把文件上传的安全问题总结一下. 首先看一下DVWA给出的Impossible级别的完整代码: <?php if( iss ...

  8. 跟着老男孩教育学Python开发【第四篇】:模块

    双层装饰器示例 __author__ = 'Golden' #!/usr/bin/env python # -*- coding:utf-8 -*-   USER_INFO = {}   def ch ...

  9. web前端开发分享-目录

    1. web前端开发分享-css,js入门篇 2. web前端开发分享-css,js进阶篇 3. web前端开发分享-css,js提高篇 4. web前端开发分享-css,js工具篇 5. web前端 ...

  10. 在Linux和Windows平台上操作MemoryMappedFile(简称MMF)

    操作系统很早就开始使用内存映射文件(Memory Mapped File)来作为进程间的共享存储区,这是一种非常高效的进程通讯手段..NET 4.0新增加了一个System.IO. MemoryMap ...