百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

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框架的核心内容,通...

取消回复欢迎 发表评论: