U-Boot-1.1.6移植到MINI2440开发板(3) —— 源码分析第一阶段

最新更新时间:2022-11-18来源: zhihu关键字:U-Boot  移植  MINI2440开发板 手机看文章 扫描二维码
随时随地手机看文章

下面进行源码内容的分析及修改:


由上面的分析可以知道,最终将所有obj文件链接生成u-boot可执行文件时,用到了/board/mini2440/u-boot.lds这个链接脚本,查看其内容:


------- /board/mini2440/u-boot.lds -------

24 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")

25 /*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/

26 OUTPUT_ARCH(arm)

27 ENTRY(_start)

28 SECTIONS

29 {

30     . = 0x00000000;

31 

32 

33     . = ALIGN(4);

34     .text      :

35     {

36       cpu/arm920t/start.o    (.text)

37       *(.text)

38     }

...

同时查看u-boot.dis文件:


------- u-boot.dis -------

2 u-boot:     file format elf32-littlearm

4 Disassembly of section .text:

6 33f80000 <_start>:

7 33f80000:    ea000012     b    33f80050

8 33f80004:    e59ff014     ldr    pc, [pc, #20]    ; 33f80020 <_undefined_instruction>

9 33f80008:    e59ff014     ldr    pc, [pc, #20]    ; 33f80024 <_software_interrupt>

可知代码段中放在最前的是/cpu/arm920t/start.S,同时上电之后最开始执行的标号是/cpu/arm920t/start.S中的_start,因此从这里开始分析。


/cpu/arm920t/start.S:


找到start.S中的_start标号:


------- /cpu/arm920t/start.S -------

41 .globl _start

42 _start:    b       reset

43     ldr    pc, _undefined_instruction

44     ldr    pc, _software_interrupt

45     ldr    pc, _prefetch_abort

46     ldr    pc, _data_abort

47     ldr    pc, _not_used

48     ldr    pc, _irq

49     ldr    pc, _fiq

50 

51 _undefined_instruction:    .word undefined_instruction

52 _software_interrupt:    .word software_interrupt

53 _prefetch_abort:    .word prefetch_abort

54 _data_abort:        .word data_abort

55 _not_used:        .word not_used

56 _irq:            .word irq

57 _fiq:            .word fiq

58 

59     .balignl 16,0xdeadbeef

...

75 _TEXT_BASE:

76     .word    TEXT_BASE

77 

78 .globl _armboot_start

79 _armboot_start:

80     .word _start

81 

82 /*

83 * These are defined in the board-specific linker script.

84 */

85 .globl _bss_start

86 _bss_start:

87     .word __bss_start

88 

89 .globl _bss_end

90 _bss_end:

91     .word _end

第41行,.global是编译的关键词,告诉编译器这是一个全局可见的名字(可能是变量,也可能是函数名),在这里_start是一个标号(GNU汇编编译器的默认入口标号),用.global关键字将其定义为一个全局可见的标号,以便在编译链接过程中能够找到。


第59行,.balignl表示结束的地址必须为后面第一个参数(16)的整数倍,如果不是整数倍,则进行填充使其达到整数倍,填充的内容为0xdeadbeef,这条指令用于将后面的指令对齐在16的整数倍的地址上。


第75行到第91行,定义一些标号:


_TEXT_BASE:TEXT_BASE(0x33F80000);

_armboot_start:_start(0x33F80000);

_bss_start:__bss_start(u-boot.lds中定义的BSS起始地址);

_bss_end:_end(u-boot.lds中定义的BSS结束地址,也是最后的结束地址)

_start标号下第一条指令就是跳转指令,b reset指令表示无条件跳转到reset标号继续执行。


后面为S3C2440的7个中断向量地址,并使用跳转指令指向中断服务程序,当发生中断时,程序指针PC会跳转到相应的中断向量,执行中断程序。


找到reset标号:


------- /cpu/arm920t/start.S -------

106 /*

107 * the actual reset code

108 */

109 

110 reset:

111     /*

112      * set the cpu to SVC32 mode

113      */    

reset标号下首先对S3C2440的当前程序状态寄存器(CPSR)进行操作,使芯片工作在超级用户模式下(Supervisor)。


查看S3C2440手册中关于CPSR寄存器的说明:


寄存器高4位是程序运行标志位,低8位是状态控制位,手册中具体说明如下:

第7位——中断禁止位,置1时禁止中断;

第6位——快速中断禁止位,置1时禁止中断;

第5位——芯片运行状态位,置1时运行在THUMB状态下,否则运行在ARM状态下;

第4~0位——运行模式选择位,其模式设置如下:

