一 代码树
二 工程组织结构
主Makefile:board/at91sam9260ek/nandflash/Makefile
链接脚本:elf32-littlearm.lds
系统入口:crt0_gnu.S
三 流程分析
在elf32-littlearm.lds的第三行,ENTRY(reset),说明程序的入口点是标号reset,此标号在crt0_gnu.S中。
在crt0_gnu.S中,找到reset标号,程序从此处开始执行。
进行9260的时钟源的设置
进行c语言运行环境初始化
最后进入main函数
main.c是我们程序的主体
首先进行硬件初始化,hw_init
然后从nand flash里面加载代码,load_nandflash
然后返回要跳转的地址,return JUMP_ADDR;//u-boot在ram中的物理地址
返回到crt0_gnu.S继续执行
bx r0,此句就是跳转到main函数返回的地址处。
也就是跳转到bootstrap所加载的程序(uboot)继续执行
四 代码分析
几个重要的函数。
hw_init(按顺序),在board/at91sam9260ek/at91sam9260ek.c中
关掉watchdog
设置PLL,也就是9260的运行频率
设置IO口
初始化SDRAM
load_nandflash,在driver/nandflash.c中
首先初始化nand flash硬件
然后读取nand flash ID,获取相关信息,包括总线宽度,块大小等。
然后从flash中读取数据加载到指定地址
五 移植相关
SDRAM的总线宽度和容量大小
board/at91sam9260ek/at91sam9260ek.c
/* Configure SDRAM Controller */
sdram_init( AT91C_SDRAMC_NC_9 |
AT91C_SDRAMC_NR_13 |
AT91C_SDRAMC_CAS_2 |
AT91C_SDRAMC_NB_4_BANKS |
AT91C_SDRAMC_DBW_32_BITS |
AT91C_SDRAMC_TWR_2 |
AT91C_SDRAMC_TRC_7 |
AT91C_SDRAMC_TRP_2 |
AT91C_SDRAMC_TRCD_2 |
AT91C_SDRAMC_TRAS_5 |
AT91C_SDRAMC_TXSR_8, /* Control Register */
(MASTER_CLOCK * 7)/1000000, /* Refresh Timer Register */
AT91C_SDRAMC_MD_SDRAM); /* SDRAM (no low power) */
红色字体处控制sdram是32bit还是16bit
board/at91sam9260ek/nandflash/at91sam9260ek.h
#define JUMP_ADDR 0x23F00000 /* Final Jump Address */
加载地址,根据sdram的实际容量来变化
9260的主频设置
board/at91sam9260ek/nandflash/at91sam9260ek.h中定义
#define MASTER_CLOCK (198656000/2)
#define PLL_LOCK_TIMEOUT 1000000
#define PLLA_SETTINGS 0x2060BF09
#define PLLB_SETTINGS 0x10483F0E
/* Switch MCK on PLLA output PCK = PLLA = 2 * MCK */
#define MCKR_SETTINGS (AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_2)
#define MCKR_CSS_SETTINGS (AT91C_PMC_CSS_PLLA_CLK | MCKR_SETTINGS)