iTop4412的uboot第一阶段

iTop4412的uboot第一阶段
iTop4412的uboot第一阶段

2

uboo

t

源码分析

2.5.1.star t.S

2.5.1.star t.S 引入引入

2.5.1.1、u-boot.lds中找到start.S入口

(1)在C语言中整个项目的入口就是 main函数(这是

个.c文件的项目,第一个要分析的文件就是包含了C语言规定的),所以譬如说一

个有

main函数的那个文件。

10000

( 2 方。ENTRY(_start)因此

_start

符号所在的文件就是整个程序的起始文

件,

_sta

rt

所在处的

代码就是整个程序的起始代码。

2.5.1.2、SourceInsight中如何找到

文件

(1)当前状况:我们知道在uboot中的1000多个文件中有一个符号

_start,但是我们不知道

这个符号在哪个文件中。这种情况下要查找一个符号在所有项目中文件中的引用,要使用SourceInsight的搜索功能。

(2)start.s 在cpu/arm_cortexa9/start.s

(3)然后进入start.S文件中,发现

个uboot的入口代码,就是第57 57行中就

是行。_sta

rt

标号的定义处,于是乎我们就找到了整

2.5.1.3、SI中找文件技巧

(1)以上,找到了start.S文件,下面我们就从start.S文件开始分析uboot第一阶段。

(2)在SI中,如果我们知道我们要找的文件的名字,但是我们又不知道他在哪个目录下,我

们要怎样找到并打开这个文件?方法是在 SI中先打开右边的工程项目管理栏目,然后点击

最左边那个(这个是以文件为单位来浏览的),然后在上面输入栏中输入要找的文件的名

字。我们在输入的时候,SI在不断帮我们进行匹配,即使你不记得文件的全名只是大概记

得名字,也能帮助你找到你要找的文件。

2.5.2.start.S解析1

2.5.2.1、不简单的头文件包含

(1)#include。config.h是在include目录下的,这个文件不是源码中本身存在的文件,而是配置过程中自动生成的文件。这个文件的内容其实是包含了下面3个头文件

(2)

经过分析后,这3个头文件,这个文件是整个uboot移植时的配置文件。这里面是

因此这个头文件包含将这三个文件和start.S文件关联了起来。因此之后在分析时,主要要考虑的就是include/configs/itop_4412_android.h 文件。

好多宏。start.S文件

(3)

#include。include/version.h 中包含了include/version_autogenerated.h ,这个头文

件就是配置过程中自动生成的。里面就一行内容:#define U_BOOT_VERSION"U-Boot 2010.03"。如下图所示。这里面定义的

U_BOOT_VERSION的值是一个字符串,字符串中的

版本号信息来自于Makefile中的配置值。

这个宏在程序中会被调用,在uboo

t 启动过程中会串口打印

uboo

t

的版本号,那个版本号

信息就是从这来的。

(4)在include/configs/itop_4412_android.h 中定义了CONFIG_ENABLE_MMU

#include。asm目录不是uboot中的原生目录,uboot中本来是没有这

个目录的。asm目录是配置时创建的一个符号链接,实际指向的是就是asm-arm(详解上一

章节分析 mkconfig脚本时).

(5)经过分析后发现,实际文件是:include/asm-arm/proc-armv/domain.h

(6)从这里可以看出之前配置时创建的符号链接的作用,如果没有这些符号链接则编译时根

本通不过,因为找不到头文件。(所以uboot不能在windows的共享文件夹下配置编译,因

为windows中没有符号链接)

思考:为什么start.S不直接包含asm-arm/proc-armv/domain.h,而要用asm/proc/domain.h。

这样的设计主要是为了可移植性。因为如果直接包含,则start.S文件和CPU架构(和硬件)

有关了,可移植性就差了。譬如我要把uboot移植到mips架构下,则start.S源代码中所有

的头文件包含全部要修改。我们用了符号链接之后,则start.S中源代码不用改,只需要在

具体的硬件移植时配置不同,创建的符号链接指向的不同,则可以具有可移植性。

2.5.

3.start.S解析2

2.5.

3.1、启动代码的16字节头部

(1)在SD卡启动/Nand启动等整个镜像开头需要16字节的校验头。(mkv210image.c中就是

为了计算这个校验头)。我们以前做裸机程序时根本没考虑这16字节校验头,因为:1、如

果我们是 usb启动直接下载的方式启动的则不需要16字节校验头( iromapplicationnote);

2、如果是 SD卡启动mkv210image.c中会给原镜像前加16字节的校验头。

(2)uboot这里start.S中在开头位置放了16字节的填充占位,这个占位的16字节只是保证

正式的image的头部确实有16字节,但是这16字节的内容是不对的,还是需要后面去计算校

验和然后重新填充的。

2.5.

3.2、异常向量表的构建

(1)异常向量表是硬件决定的,软件只是参照硬件的设计来实现它。

(2)异常向量表中每种异常都应该被处理,否则真遇到了这种异常就跑飞了。但是我们在

uboot中并未非常细致的处理各种异常。

(3)复位异常处的代码是:breset,因此在CPU复位后真正去执行的有效代码是reset处的代

码,因此reset 符号处才是真正的有意义的代码开始的地方。 2.5.3.3、有点意思的

deadbeef

(1).balignl16,0xdeadbeef.这一句指令是让当前地址对齐排布,

向后走地址直到对齐,并且向后走的那些内存要用

0xdeadbee f

如果当前地址不对齐则自动来填充。

(2)0xdeadbeef 这是一个十六进制的数字,这个数字很有意思,组成这个数字的十六进制数 全是abcdef 之中的字母,而且这8个字母刚好组成了英文的deadbeef 这两个单词,字面意思是坏牛肉。

(3)为什么要对齐访问?有时候是效率的要求,有时候是硬件的特殊要求。 2.5.3.4、TEXT_BASE 等

(1)第100行这个 TEXT_BASE 就是上个课程中分析

Makefile 时讲到的那个配置阶段的

TEXT_BASE ,其实就是我们链接时指定的 uboot 的链接地址。(值就是 c3e00001) (2)源代码中和配置Makefile 中很多变量是可以互相运送的。简单来说有些符号的值可以从Makefile 中传递到源代码中。

2.5.4.start.S 解析3

(1)CFG_PHY_UBOOT_BASE33e00000 uboot 在DDR 中的物理地址

2.5.4.1、设置CPU 为SVC 模式

(1)msr cpsr_c,#0xd3将CPU 设置为禁止 FIQIRQ ,ARM 状态,SVC 模式。 (2)其实ARMCPU 在复位时默认就会进入 SVC 模式,但是这里还是使用软件将其置为

式。整个 uboot 工作时CPU 一直处于 SVC 模式。

SVC 模

2.5.4.2、设置L2、L1cache 和MMU

(1)bldisable_l2cache // 禁止L2cache

(2)blset_l2cache_auxctrl_cy cle //l2cache 相关初始化 (3)blenable_l2cache // 使能l2cache (4)刷新L1cache 的icache 和dcache 。

(5)关闭MMU

总结:上面这 5步都是和 CPU 的cache 和mmu 有关的,不用去细看,大概知道即可。

2.5.4.3、识别并暂存启动介质选择

(1)从哪里启动是由SoC的OM5:OM0这6个引脚的高低电平决定的。

(2)实际上在我们芯片内部有一个寄存器(地址是 0x10020000),这个寄存器中的值是硬件根据OM引脚的设置而自动设置值的。这个值反映的就是OM引脚的接法(电平高低),也就是真正的启动介质是谁。

(3)我们代码中可以通过读取这个寄存器的值然后判断其值来确定当前选中的启动介质是

Nand还是SD还是其他的。

(4)start.S的0行执行完后,在r2寄存器中存储了一个数字,这个数字等于某个特定值时就表示SD启动,等于另一个特定值时表示从Nand启动····

(5)260行中给r3中赋值#BOOT_MMCSD(0x03),这个在SD启动时实际会被执行,因此执行完这

一段代码后r3中存储了0x03,以后备用。

2.5.4.4、设置栈(SRAM中的栈)并调用lowlevel_init

(1)第一次设置栈。这次设置栈是在SRAM中设置的,因为当前整个代码还在SRAM中运行,此时DDR还未被初始化还不能用。栈地址_TEXT_PHY_BASE是自己指定的,指定的原则就是这块空间只给栈用,不会被别人占用。

(2)在调用函数前初始化栈,主要原因是在被调用的函数内还有再次调用函数,而

返回地址存储到LR中,但是我们只有一个LR,所以在第二层调用函数前要先将

否则函数返回时第一层的返回地址就丢了。????BL只会将LR入栈,

我们的uboot中没有两次设置栈

2.5.5.start.S解析4

(1)使用 SourceInsight的 Reference功能,找到lowlevel_init函数真正的地方,是在

uboot/board/samsumg/smdkc210/lowlevel_init_scp.S中。因为在MKconfig中产生了软链接。这一点跟视频中有点不一样

2.5.5.1、检查复位状态

(1)复杂CPU允许多种复位情况。譬如直接冷上电、热启动、睡眠(低功

)状态下的唤醒等,

这些情况都属于复位。所以我们在复位代码中要去检测复位状态,来判断到底是哪种情况。

(2)判断哪种复位的意义在于:冷上

电时

DDR是需要初始化才能用的;而热启动或者低功耗

状态下的复位则不需要再次初始化

2.5.5.2、IO状态恢复itop4412 DDR。

没有这个代码

(1)这个和上一个和主线启动代码都无关,因此不用去管他。

2.5.5.3、关看门狗

(1)参考裸机中看门狗章节

2.5.5.4、一些SRAMSROM相关GPIO设置

(1)与主线启动代码无关,不用管

2.5.5.5、供电锁存

(1)lowlevel_init.S的第100-104行,开发板供电锁存。

总结:在前100行,lowlevel_init.S中并没有做太多有意义的事情(除了关看门狗、供

电锁存外),然后下面从110行才开始进行有意义的操作。

2.5.6.start.S解析5

2.5.6.1、判断当前代码执行位置

(1)lowlevel_in

it.S

的110-

115

行。

(2)这几行代码的作用就是判定当前代码执行的位置在SRAM中还是在DDR中。为什么要做

这个判定?原因1:BL1(uboot的前一部分)在SRAM中有一份,在DDR中也有一份,因

此如果是冷启动那么当前代码应该是在SRAM中运行的BL1,如果是低功耗状态的复位这时候

应该就是在DDR中运行的。原因2:我们判定当前运行代码的地址是有用的,可以指导后面代

码的运行。譬如在lowlevel_init.S中判定当前代码的运行地址,就是为了确定要不要执行时

钟初始化和初始化DDR的代码。如果当前代码是在SRAM中,说明冷启动,那么时钟

和DDR都需要初始化;如果当前代码是在DDR中,那么说明是热启动则时钟和DDR都不用再次

初始化。

(2)bic

位赋值

r1,pc,r0这句代码的意义是:将pc的值中的某些bit位

r1(r0中为1的那些位清零)相等于: r1=pc&~(ff000fff)

0,剩下一些特殊

bit

ld

r

r2,_TEXT_BASE 加载链接地址

r2,然后

r

2

的相应位

0剩下特定位。

(3)最后比

r

1

和r2.

总结:这一段代码是通过读取当前运行地址和链接地址,然后处理两个地址后对比是否相等,来判定当前运行是在SRAM中(不相等)还是DDR中(相等)。从而决定是否跳过下面的时钟和DDR初始化。

2.5.6.2、system_clock_init

(1)这个初始化时钟的过程是用汇编代码写的。

(2)在include/configs/itop_4412_android.h 中,有和时钟相关的配置值。这些宏定义就决定了210的时钟配置是多少。也就是说代码在lowlevel_init.S中都写好了,但是代码的设置值都

被宏定义在 include/configs/itop_4412_android.h 中了。因此,如果移植时需要更改CPU的时

钟设置,根本不需要动代码,只需要在include/configs/itop_4412_android.h中更改配置

值即可。但需要看懂芯片手册才能改这些值。

2.5.7.start.S解析6

2.5.7.1、mem_ctrl_asm_init

(1)该函数用来初始化DDR

(2)函数位置在cpu/arm_cortexa9/s5pc210/cpu_init.S 文件中。

(3)该函数和裸机中初始化DDR代码是一样的。实际上裸机中初始化DDR的代码就是从这里抄的。配置值也可以从这里抄,但是当时我自己根据理解+抄袭整出来的一份。

(4)配置值中其他配置值参考裸机中的解释即可明白,有一个和裸机中讲的不一样。

DMC0_MEMCONFIG_0,在裸机中配置值为0x20E01323;在uboot中配置为0x30F01313.这个配置不同就导致结果不同。(没有裸机视频)

在裸机中DMC0的256MB内存地址范围是0x20000000-0x2FFFFFFF;

在uboot中DMC0的256MB内存地址范围为0x30000000-0x3FFFFFFF

我们的内存地址不一样、

(5)之前在裸机中时配置为 2开头的地址,当时并没有说可以配置为3开头。从分析九鼎移植的uboot可以看出:DMC0上允许的地址范围是20000000-3FFFFFFF(一共是512MB),而我们实际只接了256MB物理内存,SoC允许我们给这256MB挑选地址范围。

(6)总结一下:在uboot中,可用的物理地址范围为:0x30000000-0x4FFFFFFF。一共512MB,其中30000000-3FFFFFFF为DMC0,40000000-4FFFFFFF为DMC1。

所以我们的板子在uboot中,可用的物理地址范围为:0x40000000-0x4FFFFFFF。一共512MB,其中40000000-4FFFFFFF为DMC0,50000000-5FFFFFFF为DMC1。

(7)我们需要的内存配置值在 x210_sd.h的438行到468行之间。分析的时候要注意条件编译

的条件,配置头文件中考虑了不同时钟配置下的内存配置值,这个的主要目的是让不同时钟需求的客户都能找到合适自己的内存配置值。

(8)在uboot中DMC0和DMC1都工作了,所以在裸机中只要把uboot中的配置值和配置代码全部移植过去,应该是能够让DMC0和DMC1都工作的。

2.5.7.2、uart_asm_init

(1)这个函数用来初始化串口

(2)初始化完了后通过串口发送了一个 'O'

2.5.7.3、tzpc_init

(1)trustzone初始化,没搞过,不管

2.5.7.4、pop{pc}以返回

(1)返回前通过串口打

'K'

分析;lowlevel_init.S 执行完如果没错那么就会串口打印出"OK"字样。这应该是我

uboot

中看到的最早的输出信息。

2.5.8.star t.S 解

7

总结回顾:lowlevel_init.S中总共做了哪些事情:

检查复位状态、IO恢复、关看门狗、开发板供电锁存、时钟初始化、DDR初始化、串口初始化并打印'O'、tzpc初始化、打印'K'。

其中值得关注的:关看门狗、开发板供电锁存、时钟初始化、DDR初始化、打印"OK" 2.5.8.1、再次设置

栈(

DDR中的栈)

(1)再次开发板供电锁存。第一,做2次是不会错的;第二,

2次则

2次无意义;做代

码移植时有一个古怪谨慎保守策略就是尽量添加代码而不要删除代码。

(2)之前在调用lowlevel_init程序前设置过1次栈(start.S284-287行),那时候因为DDR尚未

初始化,因此程序执行都是在SRAM中,所以在SRAM中分配了一部分内存作为栈。本次因

为DDR已经被初始化了,因此要把栈挪移到DDR中,所以要重新设置栈,这是第二次

(start.S297-299行);这里实际设置的栈的地址是43E00000,刚好在uboot的代码段的下面紧挨着。

(3)为什么要再次设置栈?DDR已经初始化了,已经有大片内存可以用了,没必要再把栈放

在SRAM中可怜兮兮的了;原来SRAM中内存大小空间有限,栈放在那里要注意不能使用过

多的栈否则栈会溢出,我们及时将栈迁移到DDR中也是为了尽可能避免栈使用时候的小心

翼翼。

感慨:uboot的启动阶段主要技巧就在于小范围内有限条件下的辗转腾挪。

2.5.8.2、再次判断当前地址以决定是否重定位

(1)再次用相同的代码判断运行地址是在次判断是为了决定是否要执行初始化时钟和SRAM中还是DDR中,不过本次判断的目的不同(上DDR的代码)这次判断是为了决定是否进行

uboo

t

的relocate。

(2)冷启动时当前情况是uboot的前一部分(16kb或者8kb)开机自动从SD卡加载到SRAM

中正在运行,uboot的第二部分(其实第二部分是整个uboot)还躺在SD卡的某个扇区开头

的N个扇区中。此时uboot的第一阶段已经即将结束了(第一阶段该做的事基本做完了),结束之前要把第二部分加载到DDR中链接地址处(43e00000),这个加载过程就叫重定位。

2.5.9.uboot重定位详解

(1)D0037488这个内存地址在SRAM中,这个地址中的值是被硬件自动设置的。硬件根据我

们实际电路中SD卡在哪个通道中,会将这个地址中的值设置为相应的数字。譬如我们从SD0通道启动时,这个值为EB000000;从SD2通道启动时,这个值为EB200000

(2)我们在start

.S

的260行确定了

MMCSD启动,然后又在278行将#BOOT_MMCSD写入了

INF_REG3寄存器中存储着。然后又在322行读出来,再和#BOOT_MMCSD去比较,确定是

从MMCSD启动。最终跳转到mmcsd_boot函数中去执行重定位动作。

(3)真正的重定位是通过调用 movi_uboot_copy 函数完成的,在uboot/cpu/s5pc11x/movi.c 中。是一个C语言的函数

(4)copy_bl2(2,MOVI_BL2_POS,MOVI_BL2_BLKCNT,

CFG_PHY_UBOOT_BASE,0);

分析参数:MOVI_BL2_POS是uboot的第二部分在SD卡中的开始扇区,这个扇区数字必须和烧

录uboot时烧录的位置相同;MOVI_BL2_BLKCNT是uboot的长度占用的扇区数;

CFG_PHY_UBOOT_BASE是重定位时将uboot的第二部分复制到DDR中的起始地址

(43E00000).

2.5.10.start.S解析8

2.5.10.1、什么是虚拟地址、物理地址

(1)物理地址就是物理设备设计生产时赋予的地址。像裸机中使用的寄存器的地址就是CPU 设计时指定的,这个就是物理地址。物理地址是硬件编码的,是设计生产时确定好的,一旦确定了就不能改了。

(2)一个事实就是:寄存器的物理地址是无法通过编程修改的,是多少就是多少,只

能通过查询数据手册获得并操作。坏处就是不够灵活。一个解决方案就是使用虚拟

地址。

(3)虚拟地址意思就是在我们软件操作和硬件被操作之间增加一个层次,叫做虚拟地址

映射层。有了虚拟地址映射后,软件操作只需要给虚拟地址,硬件操作还是用原来的

物理地址,

映射层建立一个虚拟地址到物理地址的映射表。当我们软件运行的时候,软件中使用的虚拟

地址在映射表中查询得到对应的物理地址再发给硬件去执行(虚拟地址到物理地址的映射是

不可能通过软件来实现的)。

https://www.360docs.net/doc/256841720.html,/xmlrpc.php?r=blog/article&uid=22891521&id=2109284

2.5.10.2、MMU单元的作用

(1)MMU就是memorymanagementunit,内存管理单元。MMU实际上是SOC中一个硬件单元,它

的主要功能就是实现虚拟地址到物理地址的映射。

(2)MMU单片在CP15协处理器中进行控制,也就是说要操控MMU进行虚拟地址映射,方

法就是对cp15协处理器的寄存器进行编程。

2.5.10.3、地址映射的额外

收益

1:访问控制

(1)访问控制就是:在管理上对内存进行分块,然后每块进行独立的虚拟地址映射,然后在

每一块的映射关系中同时还实现了访问控制(对该块可读、可写、只读、只写、不可

访问等控制)

(2)回想在C语言中编程中经常会出现一个错误: Segmentationfault。实际上这个段错误就

MMU实现的访问控制有关。当前程序只能操作自己有权操作的地址范围(若干个内存块)

,如果当前程序指针出错访问了不该访问的内存块则就会触发段错误。

2.5.10.4、地址映射的额外收益2:cache

(1)cache的工作和虚拟地址映射有关系。

(2)cache是快速缓存,意思就是比 CPU慢但是比DDR块。CPU嫌DDR太慢了,于是乎把一

些DDR中常用的内容事先读取缓存在cache中,然后 CPU每次需要找东西时先在cache

找。如果 cache中有就直接用 cache中的;如果 cache中没有才会去 DDR中寻找。

参考阅读:https://www.360docs.net/doc/256841720.html,/xmlrpc.php?r=blog/article&uid=22891521&id=2109284

2.5.11.star t.S 解

9

2.5.11.1、使能域访问(cp15的c3寄存器)

(1)cp15协处理器内部有 c0到c15共16个寄存器,这些寄存器每一个都有自己的作用。我

们通过mrc和mcr指令来访问这些寄存器。所谓的操作 cp协处理器其实就是操作cp15的这

些寄存器。

(2)c3寄存器在mmu中的作用是控制域访问。域访问是和MMU的访问控制有关的。

2.5.11.2、设置TTB(cp15的c2寄存器)

(1)TTB就是

translationtable base,转换表基地址。首先要明白什么是

TT (translationtable

转换表),TTB其实就是转换表的基地址。

(2 )转换表是建立一套虚拟地址映射的关键。转换表

分2部分,表索引和表项。表索引对应

虚拟地址,表项对应物理地址。一对表索引和表项构成一个转换表单

元,能够对一个内存块

进行虚拟地址转换。(映射中基本规定中规定了内存映射和管理是以块为单位的,至于块有

多大,要看你的MMU的支持和你自己的选择。在ARM中支持3种块大小,细表1KB、粗表4KB、段1MB)。真正的转换表就是由若干个转换表单元构成的,每个单元负责1个内存

块,总体的转换表负责整个内存空间(0-4G)的映射。

(3 )整个建立虚拟地址映射的主要工作就是建立这张转换表

(4 )转换表放置在内存中的,放置时要求起始地址在内存

中要xx位对齐。转换表不需要软件

去干涉使用,而是将基地址TTB设置到cp15的c2寄存器中,然后MMU工作时会自动去查转换表。

2.5.11.3、使能MMU单元(cp15的c1寄存器)

(1)cp15的c1寄存器的bit0控制MMU的开关。只要将这一个bit置1即可开启MMU。开启MMU之后上层软件层的地址就必须经过TT的转换才能发给下层物理层去执行。

2.5.11.4、找到映射表待分析

(1)通过符号查找,确定转换表在lowlevel_init.S文件的593行。

2.5.12.start.S解析10

2.5.12.1、宏FL_SECTION_ENTRY

0x200 512Mb

2.5.12.2、页表项各bit位含义

2.5.12.3、段式页表详解

2.5.12.4、实验操作验证

2.5.12.5、总结:关于MMU和虚拟地址映射的学习

宏观上理解转换表:整个转换表可以看作是一个int类型的数组,数组中的一个元素就是一个表索引和表项的单元。数组中的元素值就是表项,这个元素的数组下标就是表索引。

ARM的段式映射中长度为1MB,因此一个映射单元只能管1MB内存,那我们整个4G范围内需要4G/1MB=4096个映射单元,也就是说这个数组的元素个数是4096.实际上我们做的时候并没有依次单个处理这4096个单元,而是把4096个分成几部分,然后每部分用for循环做相同的处理。

2.5.1

3.start.S解析11

2.5.1

3.1、再次设置栈

(1)第三次设置栈。这次设置栈还是在DDR中,之前虽然已经在DDR中设置过一次栈了,但是本次设置栈的目的是将栈放在比较合适(安全,紧凑而不浪费内存)的地方。

(2)我们实际将栈设置在 uboot起始地址上方2MB处,这样安全的栈空间是:2MB-uboot大小-0x1000=1.8MB左右。这个空间既没有太浪费内存,又足够安全。

2.5.1

3.2、清理bss

(1)清理bss段代码.注意表示bss段的开头和结尾地址的符号是从链接脚

u-boot.lds得来

的。(不懂清理bss段代码的作用)

2.5.1

3.3、ldr pc,_start_armboot

(1)start_armboot 是uboot/lib_arm/board.c 中,这是一个C语言实现的函数。这个函数就是

uboot的第二阶段。这句代码的作用就是将uboot第二阶段执行的函数的地址传给pc,实际

上就是使用一个远跳转直接跳转到DDR中的第二阶段开始地址处。

(2)远跳转的含义就是这句话加载的地址和当前运行地址无关,而和链接地址有关。

因此这个远跳转可以实现从SRAM中的第一阶段跳转到DDR中的第二阶段。

(3)这里这个远跳转就是uboot第一阶段和第二阶段的分界线。

2.5.1

3.4、总结:uboot的第一阶段做了哪些工作

(1)构建异常向量表

(2)设置CPU为SVC模式

(3)关看门狗

(4)开发板供电置锁

(5)时钟初始化

(6)DDR初始化

(7)串口初始化并打印"OK"

(8)重定位

(9)建立映射表并开启MMU

(10)跳转到第二阶段

u-boot启动分析

背景: Board →ar7240(ap93) Cpu →mips 1、首先弄清楚什么是u-boot Uboot是德国DENX小组的开发,它用于多种嵌入式CPU的bootloader程序, uboot不仅支持嵌入式linux系统的引导,当前,它还支持其他的很多嵌入式操作系统。 除了PowerPC系列,还支持MIPS,x86,ARM,NIOS,XScale。 2、下载完uboot后解压,在根目录下,有如下重要的信息(目录或者文件): 以下为为每个目录的说明: Board:和一些已有开发板有关的文件。每一个开发板都以一个子目录出现在当前目录中,子目录存放和开发板相关的配置文件。它的每个子文件夹里都有如下文件(以ar7240/ap93为例): Makefile Config.mk Ap93.c 和板子相关的代码 Flash.c Flash操作代码 u-boot.lds 对应的链接文件 common:实现uboot命令行下支持的命令,每一条命令都对应一个文件。例如bootm命令对应就是cmd_bootm.c cpu:与特定CPU架构相关目录,每一款Uboot下支持的CPU在该目录下对应一个子目录,比如有子目录mips等。它的每个子文件夹里都有入下文件: Makefile Config.mk Cpu.c 和处理器相关的代码s Interrupts.c 中断处理代码 Serial.c 串口初始化代码 Start.s 全局开始启动代码 Disk:对磁盘的支持

Doc:文档目录。Uboot有非常完善的文档。 Drivers:Uboot支持的设备驱动程序都放在该目录,比如网卡,支持CFI的Flash,串口和USB等。 Fs:支持的文件系统,Uboot现在支持cramfs、fat、fdos、jffs2和registerfs。 Include:Uboot使用的头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。该目下configs目录有与开发板相关的配置文件,如 ar7240_soc.h。该目录下的asm目录有与CPU体系结构相关的头文件,比如说mips 对应的有asm-mips。 Lib_xxx:与体系结构相关的库文件。如与ARM相关的库放在lib_arm中。 Net:与网络协议栈相关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。 Tools:生成Uboot的工具,如:mkimage等等。 3、mips架构u-boot启动流程 u-boot的启动过程大致做如下工作: 1、cpu初始化 2、时钟、串口、内存(ddr ram)初始化 3、内存划分、分配栈、数据、配置参数、以及u-boot代码在内存中的位置。 4、对u-boot代码作relocate 5、初始化malloc、flash、pci以及外设(比如,网口) 6、进入命令行或者直接启动Linux kernel 刚一开始由于参考网上代码,我一个劲的对基于smdk2410的板子,arm926ejs的cpu看了N 久,启动过程和这个大致相同。 整个启动中要涉及到四个文件: Start.S →cpu/mips/start.S Cache.S →cpu/mips/cache.S Lowlevel_init.S →board/ar7240/common/lowlevel_init.S Board.c →lib_mips/board.c 整个启动过程分为两个阶段来看: Stage1:系统上电后通过汇编执行代码 Stage2:通过一些列设置搭建了C环境,通过汇编指令跳转到C语言执行. Stage1: 程序从Start.S的_start开始执行.(至于为什么,参考u-boot.lds分析.doc) 先查看start.S文件吧!~ 从_start标记开始会看到一长串莫名奇妙的代码:

UBOOT命令详解

常用U-boot命令详解(z) 2010-09-30 15:05:52| 分类:学习心得体会|字号订阅 U-boot发展到现在,他的命令行模式已经非常接近Linux下的shell了,在我编译的 U-boot-2009.11中的命令行模式模式下支持“Tab”键的命令补全和命令的历史记录功能。而且如果你输入的命令的前几个字符和别的命令不重复,那么你就只需要打这几个字符即可,比如我想看这个U-boot的版本号,命令就是“ version”,但是在所有的命令中没有其他任何一个的命令是由“v”开头的,所以只需要输入“v”即可。 [u-boot@MINI2440]# version U-Boot 2009.11 ( 4月04 2010 - 12:09:25) [u-boot@MINI2440]# v U-Boot 2009.11 ( 4月04 2010 - 12:09:25) [u-boot@MINI2440]# base Base Address: 0x00000000 [u-boot@MINI2440]# ba Base Address: 0x00000000 由于U-boot支持的命令实在太多,一个一个细讲不现实,也没有必要。所以下面我挑一些烧写和引导常用命令介绍一下,其他的命令大家就举一反三,或者“help”吧! (1)获取帮助 命令:help 或? 功能:查看当前U-boot版本中支持的所有命令。 [u-boot@MINI2440]#help ?- alias for'help' askenv - get environment variables from stdin base - print or set address offset bdinfo - print Board Info structure bmp - manipulate BMP image data boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootelf - Boot from an ELF image in memory bootm - boot application image from memory bootp - boot image via network using BOOTP/TFTP protocol

Tiny6410_Uboot移植步骤详解

Uboot_for_Tiny6410_移植步骤详解 一、设计要求 1.目的 1)掌握U-boot剪裁编写 2)掌握交叉编译环境的配置 3)掌握U-boot的移植 2.实现的功能 1)U-boot编译成功 2)移植U-boot,使系统支持从NAND FLASH启动 二、设计方案 1.硬件资源 1)ARM处理器:ARM11芯片(Samsung S3C6410A),基于ARM1176JZF-S核设 计,运行频率533Mhz,最高可达 667Mhz 2)存储器:128M DDR RAM,可升级至 256M;MLC NAND Flash(2GB) 3)其他资源:具有三LCD接口、4线电阻 触摸屏接口、100M标准网络接口、标准DB9 五线串口、Mini USB2.0接口、USB Host 1.1、3.5mm音频输入输出口、标准TV-OUT

