uboot第一阶段详细分析

2024-05-10 09:38:19
uboot第一阶段详细分析
作者:程姚根,华清远见嵌入式学院讲师。
uboot的第一阶段设计的非常巧妙,几乎都是用汇编语言实现的,下面我们一起来看看它的精妙之处吧!
首先我们来看一下它的链接脚本,通过它我们可以知道它整个程序的各个段是怎么存放的。
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
        OUTPUT_ARCH(arm)
        ENTRY(_start)
        SECTIONS
        {
                . = 0x00000000;
. = ALIGN(4);
                .text :
                {
                        cpu/arm920t/start.o        (.text)
                        *(.text)//所有的其他程序的代码段以四字节对齐放在它后面
                }
. = ALIGN(4);
                .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }//只读数据段
. = ALIGN(4);
                .data : { *(.data) }//指定读/写数据段
. = ALIGN(4);
                .got : { *(.got) }//指定got段,got段式是uboot自定义的一个段,非标准段
. = .;
                __u_boot_cmd_start = .;//把__u_boot_cmd_start赋值为当前位置,即起始位置
                .u_boot_cmd : { *(.u_boot_cmd) }//指定u_boot_cmd段,uboot把所有的uboot命令放在该段
                __u_boot_cmd_end = .;//把 __u_boot_cmd_end赋值为当前位置,即结束位置
. = ALIGN(4);
                __bss_start = .;//__bss_start赋值为当前位置,即bss段得开始位置
                .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
                _end = .;//把_end赋值为当前位置,即bss段得结束地址
        }
从它我们可以看到,uboot运行的第一个程序是cpu/arm920t/start.S,其他的都有注释,就不多说了。
下面我们来看看在fs2410上通过nor flash启动,u-boot的启动流程:
电源一上电之后,pc指针从0x00000000 地址开始执行,也就是说这个时候程序跑在nor flash里面(别忘记,nor flash这个时候接在0x00000000地址,它是可以执行程序的只是速度没有在ram里面执行快)
这个时候有人可能会问那s3c2410片内的4kRam映射到哪呢?通过查看芯片手册这个时候它在0x40000000,如下图:

(使用NOR FLASH启动,设备地址映射图)
现在我们知道是那个程序在哪里存储,从哪个地址运行,下面我们来看看这段程序的汇编代码:
在这里我们知道运行的第一条指令是b start_code,呵呵!看到这段代码的时候许多人都认为_start的值是0x00000000,为什么是这个地址呢? 因为连接脚本上指定了。真的是这样吗?我们来看看我们编译好之后,在u-boot目录下有个System.map,这里面有各个变量的值,如下图:
哈哈,_start的值怎么会是0x33f80000?这是因为在顶层的Makefile里面我们指定了它的连接地址。
看到那个 -o u-boot了吗,就是通过它生成ELF格式的u-boot的,里面有个LDFLAGS变量,它是什么呢,我们继续往下面看:
(顶层的config.mk里面有这个变量的说明)
看到了没有,LDFLAGS里面除了指定链接脚本,如果TEXT_BASE不等于空,还加上了-Ttext$(TEXT_BASE),TEXT_BASE的值是多少呢?我们可以在board/samsung/smdk2410/config.mk里面有定义,它的值为0x33f80000。这样我就可以知道为什么System.map的地址都是0x33f80000。
好我们来看第一条汇编指令b start_code,从System.map文件我们可以知道,这条指令相当于b 0x33f80050。"0x33f80050"?你是否有疑问,这个时候内存还没有初始化呢,怎么能跳到内存中去了(sdram的起始地址0x30000000)。呵呵,其实不是这样的。还记得b指令是相对跳转指令吗,它和代码的位置是无关的,这种精妙的设计才使得后面的指令能继续的执行。
下面我们继续来看它的汇编指令:
呵呵,这段汇编代码很好理解,就是设置CPU为 管理模式。
这段汇编代码就不分析了,这是跟atmel相关的,我不管它,继续下面:
这段汇编代码也很好理解,就是关掉看门狗,然后关掉所有中断。
哦哦,设置时钟,还记得一上电FCLK是多少吗,只有12MHZ。
呵呵!跳转指令,我们来看看它做了什么,这样我们先从名字上来猜猜它是什么意思?cpu初始化,初始化什么呢?继续向下看:
呵呵,有英文注释,清cache,关闭MMU。都是用协处理指令实现的,如果看不懂,可以看看协处理器指令。多了解一点就多知道一点,不是吗?
从上面可以看到,还有一次跳转bl lowlevel_init。这里面有干了一些什么呢,我们可以到board/samsung/smdk2410/ lowlevel_init.S去看。呵呵,这里我就不截图了,其实我们只有知道,它在这里面干了初始化内存操作。
继续往下面看:
呵呵,终于到重点部分了,代码重定向。下面我们来看看它到底是怎么重定向的:
Adr r0,_start
这条汇编指令的意思就是把_start当前代码存储的地址赋给r0,假如这段代码存储在SDRAM里面,那么r0的值就是0x30000000。现在这段代码存储在NOR Flash里面,所以r0的值就是
0x0000000
        Ldr r1,_TEXT_BASE