10000:User Mode,普通用户模式

10001:FIQ Mode,快速中断模式

10010:IRQ Mode,中断模式

10011:Supervisor Mode,超级用户模式

10111:Abort Mode

11011:Undefined Mode

11111:System Mode

使用状态寄存器访问指令MRS和MSR进行访问:


MRS:状态寄存器(CPSR或SPSR)内容传送到通用寄存器(Rd)

格式:MRS{} ,


MSR:将操作数(opt)的内容传送到状态寄存器(CPSR或SPSR)的特定域中

格式:MSR{} _域, opt

位[31:24]为条件标志位域,用f表示;

位[23:16]为状态位域,用s表示;

位[15:8]为扩展位域,用x表示;

位[7:0]为控制位域,用c表示。

其中SPSR为程序状态保存寄存器。


CPSR: Current Program Status Register

SPSR: Saved Program Status Register

因此reset标号下的指令:


------- /cpu/arm920t/start.S -------

110 reset:

111     /*

112      * set the cpu to SVC32 mode

113      */

114     mrs    r0,cpsr

115     bic    r0,r0,#0x1f

116     orr    r0,r0,#0xd3

117     msr    cpsr,r0

首先通过MRS指令将CPSR的值读到R0中,然后在R0中对CPSR的值进行操作,再通过MSR指令将改变后的值写入CPSR中。


其中:


BIC{} Rd, Opt1, Opt2:

清除操作数1(Opt1)中的某些位,并将结果写入目的寄存器(Rd)中,操作数2(Opt2)为32位掩码,掩码中置1的位在操作数1中将会被清0。


ORR{} Rd, Opt1, Opt2:

将两个操作数进行或运算,并将结果写入目的寄存器(Rd)中,常用于将操作数1的某些位置1。

因此首先将CPSR的值传送到R0中:


------- /cpu/arm920t/start.S -------

114     mrs    r0,cpsr

然后清除R0的低5位:


------- /cpu/arm920t/start.S -------

115     bic    r0,r0,#0x1f

将R0的值或上0b11010010(0xD3),即用于模式选择的低5位[4:0]置为10011,即Supervisor Mode,超级用户模式,并将[7:6]置1,禁止中断:


------- /cpu/arm920t/start.S -------

116     orr    r0,r0,#0xd3

最后再将修改好的值写入CPSR:


------- /cpu/arm920t/start.S -------

117     msr    cpsr,r0

接下来利用宏定义设置和看门狗、中断以及时钟相关的寄存器:


------- /cpu/arm920t/start.S -------

120 #if defined(CONFIG_S3C2400)

121 # define pWTCON        0x15300000

122 # define INTMSK        0x14400008    /* Interupt-Controller base addresses */

123 # define CLKDIVN    0x14800014    /* clock divisor register */

124 #elif defined(CONFIG_S3C2410)

125 # define pWTCON        0x53000000

126 # define INTMSK        0x4A000008    /* Interupt-Controller base addresses */

127 # define INTSUBMSK    0x4A00001C

128 # define CLKDIVN    0x4C000014    /* clock divisor register */

129 #endif

添加对S3C2440的支持,添加修改如下,因为S3C2440这4个寄存器的地址与S3C2410一致,所以也可直接在124行添加对S3C2440的判断:


------- /cpu/arm920t/start.S -------

120 #if defined(CONFIG_S3C2400)

121 # define pWTCON        0x15300000

122 # define INTMSK        0x14400008    /* Interupt-Controller base addresses */

123 # define CLKDIVN    0x14800014    /* clock divisor register */

124 #elif defined(CONFIG_S3C2410)

125 # define pWTCON        0x53000000

126 # define INTMSK        0x4A000008    /* Interupt-Controller base addresses */

127 # define INTSUBMSK    0x4A00001C

128 # define CLKDIVN    0x4C000014    /* clock divisor register */

129 #elif defined(CONFIG_S3C2440)

130 # define pWTCON        0x53000000

131 # define INTMSK        0x4A000008    /* Interupt-Controller base addresses */

132 # define INTSUBMSK    0x4A00001C

133 # define CLKDIVN    0x4C000014    /* clock divisor register */

134 #endif

接下来关闭看门狗:


------- /cpu/arm920t/start.S -------

136 #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)

137     ldr     r0, =pWTCON

138     mov     r1, #0x0

139     str     r1, [r0]

屏蔽中断:


------- /cpu/arm920t/start.S -------

141     /*

142      * mask all IRQs by setting all bits in the INTMR - default

143      */

144     mov    r1, #0xffffffff

145     ldr    r0, =INTMSK

146     str    r1, [r0]

