Nios II的Boot过程分析
2012-12-10
标签:

5Bootloader解读

Altera提供了两个bootloader程序,一个用于从EPCS器件中boot,另一个用于从flash器件中boot。它们的汇编源码和makefile都在C:\altera\kits\nios2_51\components\altera_nios2\sdk\src\boot_loader_sources目录中。其中boot_loader.s是公共部分,而boot_loader_epcs_bits.s则用于从EPCS器件中Boot,boot_loader_cfi_bits.s用于从flash中Boot。

5.1 boot_loader.s解读

#ifdef EPCS

#define FIND_PAYLOADsub_find_payload_epcs// 查找EPCS中数据负荷子程序

#define READ_INTsub_read_int_from_flash_epcs// 从EPCS中读取一个32位word

#define STREAMING_COPY sub_streaming_copy_epcs// 从EPCS中拷贝流的子程序

#define CLOSE_DEVICEsub_epcs_close// 关闭EPCS器件的子程序

#else

#define FIND_PAYLOADsub_find_payload_cfi// 查找CFI并行flash中数据负荷的子程序

#define READ_INTsub_read_int_from_flash_cfi// 从CFI并行flash中读取一个32位的word

#define STREAMING_COPY sub_streaming_copy_cfi// 从CFI并行flash中拷贝流的子程序

#endif

#include "boot_loader.h"

.global reset

.global _start

.global main

.global end_of_boot_copier

reset:

_start:

main:

// 清除CPU的状态寄存器禁止中断,这个动作在硬件复位的时候其实已经自动完成。.

wrctlstatus, r_zero

// 冲刷指令cache.

// Nios II 最多支持64Kbytes的指令cache,所以只初始化了64Kbytes的指令cache

movhir_flush_counter,%hi(0x10000)

cache_loop:

initir_flush_counter

// 没有必要初始化数据cache, bootloader不存取存贮器数据

addir_flush_counter, r_flush_counter,-32

bner_flush_counter, r_zero, cache_loop

// 冲刷流水线

flushp

// r_flash_ptr = find_payload();

// 调用查找数据负荷子程序寻找数据负荷

nextpcreturn_address_less_4

brFIND_PAYLOAD

// 拷贝.

//

// 在循环的开始,寄存器r_flash_ptr 包含“程序记录”的地址。

//

// 1) 读取“程序记录”的长度域(4-bytes)(r_data_size)

// 2) 读取“程序记录”的目的地址域(4-bytes)(r_dest)

// 3) 循环:

//拷贝 r_data_size 个字节, 一次一个字节: *r_dest++ = *r_flash_ptr++

// 把0xFFFFFFFF装入r_halt_record,用于测试是否要停机。

subir_halt_record, r_zero, 1

per_record_loop:

//读取“程序记录”的长度域,r_data_size = READ_INT(r_flash_ptr++)。

nextpcreturn_address_less_4

brREAD_INT

movr_data_size, r_read_int_return_value

// 读取“程序记录”的目的地址域,r_dest = READ_INT(r_flash_ptr++)。

nextpcreturn_address_less_4

brREAD_INT

movr_dest, r_read_int_return_value

// 测试长度域是否为0

// 如果是就直接运行程序

beqr_data_size, r_zero, last_program_record

// 如果长度域为-1(0xFFFFFFFF),就停机。

halt_record_forever:

beqr_data_size, r_halt_record, halt_record_forever

// 使用拷贝流子程序搬移数据

nextpcreturn_address_less_4

brSTREAMING_COPY

// 程序运行到这里,表明已经处理了当前的“程序记录”了,

// 而且知道这不是最后一个“程序记录”因为它的长度域不为0,

// 这就意味着要处理下一个“程序记录”。

brper_record_loop

last_program_record:

// 处理完最后一个程序记录后就要把控制权转给实际的运行程序.

// r_dest是实际程序的入口地址

// 在中止boot-loader之前要关闭EPCS器件,如果不做这一步,

// 会导致HAL的open()调用要花好几秒钟才能打开EPCS器件

#ifdef EPCS

nextpcreturn_address_less_4

brCLOSE_DEVICE

#endif

// 跳转到目的地址运行程序

callrr_dest

afterlife:// 程序跑到这里表明有问题。

brafterlife

.end

共 5 页   上一页12345下一页
可能会用到的工具/仪表
相关文章
推荐文章
热门文章
章节目录
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号