这条汇编指令的意思是把_TEXT_BASE的值作为地址,把这个地址的内容赋给r1,从下面可以知道:
_TEXT_BASE里面存储的内容是TEXT_BASE,也就是0x33f80000,所以r1的值就是0x33f80000
Cmp r0,r1
将r0和r1做比较,此时r0 = 0x0000000,r1 = 0x33f80000,显然不相等,那么执行的就是下面的汇编指令:
ldr r2, _armboot_start
由此可以知道r2的值是_start,也就是0x33f80000,也是整个代码的起始地址。
Ldr r3, _bss_start
由u-boot.lds的链接脚本可以知道,r3的值是整个代码得结尾.
Sub r2,r3,r2
这条指令的意思是r2 = r3 -r2,即r2 = 代码结束 - 代码开始,这样得到的是r2 = 代码的大小。
Add r2,r0,r2
这条指令的意思是r2 = r0 + r3,即 r2 = 代码开始 + 代码大小,这样得到的是r2 = nor falsh 里面代码的结尾
此时我们得到r0 = nor flash 代码的起始位置,r1 = 0x33f80000(sdram :0x300000000 ~ 0x34000000)
呵呵,这个时候代码就被从nor flash里面拷贝到sdram里面了。
这段代码的意思是设置一些堆栈
这段代码的意思是清bss段,
呵呵,终于看到pc指针的值被改变了。也就是这个时候,pc指针开始跳到sdram里面执行代码,这也就到了第二阶段(从语言阶段),后面的代码都是用C语言写得了。先分析到这里,下次我们看第二阶段。

转载于:https://blog.51cto.com/embedjee/739838

uboot第一阶段详细分析相关推荐

  1. U-BOOT启动流程详细分析[转]

    http://www.cnblogs.com/heaad/archive/2010/07/17/1779829.html U-Boot启动内核的过程可以分为两个阶段,两个阶段的功能如下: (1)第一阶 ...

  2. Uboot代码结构详细分析

    1. Bootloader功能分析 Bootloader(如Uboot.Redboot.Blob.vivi等)直接和CPU.外围硬件设备(存储器.网卡.LCD等)打交道,负责初始化硬件设备,以及负责拉 ...

  3. uboot启动流程详细分析(基于i.m6ull)

    uboot介绍 uboot就是一段引导程序,在加载系统内核之前,完成硬件初始化,内存映射,为后续内核的引导提供一个良好的环境.uboot是bootloader的一种,全称为universal boot ...

  4. ARMv8架构u-boot启动流程详细分析(一)

    文章目录 1 概述 2 armv8 u-boot的启动 3 u-boot源码整体结构和一些编译配置方式 3.1 编译配置方式 3.2 u-boot源码结构 4 u-boot armv8链接脚本 4.1 ...

  5. ARMv8架构u-boot启动流程详细分析(二)

    文章目录 1 u-boot在汇编启动阶段对系统的一些初始化 1.1 启动前为后续流程做的一些平台相关操作 1.2 开启地址无关后的重定位地址操作 1.3 进入_main之前系统寄存器初始化和从核的引导 ...

  6. 海思uboot启动流程详细分析(二)

    1. 第二个start.S 从start_armboot开始,在startup.c中有包含#include <config.h> 在config.h中: /* Automatically ...

  7. u-boot分析之两阶段代码分析(三)

    目录 u-boot(三)启动文件 1,概述 2,uboot第一阶段代码分析: 汇编 2,uboot第二阶段代码分析 C:_start_armboot C:main_loop u-boot(三)启动文件 ...

  8. uboot源码分析1-启动第一阶段

    笔者发现以前做的时候,不是很详细,现在回头看很多东西需要重新查~从这篇开始尽量写的详细,以前的慢慢补好. 慢慢更新~ 如有不足之处,希望大家多多指点. start.S引入 1.u-boot.lds中找 ...

  9. 嵌入式之uboot源码分析-启动第一阶段学习笔记

    注: 以下的内容来自朱老师物联网大讲堂uboot部分课件 Uboot启动第一阶段start.S执行步骤 1.头文件包含 <config.h>(x210的各种宏定义) <version ...

最新文章

  1. gcc 编译 java,编译lineage,gcc的版本问题
  2. 当用户将鼠标悬停在列表项上时,使光标成为手
  3. 自动配置IE代理脚本
  4. MySQL事务的特性及事务隔离级别演示
  5. html怎么改变一块区域颜色,更改HTML中所选区域的背景颜色/不透明度
  6. SpringCloud Config 分布式配置
  7. 联想sr950配置raid卡_联想ThinkServerrd服务器raid卡设置教程LSIiraid卡设置教程
  8. JSK-382 元音字母复制【入门】
  9. python---之round
  10. 拓端tecdat|R语言用回归构建配对交易(Pairs Trading)策略量化模型分析股票收益和价格
  11. 【Spring-AOP】底层类ProxyConfig,ProxyProcessorSupport分析
  12. yolov2 - tiny模型训练识别
  13. Unity引擎及编辑器C#源代码赏析(一)—目录结构
  14. PyQt——1. 简单认识PyQt及Python3.7安装QtDesigner
  15. 怎样区别桃花、杏花、梨花、樱花、梅花、李花
  16. 通过文件url地址获取base64;通过图片url地址获取base64;js获取文件的base64
  17. 听诊器的基本构造及其特征
  18. 41份艾媒舆情-舆情相关行业报告
  19. 写给湘大计算机相关专业的学弟学妹们
  20. HDU3666_差分约束

热门文章

  1. java二级考试真题_计算机等级考试真题2(JAVA)
  2. Vue2中$forceUpdate()的使用
  3. vim显示行号_使用 vim 不得不看的 2 个 tips
  4. markdown 图片居中_写作者必备技能:markdown 微信使用markdown
  5. JAVA指定范围生成随机数
  6. Maven项目有红叉,文件却没有错误,已解决
  7. Maven项目出现web.xml is missing and 《failOnMissingWebXml》is set to true,已解决
  8. 绿米开关如何重置_开个灯还带音效?跟我学简单改装智能开关,保证按上瘾!...
  9. weblogic集群部署与负载均衡_集群,负载均衡,分布式的讲解和多台服务器代码同步...
  10. 在sqlserver中创建表值函数