接口、SD卡座、红外接收等常用接口;另外 还引出4路TTL串口,另1路TV-OUT、 SDIO2接口(可接SD WiFi)接口等;在板的 还有蜂鸣器、I2C-EEPROM、备份电池、A D 可调电阻、8个中断式按键等。 2.软件资源 1)arm-linux-gcc-4.5.1(交叉编译) 2)u-boot-2010.09.tar.gz arm-linux-gcc-4.5.1-v6-vfp-20101103.t gz 三、移植过程 1.环境搭建 1)建立交叉编译环境 2)去这2个网站随便下载都可以下载得到最 新或者你想要的u-boot。( https://www.360docs.net/doc/256841720.html,/batch.viewl ink.php?itemid=1694 ftp://ftp.denx.de/pub/u-boot/ )

AM335x uboot spl分析

AM335x uboot spl分析 芯片到uboot启动流程 ROM → SPL→ uboot.img 简介 在335x 中ROM code是第一级的bootlader。mpu上电后将会自动执行这里的代码,完成部分初始化和引导第二级的bootlader,第二级的bootlader引导第三级bootader,在 ti官方上对于第二级和第三级的bootlader由uboot提供。 SPL To unify all existing implementations for a secondary program loader (SPL) and to allow simply adding of new implementations this generic SPL framework has been created. With this framework almost all source files for a board can be reused. No code duplication or symlinking is necessary anymore. 1> Basic ARM initialization 2> UART console initialization 3> Clocks and DPLL locking (minimal) 4> SDRAM initialization 5> Mux (minimal) 6> BootDevice initialization(based on where we are booting from.MMC1/MMC2/Nand/Onenand) 7> Bootloading real u-boot from the BootDevice and passing control to it. uboot spl源代码分析 一、makefile分析 打开spl文件夹只有一个makefile 可见spl都是复用uboot原先的代码。 主要涉及的代码文件为u-boot-2011.09-psp04.06.00.03/arch/arm/cpu/armv7 u-boot-2011.09-psp04.06.00.03/arch/arm/lib u-boot-2011.09-psp04.06.00.03/drivers LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-spl.lds 这个为链接脚本 __image_copy_end _end 三、代码解析 __start 为程序开始(arch/arm/cpu/armv7/start.S) .globl _start 这是在定义u-boot的启动定义入口点,汇编程序的缺省入口是 start 标号,用户也可以在连接脚本文件中用ENTRY标志指明其它入口点。

UBoot移植详解

u-boot 移植步骤详解 1 U-Boot简介 U-Boot,全称Universal Boot Loader,是遵循GPL条款的开放源码项目。从FADSROM、8xxROM、PPCBOOT逐步发展演化而来。其源码目录、编译形式与Linux内核很相似,事实上,不少U-Boot源码就是相应的Linux内核源程序的简化,尤其是一些设备的驱动程序,这从U-Boot源码的注释中能体现这一点。但是U-Boot不仅仅支持嵌入式Linux 系统的引导,当前,它还支持NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS嵌入式操作系统。其目前要支持的目标操作系统是OpenBSD, NetBSD, FreeBSD,4.4BSD, Linux, SVR4, Esix, Solaris, Irix, SCO, Dell, NCR, VxWorks, LynxOS, pSOS, QNX, RTEMS, ARTOS。这是U-Boot中Universal的一层含义,另外一层含义则是U-Boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。这两个特点正是U-Boot项目的开发目标,即支持尽可能多的嵌入式处理器和嵌入式操作系统。就目前来看,U-Boot对PowerPC系列处理器支持最为丰富,对Linux的支持最完善。其它系列的处理器和操作系统基本是在2002年11 月PPCBOOT 改名为U-Boot后逐步扩充的。从PPCBOOT向U-Boot的顺利过渡,很大程度上归功于U-Boot的维护人德国DENX软件工程中心Wolfgang Denk[以下简称W.D]本人精湛专业水平和持着不懈的努力。当前,U-Boot项目正在他的领军之下,众多有志于开放源码BOOT LOADER移植工作的嵌入式开发人员正如火如荼地将各个不同系列嵌入式处理器的移植工作不断展开和深入,以支持更多的嵌入式操作系统的装载与引导。 选择U-Boot的理由: ①开放源码; ②支持多种嵌入式操作系统内核,如Linux、NetBSD, VxWorks, QNX, RTEMS, ARTOS, LynxOS; ③支持多个处理器系列,如PowerPC、ARM、x86、MIPS、XScale; ④较高的可靠性和稳定性; ④较高的可靠性和稳定性; ⑤高度灵活的功能设置,适合U-Boot调试、操作系统不同引导要求、产品发布等; ⑥丰富的设备驱动源码,如串口、以太网、SDRAM、FLASH、LCD、NVRAM、EEPROM、RTC、键盘等; ⑦较为丰富的开发调试文档与强大的网络技术支持; 2 U-Boot主要目录结构 - board 目标板相关文件,主要包含SDRAM、FLASH驱动; - common 独立于处理器体系结构的通用代码,如内存大小探测与故障检测;

i.MX6UL -- Linux系统移植过程详解(最新的长期支持版本)

i.MX6UL -- Linux系统移植过程详解(最新的长期支持版本) ?开发平台:i.MX 6UL ?最新系统: u-boot2015.04 + Linux4.1.15_1.2.0 ?交叉编译工具:dchip-linaro-toolchain.tar.bz2 源码下载地址: U-Boot: (选择rel_imx_4.1.15_1.2.0_ga.tar.bz2) https://www.360docs.net/doc/256841720.html,/git/cgit.cgi/imx/uboot-imx.git/ Kernel: (选择rel_imx_4.1.15_1.2.0_ga.tar.bz2) https://www.360docs.net/doc/256841720.html,/git/cgit.cgi/imx/linux-2.6-imx.git/ 源码移植过程: 1、将linux内核及uBoot源码拷贝到Ubuntu12.04系统中的dchip_imx6ul目录下; 2、使用tar命令分别将uboot和kernel解压到dchip_imx6ul目录下; 3、解压后进入uboot目录下,新建文件make_dchip_imx6ul_uboot201504.sh,且文件内容如下: ################################################################### # Build U-Boot.2015.04 For D518--i.MX6UL By FRESXC # ################################################################### #!/bin/bash export ARCH=arm export CROSS_COMPILE=/dchip-linaro-toolchain/bin/arm-none-linux-gnueabi - make mrproper # means CLEAN make mx6ul_14x14_evk_defconfig make2>&1|tee built_dchip_imx6ul_uboot201504.out 4进入kernel目录下,新建文件make_dchip_imx6ul_linux4115120.sh,且文件内容如下: ###################################################################

uboot版本文件结构

uboot版本文件结构的更新改变 分类:ARM2011-09-22 12:57 339人阅读评论(0) 收藏举报本来是开始分析uboot代码的,但是无论是教材还是网上资料都对于我最新下的uboot原码结构不同,对于还是小白的我不容易找到相应的文件,下面是uboot版本中文件组织结构的改变,,,,, u-boot版本情况 网站:http://ftp.denx.de/pub/u-boot/ 1、版本号变化: 2008年8月及以前 按版本号命名:u-boot-1.3.4.tar.bz2(2008年8月更新) 2008年8月以后均按日期命名。 目前最新版本:u-boot-2011.06.tar.bz2(2011年6月更新) 2、目录结构变化: u-boot目录结构主要经历过2次变化,u-boot版本第一次从u-boot-1.3.2开始发生变化,主要增加了api的内容;变化最大的是第二次,从2010.6版本开始。 u-boot-2010.03及以前版本 ├── api存放uboot提供的接口函数 ├── board根据不同开发板定制的代码,代码也不少 ├── common通用的代码,涵盖各个方面,已命令行处理为主 ├── cpu与体系结构相关的代码,uboot的重头戏 ├── disk磁盘分区相关代码 ├── doc文档,一堆README开头的文件 ├── drivers驱动,很丰富,每种类型的设备驱动占用一个子目录 ├── examples示例程序 ├── fs文件系统,支持嵌入式开发板常见的文件系统 ├── include头文件,已通用的头文件为主 ├── lib_【arch】与体系结构相关的通用库文件 ├── nand_spl NAND存储器相关代码 ├── net网络相关代码,小型的协议栈 ├── onenand_ipl

uboot环境变量总结

Common目录下面与环境变量有关的文件有以下几个:env_common.c,env_dataflash.c,env_eeprom.c,env_flash.c,env_nand.c,env_nowhere.c,env_nvram.c,environment.c。 env_common.c中包含的是default_environment[]的定义; env_dataflash.c,env_eeprom.c,env_flash.c,env_nand.c, env_nvram.c 中包含的是相应存储器与环境变量有关的函数:env_init(void),saveenv(void),env_relocate_spec (void),env_relocate_spec (void),use_default()。至于env_nowhere.c,因为我们没有定义CFG_ENV_IS_NOWHERE,所以这个文件实际上没有用。 environment.c这个文件时是我真正理解环境变量的一个关键。在这个文件里定义了一个完整的环境变量的结构体,即包含了这两个ENV_CRC(用于CRC校验),Flags(标志有没有环境变量的备份,根据CFG_REDUNDAND_ENVIRONMENT这个宏定义判断)。定义这个环境变量结构体的时候还有一个非常重要的关键字: __PPCENV__,而__PPCENV__在该.c文件中好像说是gnu c编译器的属性,如下: # define __PPCENV__ __attribute__ ((section(".text"))) 意思是把这个环境变量表作为代码段,所以在编译完UBOOT后,UBOOT的代码段就会有环境变量表。当然,这要在我们定义了ENV_IS_EMBEDDED之后才行,具体而言,环境变量表会在以下几个地方出现(以nand flash为例): 1、UBOOT中的代码段(定义了ENV_IS_EMBEDDED), 2、UBOOT中的默认环 境变量, 3、紧接UBOOT(0x0 ~ 0x1ffff)后面:0x20000 ~ 0x3ffff 之间,包括备份的环境变量,我们读取,保存也是对这个区域(即参数区)进行的。3、SDRAM中的UBOOT中,包括代码段部分和默认部分,4、SDRAM中的melloc分配的内存空间中。 Environment.c代码如下: env_t environment __PPCENV__ = { ENV_CRC, /* CRC Sum */ #ifdef CFG_REDUNDAND_ENVIRONMENT 1, /* Flags: valid */ #endif { #if defined(CONFIG_BOOTARGS) "bootargs=" CONFIG_BOOTARGS "\0" #endif #if defined(CONFIG_BOOTCOMMAND) "bootcmd=" CONFIG_BOOTCOMMAND "\0" #endif #if defined(CONFIG_RAMBOOTCOMMAND) "ramboot=" CONFIG_RAMBOOTCOMMAND "\0"

U_Boot第一启动阶段Uboot启动分析笔记-----Stage1(start.S与lowlevel_init.S详解)

Uboot启动分析笔记-----Stage1(start.S与lowlevel_init.S详解) Uboot启动分析笔记-----Stage1(start.S与lowlevel_init.S详解) 1 u-boot.lds 首先了解uboot的链接脚本board/my2410/u-boot.lds,它定义了目标程序各部分的链接顺序。OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /*指定输出可执行文件为ELF格式,32为,ARM小端*/ OUTPUT_ARCH(arm) /*指定输出可执行文件为ARM平台*/ ENTRY(_start) /*起始代码段为_start*/ SECTIONS { /* 指定可执行image文件的全局入口点,通常这个地址都放在ROM(flash)0x0位置*、. = 0x00000000;从0x0位置开始 . = ALIGN(4); 4字节对齐 .text : {

cpu/arm920t/start.o (.text) board/my2440/lowlevel_init.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段,所有的u-boot命令相关的定义都放在这个位置,因为每个命令定义等长,所以只要以__u_boot_cmd_start为起始地址进行查找就可以很快查找到某一个命令的定义,并依据定义的命令指针调用相应的函数进行处理用户的任务*/ __u_boot_cmd_end = .; /* u_boot_cmd段结束位置,由此可以看出,这段空间的长度并没有严格限制,用户可以添加一些u-boot的命令,最终都会在连接是存放在这个位置。*/

Uboot如何向内核传递参数

Uboot如何向内核传递参数 一:启动参数的传递过程 启动参数是包装在数据结构里的,在linux kernel启动的时候,bootloader把这个数据结构拷贝到某个地址, 在改动PC跳向内核接口的同时,通过通用寄存器R2来传递这个地址的值,下面这句话就是uboot跳向linux kernel的代码(bootm命令) theKernel (0, bd->bi_arch_number, bd->bi_boot_params); thekernel其实不是个函数,而是指向内核入口地址的指针,把它强行转化为带三个参数的函数指针,会把三个 参数保存到通用寄存器中,实现了向kernel传递信息的功能,在这个例子里,会把R0赋值为0,R1赋值为机器号 R2赋值为启动参数数据结构的首地址 因此,要向内核传递参数很简单,只要把启动参数封装在linux预定好的数据结构里,拷贝到某个地址(一般约定俗成是内存首地址+100dex) 二:启动参数的数据结构 启动参数可保存在两种数据结构中,param_struct和tag,前者是2.4内核用的,后者是2.6以后的内核更期望用的 但是,到目前为止,2.6的内核也可以兼容前一种结构,两种数据结构具体定义如下(arm cpu): struct param_struct { union { struct { unsigned long page_size; /* 0 */ unsigned long nr_pages; /* 4 */ unsigned long ramdisk_size; /* 8 */ unsigned long flags; /* 12 */ #define FLAG_READONLY 1 #define FLAG_RDLOAD 4 #define FLAG_RDPROMPT 8 unsigned long rootdev; /* 16 */ unsigned long video_num_cols; /* 20 */ unsigned long video_num_rows; /* 24 */ unsigned long video_x; /* 28 */ unsigned long video_y; /* 32 */ unsigned long memc_control_reg; /* 36 */ unsigned char sounddefault; /* 40 */ unsigned char adfsdrives; /* 41 */ unsigned char bytes_per_char_h; /* 42 */ unsigned char bytes_per_char_v; /* 43 */ unsigned long pages_in_bank[4]; /* 44 */ unsigned long pages_in_vram; /* 60 */

UBoot源码分析1

?UBoot源码解析(一)

主要内容 ?分析UBoot是如何引导Linux内核 ?UBoot源码的一阶段解析

BootLoader概念?Boot Loader 就是在操作系统内核运行之前运行 的一段小程序。通过这段小程序,我们可以初始 化硬件设备、建立内存空间的映射图,从而将系 统的软硬件环境带到一个合适的状态,以便为最 终调用操作系统内核准备好正确的环境 ?通常,Boot Loader 是严重地依赖于硬件而实现 的,特别是在嵌入式世界。因此,在嵌入式世界 里建立一个通用的Boot Loader 几乎是不可能的。 尽管如此,我们仍然可以对Boot Loader 归纳出 一些通用的概念来,以指导用户特定的Boot Loader 设计与实现。

UBoot来源?U-Boot 是 Das U-Boot 的简称,其含义是 Universal Boot Loader,是遵循 GPL 条款的开放源码项目。最早德国 DENX 软件工程中心的 Wolfgang Denk 基于 8xxROM 和 FADSROM 的源码创建了 PPCBoot 工程项目,此后不断 添加处理器的支持。而后,Sysgo Gmbh 把 PPCBoot 移 植到 ARM 平台上,创建了 ARMBoot 工程项目。最终, 以 PPCBoot 工程和 ARMBoot 工程为基础,创建了 U- Boot 工程。 ?而今,U-Boot 作为一个主流、通用的 BootLoader,成功地被移植到包括 PowerPC、ARM、X86 、MIPS、NIOS、XScale 等主流体系结构上的百种开发板,成为功能最多、 灵活性最强,并且开发最积极的开源 BootLoader。目前。 U-Boot 仍然由 DENX 的 Wolfgang Denk 维护

嵌入式Linux之我行 史上最牛最详细的uboot移植,不看别后悔

嵌入式Linux之我行——u-boot-2009.08在2440上的移植详解(一) 嵌入式Linux之我行,主要讲述和总结了本人在学习嵌入式linux中的每个步骤。一为总结经验,二希望能给想入门嵌入式Linux 的朋友提供方便。如有错误之处,谢请指正。 ?共享资源,欢迎转载:https://www.360docs.net/doc/256841720.html, 一、移植环境 ?主机:VMWare--Fedora 9 ?开发板:Mini2440--64MB Nand,Kernel:2.6.30.4 ?编译器:arm-linux-gcc-4.3.2.tgz ?u-boot:u-boot-2009.08.tar.bz2 二、移植步骤 本次移植的功能特点包括: ?支持Nand Flash读写 ?支持从Nor/Nand Flash启动 ?支持CS8900或者DM9000网卡 ?支持Yaffs文件系统 ?支持USB下载(还未实现) 1.了解u-boot主要的目录结构和启动流程,如下图。

u-boot的stage1代码通常放在cpu/xxxx/start.S文件中,他用汇编语言写成;u-boot的stage2代码通常放在lib_xxxx/board.c文件中,他用C语言写成。各个部分的流程图如下:

2. 建立自己的开发板项目并测试编译。 目前u-boot对很多CPU直接支持,可以查看board目录的一些子目录,如:board/samsung/目录下就是对三星一些ARM 处理器的支持,有smdk2400、smdk2410和smdk6400,但没有2440,所以我们就在这里建立自己的开发板项目。 1)因2440和2410的资源差不多,主频和外设有点差别,所以我们就在board/samsung/下建立自己开发板的项目,取名叫my2440 2)因2440和2410的资源差不多,所以就以2410项目的代码作为模板,以后再修改

关于uboot移植 CAMDIVN与时钟

关于uboot移植 CAMDIVN与时钟 2010-03-09 19:57 在该文件的122行附近有这样一个结构体 typedef struct { S3C24X0_REG32 LOCKTIME; S3C24X0_REG32 MPLLCON; S3C24X0_REG32 UPLLCON; S3C24X0_REG32 CLKCON; S3C24X0_REG32 CLKSLOW; S3C24X0_REG32 CLKDIVN; } /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER; 是用来封装时钟寄存器的,我们要在其中增加一项S3C24X0_REG32 CAMDIVN,为什么加这么一个呢?因为这个寄存器是2410所没有的,而2440在配置时钟的时候又必须用到,看名字我们就知道是用来配置CAMERA时钟的,也就是配置摄像头的时钟的。 貌似和配置uboot启动的时钟没有关系?其实不然,我们在修改下一个文件的时候就可以看到其用途了, 此结构体修改后的结果为 typedef struct { S3C24X0_REG32 LOCKTIME; S3C24X0_REG32 MPLLCON; S3C24X0_REG32 UPLLCON; S3C24X0_REG32 CLKCON; S3C24X0_REG32 CLKSLOW; S3C24X0_REG32 CLKDIVN; S3C24X0_REG32 CAMDIVN; } /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER; 第二个文件..\cpu\arm920t\s3c24x0\speed.c 在这个文件中需要修改两个函数 第一个函数在54行附近:static ulong get_PLLCLK(int pllreg) 由于S3C2410和S3C2440的MPLL、UPLL计算公式不一样,所以get_PLLCLK 函数也需要修改:

经典=Uboot-2-命令详解(bootm)

bootm命令中地址参数,内核加载地址以及内核入口地址 分类:u-boot2010-11-04 10:472962人阅读评论(0)收藏举报downloadlinuxbytecmdheaderimage bootm命令只能用来引导经过mkimage构建了镜像头的内核镜像文件以及根文件镜像,对于没有用mkimage对内核进行处理的话,那直接把内核下载到连接脚本中指定的加载地址0x30008000再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag是由bootloader提供的,在u-boot下默认是由bootm命令建立的)。 通过mkimage可以给内核镜像或根文件系统镜像加入一个用来记录镜像的各种信息的头。同样通过mkimage也可以将内核镜像进行一次压缩(指定-C none/gzip/bzip2),所以这里也就引申出了两个阶段的解压缩过程:第一个阶段是u-boot里面的解压缩,也就是将由mkimage压缩的镜像解压缩得到原始的没加镜像头的内核镜像。第二个阶段是内核镜像的自解压,u-boot 里面的解压实际上是bootm 实现的,把mkimage -C bzip2或者gzip 生成的uImage进行解压;而kernel的自解压是对zImage进行解压,发生在bootm解压之后。 下面通过cmd_bootm.c文件中对bootm命令进行解析以及执行的过程来分析,这三种不同地址的区别: ulong load_addr = CFG_LOAD_ADDR; /* Default Load Address */ int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ...... if (argc < 2) { addr = load_addr;//当bootm命令后面不带地址参数时,将默认的加载地址赋值给addr } else { addr = simple_strtoul(argv[1], NULL, 16); //如果bootm命令后面带了加载地址,则将该地址赋值给addr,所以最终有用的地址还是bootm命令后附带的地址 } ...... //

uboot启动常见的错误汇总

【uboot启动常见的错误汇总】 1. operating at 100M full duplex mode *** ERROR: `ethaddr' not set dm9000 i/o: 0x5000000, id: 0x90000a46 DM9000: running in 16 bit mode MAC: 00:00:00:00:00:00 operating at 100M full duplex mode Wrong Image Format for bootm command ERROR: can't get kernel image! 原因是:没有设置mac地址,需要重新设置 setenv ethaddr 01:02:03:04:05:06 saveenv/save 2.在开发板上ping ubuntu的ip地址ping不通 1.网线没插 2.ubuntu没有打开 3.ping 的过程中,ubuntu会扫描ip地址,会一直去获取ip地址,但是开发板没有分配ip地址的权利,也就是ubuntu获取不了ip地址,同时查看ubuntu 的ip地址是没有的。 1.设置临时的ip地址 sudo ifconfig eth0 192.168.1.* 2.永久生效 在ubuntu的右上角添加静态ip地址。 3.发现ubuntu的右上角网络图标类似于wifi的图标,如何将这个图标改成网络的 图标 sudo /etc//init.d/network-manager restart 如何执行之后,还是wifi图标 sudo vi /etc/NetworkManager/NetworkManager.conf managed=false false --->true sudo /etc//init.d/network-manager restart 如果执行之后,还是wifi图标 重启系统 4.你的pc电脑已经打开wifi网,需要将无线网关闭 5.虚拟机网卡设置出错,需要将nat设置为桥接 6.换开发板

iTop4412的uboot第一阶段

2 uboo t 源码分析 2.5.1.star t.S 2.5.1.star t.S 引入引入 2.5.1.1、u-boot.lds中找到start.S入口 (1)在C语言中整个项目的入口就是 main函数(这是 个.c文件的项目,第一个要分析的文件就是包含了C语言规定的),所以譬如说一 个有 main函数的那个文件。 10000 ( 2 方。ENTRY(_start)因此 _start 符号所在的文件就是整个程序的起始文 件, _sta rt 所在处的 代码就是整个程序的起始代码。 2.5.1.2、SourceInsight中如何找到 文件 (1)当前状况:我们知道在uboot中的1000多个文件中有一个符号 叫 _start,但是我们不知道 这个符号在哪个文件中。这种情况下要查找一个符号在所有项目中文件中的引用,要使用SourceInsight的搜索功能。 (2)start.s 在cpu/arm_cortexa9/start.s (3)然后进入start.S文件中,发现 个uboot的入口代码,就是第57 57行中就 是行。_sta rt 标号的定义处,于是乎我们就找到了整 2.5.1.3、SI中找文件技巧 (1)以上,找到了start.S文件,下面我们就从start.S文件开始分析uboot第一阶段。 (2)在SI中,如果我们知道我们要找的文件的名字,但是我们又不知道他在哪个目录下,我 们要怎样找到并打开这个文件?方法是在 SI中先打开右边的工程项目管理栏目,然后点击 最左边那个(这个是以文件为单位来浏览的),然后在上面输入栏中输入要找的文件的名 字。我们在输入的时候,SI在不断帮我们进行匹配,即使你不记得文件的全名只是大概记 得名字,也能帮助你找到你要找的文件。 2.5.2.start.S解析1 2.5.2.1、不简单的头文件包含

uboot调试指南

Uboot调试参考指南 一、调试目的 Uboot的调试旨在通过观察uboot运行时状态来测试硬件问题。 二、调试步骤 1.修改代码 在uboot代码路径下,编辑uboot代码,需要做以下修改; a.修改config.mk文件,添加以下两行内容: AFLAGS += -Wa,-gdwarf2 CFLAGS += -g2 -gdwarf-2 b.修改. /arch/powerpc/lib/board.c文件 debug("Now running in RAM - U-Boot at: %08lx\n", dest_addr); printf("Now running in RAM - U-Boot at: %08lx\n", dest_addr); 将debug改为printf,如上所示。 2.编译uboot 执行make BSC9131RDB_SYSCLK100_NAND,编译uboot 3.将编译好的u-boot-nand.bin(uboot image格式)及u-boot(elf格式文件)文件拷 贝出来 4.烧录uboot 将步骤3中保存的u-boot-nand.bin烧录到目标板中,烧录过程略。 5.建立工程 a.在cw界面,点击file->import, 选择code warrior -> Power architecture ELF executable,如图1所示: 图1 建立elf工程 b.选择步骤3中保存的u-boot(elf格式文件),toolchain选择bareboard application, target OS选择none,工程名字请根据需要设置,比如我的机器上设置为example, 点击next,如图2所示:

uboot_freescale_imx51_start.s_详解

/* * *Purpose: the document is used to learn detailed information aboutimx51 cpu start.S, *referring to some documents on websites. *file address: U-boot-2009.08/Cpu/Arm_cortexa8/start.S * * writer: xfhai 2011.7.22 * *Instruction: *1.@xxxx : indicates annotation *2./***** *** *****/ : stand for code in my files *3.instructions refers to code not included in my file * */ Section 1: uboot overview 大多数bootloader都分为stage1和stage2两部分,u-boot也不例外。依赖于CPU体系结构的代码(如设备初始化代码等)通常都放在stage1且可以用汇编语言来实现,而stage2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。 1、Stage1 start.S代码结构 u-boot的stage1代码通常放在start.S文件中,他用汇编语言写成,其主要代码部分如下:==> (1)定义入口。由于一个可执行的Image必须有一个入口点,并且只能有一个全局入口,通常这个入口放在ROM(Flash)的0x0地址,因此,必须通知编译器以使其知道这个入口,该工作可通过修改连接器脚本来完成。 ==>(2)设置异常向量(Exception Vector)。 ==>(3)设置CPU的速度、时钟频率及终端控制寄存器。 ==>(4)初始化内存控制器。 ==>(5)将ROM中的程序复制到RAM中。 ==>(6)初始化堆栈。 ==>(7)转到RAM中执行,该工作可使用指令ldr pc来完成。 2、Stage2 C语言代码部分 lib_arm/board.c中的start arm boot是C语言开始的函数也是整个启动代码中C语言的主函数,同时还是整个u-boot(armboot)的主函数,该函数只要完成如下操作: ==>(1)调用一系列的初始化函数。 ==>(2)初始化Flash设备。 ==>(3)初始化系统内存分配函数。 ==>(4)如果目标系统拥有NAND设备,则初始化NAND设备。 ==>(5)如果目标系统有显示设备,则初始化该类设备。 ==>(6)初始化相关网络设备,填写IP、MAC地址等。 ==>(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。

相关文档
最新文档