Linux系统移植之——系统启动 bootloader 的编写、内存映射篇
ztj100 2024-12-16 17:39 20 浏览 0 评论
你们要的Linux系统移植来了,本章主要讲解系统启动 bootloader ,涉及ADS命令行、内存映射的内容。
本人也是一名程序员,给大家挑选的都是IT编程相关的精品资料,希望对大家的学习有帮助。
另外,本人近期会陆续上传这些资料和视频教程,可以关注一下互相交流:C C++ Java python linux ARM 嵌入式 物联网等。
1 工具介绍
1.1 ADS 命令行命令介绍
1.1.1 armasm
1.1.2 armcc, armcpp
1.1.3 armlink
2 基本原理
2.1 可执行文件组成及内存映射
2.1.1 可执行文件的组成
2.1.2 装载过程
2.1.3 启动过程的汇编部分
2.1.4 启动过程的 C 部分
3 AXD 的使用以及源代码说明
3.1 源代码说明
3.1.1 汇编源代码说明
3.1.2 C 语言源代码说明
3.1.3 源代码下载
3.2 AXD 的使用
3.2.1 配置仿真器
3.2.2 启动 AXD 配置开发板
3 AXD 的使用以及源代码说明
3.1 源代码说明
3.1.1 汇编源代码说明
;===============================================================================
; 引用头文件
;===============================================================================
get bdinit.h
;===============================================================================
; 引用标准变量
;===============================================================================
IMPORT |Image$RO$Base| ; Base address of RO section
IMPORT |Image$RO$Limit| ; End address of RO section
IMPORT |Image$RW$Base| ; Base address of RW section
IMPORT |Image$RW$Limit| ; End address of RW section
IMPORT |Image$ZI$Base| ; Base address of ZI section
IMPORT |Image$ZI$Limit| ; End addresss of ZI section
IMPORT bdmain ; The entry function of C program
;===============================================================================
; 宏定义
;===============================================================================
; macro HANDLER
MACRO
$HandlerLabel HANDLER $HandleLabel
$HandlerLabel
sub sp,sp,#4 ;Decrement sp (to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack
ldr r0,=$HandleLabel;Load the address of HandleXXX to r0
ldr r0,[r0] ;Load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;Store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
;===============================================================================
; 汇编语言的入口代码
;===============================================================================
AREA Init,CODE,READONLY
CODE32
ENTRY
;=====================
; 建立中断向量表
;===================== b reset_handler ;0x00000000: Reset (SVC)
b undef_handler ;0x00000004: Undefined instruction (Undef)
b swi_handler ;0x00000008: Software Interrupt (SVC)
b iabr_handler ;0x0000000C: Instruction Abort (Abort)
b dabr_handler ;0x00000010: Data Abort (Abort)
b no_handler ;0x00000014:
b irq_handler ;0x00000018: IRQ (IRQ)
b fiq_handler ;0x0000001C: FIQ (FIQ)
LTORG
undef_handler HANDLER HandleUndef
swi_handler HANDLER HandleSWI
iabr_handler HANDLER HandlePabort
dabr_handler HANDLER HandleDabort
no_handler HANDLER HandleReserved
irq_handler HANDLER HandleIRQ
fiq_handler HANDLER HandleFIQ
;=============================
; 复位时运行的主程序
;=============================
reset_handler
;Set the cpu to SVC32 mode
mrs r0,cpsr
bic r0,r0,#0x1f
orr r0,r0,#0xd3
msr cpsr_cxsf,r0
;Turn off watchdog
ldr
r0,=WTCON
ldr
r1,=0x0
str
r1,[r0]
;Disable all the first level interrupts
ldr
r0,=INTMSK
ldr
r1,=0xffffffff
str
r1,[r0]
;Disable all the second level interrupts
ldr
r0,=INTSUBMSK
ldr
r1,=0x7ff
str
r1,[r0]
;Configure MPLL
ldr
r0,=MPLLCON
ldr
r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) ;Fin=12MHz,Fout=200MHz
str
r1,[r0]
;Set FCLK:HCLK:PCLK = 1:2:4
ldr
r0, =CLKDIVN
mov
r1, #3
str
r1, [r0]
;Set memory control registers
ldrr0,=SMRDATAldr
r1,=BWSCON
add
r2, r0, #52
;End address of SMRDATA
0
ldr
r3, [r0], #4
str
r3, [r1], #4
cmp
r2, r0
bne
%B0
;Initialize stacks
bl
InitStacks
;Setup IRQ handler
ldr
r0,=HandleIRQ
;This routine is needed
ldr
r1,=IsrIRQ
str
r1,[r0]
;Copy RW/ZI section into RAM
ldr
r0, =|Image$RO$Limit|;Get pointer to ROM data
ldr
r1, =|Image$RW$Base| ;and RAM copy
ldr
r3, =|Image$ZI$Base|
cmp
r0, r1
; Check that they are different
beq
%F2
1
cmp
r1, r3
; Copy init data
ldrcc
r2, [r0], #4
;--> LDRCC r2, [r0] + ADD r0, r0, #4
strcc
r2, [r1], #4
;--> STRCC r2, [r1] + ADD r1, r1, #4
bcc
%B1
2
ldr
r1, =|Image$ZI$Limit| ; Top of zero init segment
mov
r2, #0
3
cmp
r3, r1
; Zero init
strcc
r2, [r3], #4
bcc
%B3
bl bdmain
;Jump to the main function
;Dead loop
1
nop
b
%B1
;===============================================================================
; 初始中断处理程序
;===============================================================================
IsrIRQ
sub
sp,sp,#4 ;reserved for PC
stmfd
sp!,{r8-r9}
ldr
r9,=INTOFFSET
ldr
r9,[r9]
ldr
r8,=HandleEINT0
add
r8,r8,r9,lsl #2
ldr
r8,[r8]str
r8,[sp,#8]
ldmfd
sp!,{r8-r9,pc}
;===============================================================================
; 初始化各个模式下堆栈
;===============================================================================
InitStacks
mrs
r0,cpsr
bic
r0,r0,#MODEMASK
orr
r1,r0,#UNDEFMODE|NOINT
msr
cpsr_cxsf,r1
;UndefMode
ldr
sp,=UndefStack
orr
r1,r0,#ABORTMODE|NOINT
msr
cpsr_cxsf,r1
;AbortMode
ldr
sp,=AbortStack
orr
r1,r0,#IRQMODE|NOINT
msr
cpsr_cxsf,r1
;IRQMode
ldr
sp,=IRQStack
orr
r1,r0,#FIQMODE|NOINT
msr
cpsr_cxsf,r1
;FIQMode
ldr
sp,=FIQStack
bic
r0,r0,#MODEMASK|NOINT
orr
r1,r0,#SVCMODE
msr
cpsr_cxsf,r1
;SVCMode
ldr
sp,=SVCStack
mov
pc,lr
;Return the call routine
LTORG
;===============================================================================
; 内存区控制寄存器值表; 你可根据需要修改 bdinit.h 文件, 下面代码不用做任何改动
;===============================================================================
SMRDATA DATA
DCD
(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(
B7_BWSCON<<28))
DCD
((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0
DCD
((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1
DCD
((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2
DCD
((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3
DCD
((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4
DCD
((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5
DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6
DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7
DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M
DCD 0x30 ;MRSR6 CL=3clk
DCD 0x30 ;MRSR7
ALIGN
;===============================================================================
; 异常及中断向量表空间; 安装异常或中断处理程序在 bdisr.c 中,isr_setup()来完成.
;===============================================================================
AREA RamData, DATA, READWRITE
^ _ISR_STARTADDRESS ;表示下面数据区从_ISR_STARTADDRESS 指定的位置开始
HandleReset
# 4
HandleUndef
# 4
HandleSWI
# 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ
# 4
HandleFIQ
# 4
;=============================
; The Interrupt table
;=============================
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleRSV6
# 4
HandleBATFLT # 4
HandleTICK # 4
HandleWDT
# 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
HandleLCD
# 4
HandleDMA0
# 4
HandleDMA1
# 4
HandleDMA2
# 4
HandleDMA3
# 4
HandleMMC
# 4
HandleSPI0
# 4
HandleUART1
# 4
HandleRSV24
# 4
HandleUSBD
# 4
HandleUSBH
# 4
HandleIIC
# 4
HandleUART0
# 4
HandleSPI1
# 4HandleRTC
# 4
HandleADC
# 4
END
3.1.2 C 语言源代码说明
void bdmain(void)
{
/* 禁止 Cache 和 MMU */
cache_disable();
mmu_disable();
/* 端口初始化 */
port_init();
/* 中断处理程序 */
isr_init();
/* 串口初始化 */
serial_init(0, 115200);
/* 输出信息进行主循环 */
serial_printf("is ok!\n");
while(1) {
}
}
通常基本 ADS 的测试程序都可以在这个架构上加入自己的代码.
3.2 AXD 的使用
3.2.1 配置仿真器
1. 为仿真器安装 Server
一般的仿真器都对应有一个 Server 程序,所以在使用在线仿真之前,必须先安装这个 Server 程序。我使用
是 Dragon-ICE 仿真器, 所以先要安装 Dragon-ICE Server 程序。
2. 连接仿真器
把 dragon-ICE 仿真器的 JTAG 口连接上 ARM 板(注意:ARM 板要断电连接), 另一端通过并口连接到 PC 上,
有的仿真器是通过 USB 口连接到 PC 上, 这与仿真器的硬件相关。连接好后, 打开 ARM 电源,启动 ARM 板。
当 ARM 通电启动后,启动 Dragon-ICE Server 检测 ARM 板,详细步骤及设置参见对应的仿真器手册。我的
dragon-ICE Server 启动, 按”自动检测”可以检测到 ARM920T。
3.2.2 启动 AXD 配置开发板
1. 启动 AXD
先启动 Dragon-ICE Server 程序.
按如下步聚启动 AXD:
开始->所有程序->ARM Developer Suite v1.2->AXD Debugger
2. 装载仿真器库文件
从 AXD 菜单的 Options--> Configure Target...启动”Choose Target”目标板配置窗口.
在”Choose Target”窗口中,点击”Add”按钮,选择仿真器的库文件. 我的仿真器服务器程序安装在
c:\Dragon-ICE 下,所以选择项 c:\Dragon-ICE\dragon-ice.dll 文件.3. 为 AXD 在线仿真配置仿真器
在"Target Environments"中选中 Dragon-ICE 中,点击右边的"Configure"按钮.
在”FJB Dragon-ICE Release v1.2”窗口点击"This computer..."按钮,再点击"OK"按钮。
回到”Choose Target”窗口,点击"OK"按钮。完成配置.
回到主界面, 在右边的”Target”窗口会出现 ARM920T_0.这表明 AXD 已经进入 ARM 板的在线仿真状态.
点击菜单"System Views"-->"Controls Monitors".会出现"ARM920T-Register"窗口.此时,会显示当前 ARM 板上所
有寄存器的状态。
4. 配置 ARM 板
如果 ARM 板通电后,没有程序运行并把内存区控制寄存器配置好的说,外部 RAM 是不能使用的. 所以必须
通过仿真器来设置这些寄存器. 如果 ARM 板已经有启动程序并且已经配置好, 这一步可以省略.
首先把 2410cfg.txt 拷贝到 c:\下.
回到 AXD 主界面, 从菜单”System Views” --> “Command Line Interface”。会出现一个 Command Line
Interface 的调试命令行窗口,并显示如下提示符:
Debug >
输入 obey c:\2410cfg.txt 装载所有配置命令.
Debug >obey c:\2410cfg.txt
5. 2410cfg.txt 文件说明
sreg psr, 0x00000013
;设置当前 CPSR 的值, 把 CPU 的模式切换到 SVC 模式和 32 位指令集, 关闭 IRQ 和 FIQ。
smem 0x53000000,0,32
;设置看门狗控制寄存器 WTCON
;禁止看门狗定时器
smem 0x4C000004,((0x74<<12)+(0x3<<4)+0x1),32
;设置主频率设置寄存器 MPLLCON
;目前 CPU 的工作频率 FCLK 是 124.00MHz
smem 0x4C000014,0x3,32
;设置时钟分频寄存器 CLKDIVN
;设置 FCLK/HCLK/PCLK 的频率比例 1:2:4
smem 0x48000000,((2<<28)+(2<<24)+(1<<20)+(1<<16)+(1<<12)+(1<<8)+(1<<4)+0),32
;设置内存总线控制 BWSCON
;SDRAM BANK 6&7 is 32 位
;其它 BANK is 16 位
smem 0x48000004,((3<<13)+(3<<11)+(7<<8)+(3<<6)+(3<<4)+(3<<2)+3),32
;设置寄存器区 0 控制寄存器:BANKCON0
smem 0x4800001c,((3<<15)+(1<<2)+1),32
;设置寄存器区 6 控制寄存器: BANKCON6(SDRAM)
;RAS to CAS 延时 3 时钟周期
;列地址是 9 位
smem 0x48000020,((3<<15)+(1<<2)+1),32
;设置寄存器区 7 控制寄存器: BANKCON7(SDRAM)
;RAS to CAS 延时 3 时钟周期
;列地址是 9 位
smem 0x48000024,((1<<23)+(3<<18)+(2<<16)+1113),32
;set 外部 RAM 刷新寄存器:REFRESH
;允许自刷新
;HCLK=FCLK/2, 60MHz,刷新计算器是 1113
smem 0x48000028,0x31,32;设置寄存器的大小
;禁止 burst 操作
;允许 SDRAM power down 模式
;SCLK 在访问期间仍在活动状态
;SDRAM 模式寄存器设置
smem 0x4800002c,0x30,32
smem 0x48000030,0x30,32
3.2.3 使用 AXD 在线仿真调试程序
1. 装载可执行的文件
AXD 只支持.axf 格式的可执行文件.
启动 AXD, 在菜单的 File 中,选择 Load Image..., 选择 c:\adsbloadter\prj\prj_Data\DebugRel\prj.axf 加载执行
image. 就可以执行并调试了. AXD 提供了非常方便的调试手段, 包括在线单步, 自由设置断点等.
相关推荐
- Java项目宝塔搭建实战MES-Springboot开源MES智能制造系统源码
-
大家好啊,我是测评君,欢迎来到web测评。...
- 一个令人头秃的问题,Logback 日志级别设置竟然无效?
-
原文链接:https://mp.weixin.qq.com/s/EFvbFwetmXXA9ZGBGswUsQ原作者:小黑十一点半...
- 实战!SpringBoot + RabbitMQ死信队列实现超时关单
-
需求背景之为什么要有超时关单原因一:...
- 火了!阿里P8架构师编写堪称神级SpringBoot手册,GitHub星标99+
-
Springboot现在已成为企业面试中必备的知识点,以及企业应用的重要模块。今天小编给大家分享一份来着阿里P8架构师编写的...
- Java本地搭建宝塔部署实战springboot仓库管理系统源码
-
大家好啊,我是测评君,欢迎来到web测评。...
- 工具尝鲜(1)-Fleet构建运行一个Springboot入门Web项目
-
Fleet是JetBrains公司推出的轻量级编辑器,对标VSCode。该款产品还在公测当中,具体下载链接如下JetBrainsFleet:由JetBrains打造的下一代IDE。想要尝试的...
- SPRINGBOOT WEB 实现文件夹上传(保留目录结构)
-
网上搜到的SpringBoot的代码不多,完整的不多,能用的也不多,基本上大部分的文章只是提供了少量的代码,讲一下思路,或者实现方案。之前一般的做法都是使用HTML5来做的,大部都是传文件的,传文件夹...
- Java项目本地部署宝塔搭建实战报修小程序springboot版系统源码
-
大家好啊,我是测评君,欢迎来到web测评。...
- 新年IT界大笑料“工行取得基于SpringBoot的web系统后端实现专利
-
先看看专利描述...
- 看完SpringBoot源码后,整个人都精神了
-
前言当读完SpringBoot源码后,被Spring的设计者们折服,Spring系列中没有几行代码是我们看不懂的,而是难在理解设计思路,阅读Spring、SpringMVC、SpringBoot需要花...
- 阿里大牛再爆神著:SpringBoot+Cloud微服务手册
-
今天给大家分享的这份“Springboot+Springcloud微服务开发实战手册”共有以下三大特点...
- WebClient是什么?SpringBoot中如何使用WebClient?
-
WebClient是什么?WebClient是SpringFramework5引入的一个非阻塞、响应式的Web客户端库。它提供了一种简单而强大的方式来进行HTTP请求,并处理来自服务器的响应。与传...
- SpringBoot系列——基于mui的H5套壳APP开发web框架
-
前言 大致原理:创建一个main主页面,只有主页面有头部、尾部,中间内容嵌入iframe内容子页面,如果在当前页面进行跳转操作,也是在iframe中进行跳转,而如果点击尾部按钮切换模块、页面,那...
- 在Spring Boot中使用 jose4j 实现 JSON Web Token (JWT)
-
JSONWebToken或JWT作为服务之间安全通信的一种方式而闻名。...
- Spring Boot使用AOP方式实现统一的Web请求日志记录?
-
AOP简介AOP(AspectOrientedProgramming),面相切面编程,是通过代码预编译与运行时动态代理的方式来实现程序的统一功能维护的方案。AOP作为Spring框架的核心内容,通...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Java项目宝塔搭建实战MES-Springboot开源MES智能制造系统源码
- 一个令人头秃的问题,Logback 日志级别设置竟然无效?
- 实战!SpringBoot + RabbitMQ死信队列实现超时关单
- 火了!阿里P8架构师编写堪称神级SpringBoot手册,GitHub星标99+
- Java本地搭建宝塔部署实战springboot仓库管理系统源码
- 工具尝鲜(1)-Fleet构建运行一个Springboot入门Web项目
- SPRINGBOOT WEB 实现文件夹上传(保留目录结构)
- Java项目本地部署宝塔搭建实战报修小程序springboot版系统源码
- 新年IT界大笑料“工行取得基于SpringBoot的web系统后端实现专利
- 看完SpringBoot源码后,整个人都精神了
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)