ARM9学习笔记一:SAM9G45的启动过程

学些这么多天的bootstarp,做下总结吧,没什么新的东西,都是自己通过网站搜索、看手册文档和实际动手后,

学习到的一些基础知识,菜鸟也是一步一步学习出来。以前从来没有接触过ARM9这么高端的芯片,有个项目要

裸跑,就当做个ARM学习笔记系列吧,希望能够帮助一些还没有接触过的后来人。


一、上电启动过程

1.1首先看数据手册:

系统总是从地址0x00开始启动,有2 个参数可以修改启动的地址。
 REMAP 允许用户把内部SRAM 映射到0x0 地址,以降低开发的难度,这是一旦系统
启动时,通过软件设置的。
 BMS 允许用户把ROM 或者外部存储器映射到0x0,这是系统复位时通过硬件进行设
置的。
注意:所有的存储块都可以直接使用它们自己的基地址,而不关心其他的参数。


说明下:

1)、在上电驱动时候,启动方式有BMS决定;

2)、上电启动后,可以通过软件配置寄存,从SRAM启动;为什么呢?这个是为了引导程序做的。


继续看书册:

如果BMS 为0,则从外部总线接口与片选0 连在一起的存储器进行启动。
 利用片上RC 进行启动
 使用静态存储控制器的默认配置启动:字节模式,16-位数据总线,通过芯片选择的读
/写控制,允许从16-位不变的内存中启动。
为了达到优化的目的,并不需要做其他事情。如果想提高启动的速度,用户的程序需要执行
一套完整的配置:
 如果需要精确的时钟,32768Hz 的晶振需要启用
 进行PMC(主振荡器启用还是被旁路)配置
 配置和启用PLL
 重新为EBI CS0 连接的芯片配置SMC 的设置,周期,保持时间,模式,时序寄存器,
以适应新的时钟
 把系统时钟切换到一个新的值


也就是说当BMS为0的时候,程序从与片选0相连接的NOR Flash(可以在片内运行程序)启动。

这个启动过程仍然需要bootstarp,只不过是运行在NOR FLASH上。

注:

1)就是前面那篇博客说的那样,这里对于NOR FLASH型号没有提及,可能驱动是统一的。


继续看手册:

如果BMS 为1,则会通过内置的ROM 来进行启动,以下的程序将会执行。
启动程序是放在内置的ROM 里,也叫做“Rom code”或者“First level bootloader”。
当上电时,如果BMS 检测到为1,芯片将会从内置的ROM 启动,里面的程序会被执行。
启动程序包含了几个步骤。第一,进行设备的初始化,然后尝试从外部的存储器(NVM)
进行启动。最后,如果在NVM 找不到有效的程序,则会执行一段叫做SAM-BAR Monitor
的监控程序。


如果是空白的板子:

可以通过SAM-BA v2.16这个软件下载程序。


如果已经烧写了bootstarp,那么ROM就会找到这个boot,并且拷贝到SRAM,并且自动从SRAM首地址开始执行。

(应为NAND,SD,CF,DATA FLASH不能执行程序)。

首先来看看查找过程:


这个图是手册给的顺序,那么怎么知道是否找到了有效了boot程序呢?

继续看手册:

1、NVM 启动程序读取和分析前28 个字节代码作为首7 个ARM 异常向量。对于第6 个向量
的字节必须含有ARM 的跳转指令或者加载相对地址到PC 的指令。

2、NVM 启动程序在FTA12/16/32 格式下的NVM Flash 的根目录下查找boot.bin 文件。

我们来看第一种情况,怎么把向量放到程序前面,怎么指定长度?

把中断放到程序前面,需要在分散加载文件里面指定:


上图是启动文件和分散加载文件截图,通过first,我们把中断向量定义到了程序开始。前面7条指令包含跳转或者加载指令,我们解决了。

剩下一个问题,怎么指定文件长度?

开始我把第六个中断向量改为0,程序还是能运行。请教别人,才知道,这个大小是有第三方插件(SAM-BA v2.16)在下载程序时候,自己根据bin文件

修改的,不需要程序员自己修改。

bootstarp文件问题基本解决,这里再说多说几句,加载地址貌似是无用的,但是运行地址必须设置为SRAM地址。并且大小不能超过60K,应为bootrom

的栈占据了4K大小。


好了,到此为止,bootrom能够找到bootstarp,并且拷贝到SRAM里面。

我们再来看看官方给的bootstarp历程,其实程序很简单,注释很清楚,主要是关注一些参数。

主要是看board.h和boot.h,main.h


board.h

/// Frequency of the board main oscillator.
#define BOARD_MAINOSC           12000000


/// Master clock frequency (when using board_lowlevel.c).
// ((12MHz / DIVA / PLLADIV2 / MDIV) * (MULA+1)
#define BOARD_MCK               ((unsigned long)((BOARD_MAINOSC / 3 / 2 / 3) * 200 )) // 133MHz



/// Board DDRAM size
#define BOARD_DDRAM_SIZE        (64*1024*1024)  // 128 MB
/// List of all SDRAM pins definitions.
#define PINS_DDRAM              {0xFFFF0000, AT91C_BASE_PIOC, AT91C_ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT}
/// DDRAM bus width.
#define BOARD_DDRAM_BUSWIDTH    16
/// SDRAM bus width.
#define BOARD_SDRAM_BUSWIDTH    32


/// Nandflash controller peripheral pins definition.
#define PINS_NANDFLASH          BOARD_NF_CE_PIN, BOARD_NF_RB_PIN
/// Nandflash chip enable pin definition.
#define BOARD_NF_CE_PIN         {1 << 14, AT91C_BASE_PIOC, AT91C_ID_PIOC, PIO_OUTPUT_1, PIO_DEFAULT}
/// Nandflash ready/busy pin definition.
#define BOARD_NF_RB_PIN         {1 << 8, AT91C_BASE_PIOC, AT91C_ID_PIOC, PIO_INPUT, PIO_PULLUP}
/// Address for transferring command bytes to the nandflash.
#define BOARD_NF_COMMAND_ADDR   0x40400000
/// Address for transferring address bytes to the nandflash.
#define BOARD_NF_ADDRESS_ADDR   0x40200000
/// Address for transferring data bytes to the nandflash.
#define BOARD_NF_DATA_ADDR      0x40000000


/// Address for transferring command bytes to the norflash.
#define BOARD_NORFLASH_ADDR     0x10000000
/// Default NOR bus size after power up reset
#define BOARD_NORFLASH_DFT_BUS_SIZE 16

以及一些PIN引脚的定义



main.h主要关注这个结构体:

typedef struct _Tdesc {
    unsigned int   offset;   /// Memory offset for non FAT formated memory
    const char    *fileName; /// File Name for FAT formated memory (SDCard)    
    unsigned int   dest;     /// Destination address
    unsigned int   size;     /// Module size in bytes
    const char    *strDescr; /// Module description (optional, can be null pointer)
} Tdesc;


#define TDESC_LISTSIZE(list) (sizeof(list)/ sizeof(Tdesc))


boot.h

#if defined(ORIGIN_sdcard)
// memory source address is not used for SDcard boot (only STR_FILE)
#define FROM_ADDR 0
#else
// file name is not used for non formated memory boot (only FROM_ADDR)
#define FILE_NAME ""
#endif



const Tdesc tabDesc[] = {
    {FROM_ADDR, FILE_NAME, DEST_ADDR, BIN_SIZE, STR_DESCR}    
};


这些选择宏在MDK的定义的宏里面:


at91sam9m10  定义板子型号,和linux引导有关
ORIGIN_nandflash  定义引导闪存类型
DESTINATION_ddram  定义外置RAM类型
FROM_ADDR=0x20000  定义用户程序的加载地址
DEST_ADDR=0x70000000  定义运行地址
BIN_SIZE=0x30000  用户程序大小
TRACE_LEVEL=4  这个是一些调试信息的打印级别
NOFPUT 这个是输出定义,具体看代码吧


至此可以编译下载,并且引导程序了,可能是U-BOOT,也可能是用户程序。



  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值