最新新闻:

    如何编译bootloader,linux内核和文件系统「高级语言编写的程序可移植」

    时间:2022-11-25 14:41:37来源:搜狐

    今天带来如何编译bootloader,linux内核和文件系统「高级语言编写的程序可移植」,关于如何编译bootloader,linux内核和文件系统「高级语言编写的程序可移植」很多人还不知道,现在让我们一起来看看吧!

    你们要的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

    ;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

    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

    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

    bl bdmain

    ;Jump to the main function

    ;Dead loop

    1

    nop

    b

    ;===============================================================================

    ; 初始中断处理程序

    ;===============================================================================

    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­ICEdragon­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:adsbloadterprjprj_DataDebugRelprj.axf 加载执行

    image. 就可以执行并调试了. AXD 提供了非常方便的调试手段, 包括在线单步, 自由设置断点等.

    声明:文章仅代表原作者观点,不代表本站立场;如有侵权、违规,可直接反馈本站,我们将会作修改或删除处理。

    图文推荐

    热点排行

    精彩文章

    热门推荐