147 # if defined(CONFIG_S3C2410)

148     ldr    r1, =0x3ff

149     ldr    r0, =INTSUBMSK

150     str    r1, [r0]

151 # endif

以及设置时钟分频:


------- /cpu/arm920t/start.S -------

153     /* FCLK:HCLK:PCLK = 1:2:4 */

154     /* default FCLK is 120 MHz ! */

155     ldr    r0, =CLKDIVN

156     mov    r1, #3

157     str    r1, [r0]

158 #endif    /* CONFIG_S3C2400 || CONFIG_S3C2410 */

S3C2440的看门狗、中断设置与S3C2410相似,具体操作见S3C2440数据手册。但两者时钟设置上稍微有些区别,S3C2440内部有两个锁相环(PLL),一个用于FCLK、HCLK、PCLK,另一个用于USB模块(通常设置为48MHz)。FCLK即为CPU运行频率,HCLK用于AHB总线上的外设,PCLK用于APB总线上的外设。


S3C2440通过MPLLCON与UPLLCON两个寄存器来设置时钟频率(注意如果要同时设置MPLL与UPLL时,应该先设置UPLL,中间间隔大约7个时钟周期,然后再设置MPLL):



在刚上电时钟频率默认为晶振频率,即12MHz,通过设置时钟倍频,获得实际工作的时钟频率,计算公式如下,其中Fin在这里为晶振频率,即12MHz,MPLL计算的结果即为FCLK的值,而S3C2410的MPLL计算略有不同(MPLL少乘一个2):


S3C2440通过CLKDIVN寄存器设置FCLK、HCLK、PLCK的分频:

并且,在HDIVN不为0时,需要将CPU的总线模式从快速总线模式改变为其他模式,而S3C2440不支持同步总线模式,因此将其设置为异步总线模式,否则CPU将按HCLK的频率运行:

在ARM920T的技术手册中有详细说明,ARM处理器使用协处理器15(CP15)的寄存器来控制cache、TCM和MMU等,CP15包含了编号为0~15的共16个32位的寄存器,其中总线模式控制在寄存器1(Register 1, control register),其说明与访问指令如下:

总线模式的控制位是第[31:30]位,设置方式如下:

因此,根据上述分析进行修改,首先添加对S3C2440的支持:


------- /cpu/arm920t/start.S -------

136 #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

看门狗的设置与S3C2410一致,不需要修改。中断屏蔽寄存器INTMSK的设置也一致,而S3C2440的中断子屏蔽寄存器INTSUBMSK中位[14:0]均需要进行屏蔽,添加修改如下:


------- /cpu/arm920t/start.S -------

151 # elif defined(CONFIG_S3C2440)

152     ldr    r1, =0x7fff

153     ldr    r0, =INTSUBMSK

154     str    r1, [r0]

由于S3C2440的时钟设置与S3C2410不同,同时为了后续程序(SDRAM等)的设置,将S3C2440的时钟频率FCLK设置为200MHz,且分频比为1:2:4,即FCLK : HLCK : PCLK=200MHz : 100MHz : 50MHz,因此添加修改:


------- /cpu/arm920t/start.S -------

157 # if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)

158     /* FCLK:HCLK:PCLK = 1:2:4 */

159     /* default FCLK is 120 MHz ! */

160     ldr    r0, =CLKDIVN

161     mov    r1, #3

162     str    r1, [r0]

163 # elif defined(CONFIG_S3C2440)

164     /* FCLK:HCLK:PCLK = 200MHz:100MHz:50MHz */

165 # define MPLLCON 0x4C000004

166 # define MPLL_200MHz    ((0x5C<<12)|(0x01<<4)|(0x02))

167     ldr    r0, =MPLLCON

[1] [2] [3] [4] [5]
关键字:U-Boot  移植  MINI2440开发板 编辑:什么鱼 引用地址:U-Boot-1.1.6移植到MINI2440开发板(3) —— 源码分析第一阶段

上一篇:U-Boot-1.1.6移植到MINI2440开发板(4) —— 源码分析第二阶段(1)
下一篇:U-Boot-1.1.6移植到MINI2440开发板(1) —— 移植前分析

推荐阅读

基于S3C2410开发板U-BOOT移植解决方案
引言随着嵌入式系统的日趋复杂,它对大容量数据存储的需求越来越紧迫。而嵌入式设备低功耗、小体积以及低成本的要求,使硬盘无法得到广泛的应用。NAND闪存设备就是为了满足这种需求而迅速发展起来的。目前关于U-BOOT的移植解决方案主要面向的是微处理器中的NOR 闪存,如果能在微处理器上的NAND 闪存中实现U-BOOT的启动,则会给实际应用带来极大的方便。U-BOOT简介U-BOOT 支持ARM、 PowerPC等多种架构的处理器,也支持Linux、NetBSD和VxWorks等多种操作系统,主要用来开发嵌入式系统初始化代码bootloader。bootloader是芯片复位后进入操作系统之前执行的一段代码,完成由硬件启动到操作系统启动的
发表于 2023-01-11
基于S3C2410<font color='red'>开发板</font>的<font color='red'>U-BOOT</font><font color='red'>移植</font>解决方案
U-boot在S3C2440上的移植详解(五)
一、移植环境主 机:VMWare--Fedora 9开发板:Mini2440--64MB Nand,Kernel:2.6.30.4编译器:arm-linux-gcc-4.3.2.tgzu-boot:u-boot-2009.08.tar.bz2二、移植步骤9)实现u-boot对yaffs/yaffs2文件系统下载的支持。 注意:此篇对Nand的操作是基于MTD架构方式,在“u-boot-2009.08在2440上的移植详解(三)”中讲到过。 通常一个Nnad Flash存储设备由若干块组成,1个块由若干页组成。一般128MB以下容量的Nand Flash芯片,一页大小为528B,被依次分为2个256B的主数据区和16B的额外空间;12
发表于 2023-01-11
<font color='red'>U-boot</font>在S3C2440上的<font color='red'>移植</font>详解(五)
关于uboot的功能分析透彻方案
如果我们想快速的移植uboot,那么我们就要先将我们用到的uboot的功能分析透彻,uboot最终目的就是**引导内核**,但是在实际开发中为了方便开发调试,我们将uboot加入了很多功能,比如tftp下载,nfs启动,串口打印等功能;那么我们先按着执行的顺序来分析代码。uboot并没有对2440进行支持,所以我们分析阶段先分析smdk2410的相关代码,分析完成以后我们在根据s3c2440的技术手册在2410的基础上进行移植。Makefile分析首先我们根据编译过程进行分析,编译需要执行命令:make smdk2410_config我们查看根目录下Makefile文件,搜索smdk2410_config得到如下代码:smdk241
发表于 2023-01-11
s3c2440移植openharmony
s3c2440移植openharmony。OpenHarmony是开放原子开源基金会的一个孵化项目,OpenHarmony完全开源开放,OpenHarmony轻量和小型系统比较适合内存小的IOT设备。OpenHarmony同时提供许多可选的系统组件,设备开发者能够按需配置。系统能够把这些能够选择的组件合成一个系列的系统能力让设备开发者更好的理解和开发。想对OpenHarmony进行开发、编译、烧录、调测能够使用DevEco Device Tool。现在的openharmony轻量和小型系统搭建系统环境Windows版本不支持在Windows平台编译,Hi3861除外,其它的只能在Ubuntu平台下编译。
发表于 2023-01-09
基于S3C2410处理器目标板的Linux移植
引言嵌 人式系统就是以应用为中心、以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗等严格要求的专用计算机系统。ARM嵌人式 芯片是一种高性能、低功耗的RISC芯片。它由英国ARM公司设计,世界上几乎所有的主要半导体生产商都生产基于ARM体系机构的通用芯片,或在其专用芯 片中应用相关ARM技术。在2001年基于ARM内核的处理器占市场份额的75%,成为业界的龙头。Linux 是免费发行的、快速高效的操作系统 ,Linux的出现在计算机世界引发了一场革命。Linux操作系统以代码开放、功能强大又易于移植成为嵌入式操作新兴力量。嵌人式Linux是按照嵌人 式操作系统的要求设计的一种小型操作系统,由一个内核以及
发表于 2023-01-06
s3c2410/2440(armv4t) 移植Android
ARMv4移植简单教程: 相信国内很多朋友手上都有s3c2410/2440的片子,基于armv4t(arm920t)的指令架构。在之前,因为android的一些底层代码含 有armv5t的指令, 所以以前无法移植到这样的平台。 在这里也放出移植教程和已经编译好的image。 让更多的朋友可以在自己的开发板上亲身体验android。教程基于勤研qt2410以及扬创utu2440完成。 注意,移植是到armv4而不是armv4t,原因应该是不开thumb支持会比较好移植一些(改动未涉及的库依然会用thumb代码,所以kernel依然要开thumb支持)。 kernel移植及nfs配置的详细部分等请自行查阅相关文档,本文只做提点,另
发表于 2023-01-05
小广播
设计资源 培训 开发板 精华推荐

何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2023 EEWORLD.com.cn, Inc. All rights reserved