下了一个uboot2009.11.1(lastest),准备移植到我们9260上。
先说说我的硬件:uboot要关心的是9260,sst39vf3201,dm9161,其他和at91sam9260ek的差不多。
这里面最大的差别就是norflash了,at91sam9260ek上虽然留了norflash的地方,但是那是空的,所以uboot里面默认的是CONFIG_SYS_NO_FLASH。而且像上就没有norflash的参考,都是nand和dataflash的参考。
at91sam9260的启动有两种方式,内部rom和外部flash,外部flash就是norflash,内部rom是内部集成一小段代码,具体可以参看datasheet,这样是为了可以从nandflash以及dataflash启动。
at91sam9260的风格来看,都喜欢在uboot前面加一级bootstrap,因为从内部rom启动时候,会先从nand或者data中拷贝4k的代码到内部sram0中执行,所以一般把bootstrap放在前4k的地方,具体的原理和做法可以参看。外部flash,norflash中,我们当然也可以用类似的方式,bootstrap+uboot,但是能在uboot完成的事我还是打算和到一起,也就是把bootstrap的工作移植到uboot,反正原来的参考都没考虑norflash的情况。
第一步:首先我们来看根目录下的makefile
at91sam9260ek_nandflash_config \
at91sam9260ek_dataflash_cs0_config \
at91sam9260ek_dataflash_cs1_config \
at91sam9260ek_config \
: unconfig
@mkdir -p $(obj)include
@if [ "$(findstring 9g20,$@)" ] ; then \
echo "#define CONFIG_AT91SAM9G20EK 1" >>$(obj)include/config.h ; \
$(XECHO) "... 9G20 Variant" ; \
else \
echo "#define CONFIG_AT91SAM9260EK 1" >>$(obj)include/config.h ; \
fi;
@if [ "$(findstring _nandflash,$@)" ] ; then \
echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \
$(XECHO) "... with environment variable in NAND FLASH" ; \
elif [ "$(findstring dataflash_cs0,$@)" ] ; then \
echo "#define CONFIG_SYS_USE_DATAFLASH_CS0 1" >>$(obj)include/config.h ; \
$(XECHO) "... with environment variable in SPI DATAFLASH CS0" ; \
else
echo "#define CONFIG_SYS_USE_DATAFLASH_CS1 1" >>$(obj)include/config.h ; \
$(XECHO) "... with environment variable in SPI DATAFLASH CS1" ; \
fi;
@$(MKCONFIG) -a at91sam9260ek arm arm926ejs at91sam9260ek atmel at91
|
上面我们可以看到at91sam9260_config默认就是是
at91sam9260ek_dataflash_cs1_config,(norflash直接被忽视了。。)我们来做下面的修改
at91sam9260ek_nandflash_config \
at91sam9260ek_dataflash_cs0_config \
at91sam9260ek_dataflash_cs1_config \
at91sam9260ek_config \
: unconfig
@mkdir -p $(obj)include
@if [ "$(findstring 9g20,$@)" ] ; then \
echo "#define CONFIG_AT91SAM9G20EK 1" >>$(obj)include/config.h ; \
$(XECHO) "... 9G20 Variant" ; \
else \
echo "#define CONFIG_AT91SAM9260EK 1" >>$(obj)include/config.h ; \
fi;
@if [ "$(findstring _nandflash,$@)" ] ; then \
echo "#define CONFIG_SYS_USE_NANDFLASH 1" >>$(obj)include/config.h ; \
$(XECHO) "... with environment variable in NAND FLASH" ; \
elif [ "$(findstring dataflash_cs0,$@)" ] ; then \
echo "#define CONFIG_SYS_USE_DATAFLASH_CS0 1" >>$(obj)include/config.h ; \
$(XECHO) "... with environment variable in SPI DATAFLASH CS0" ; \
elif [ "$(findstring dataflash_cs1,$@)" ] ; then \
echo "#define CONFIG_SYS_USE_DATAFLASH_CS1 1" >>$(obj)include/config.h ; \
$(XECHO) "... with environment variable in SPI DATAFLASH CS1" ; \
else \
echo "#define CONFIG_SYS_USE_NORFLASH 1" >>$(obj)include/config.h ; \
$(XECHO) "...with environment variable in NOR FLASH" ; \
fi;
@$(MKCONFIG) -a at91sam9260ek arm arm926ejs at91sam9260ek atmel at91
|
在config.h增加了CONFIG_SYS_USE_NORFLASH
第二部就是修改配置了,include/configs/at91sam9260ek.h
这里面有点我要特别提一下,就是AT91_MAIN_CLOK这个配置害我至少忙了一天,在以前的版本这个参数一般都是pll后的数值,但是到了最新版本这个参数就是main clock的值,也就是外部晶振的值,在cpu/arm926ejs/at91下面多了一个clock.c这个文件里面主要就是计算各种频率,方便是方便了,不过刚开始害我查了很久,还以为倍频出了问题。。郁闷一下。。
默认define了CONFIG_SKIP_LOWLEVEL_INIT和CONFIG_SKIP_RELOCATE_UBOOT,因为bootsrap,所以这两部分工作在uboot中是不需要的,但是我们合体了,所以还是需要的,所以因此增加很多配置,去掉CONFIG_SYS_NO_FLASH,增加
#define PHYS_FLASH_1 0x10000000
#define CONFIG_SYS_MAX_FLASH_SECT 1024
#define CONFIG_SYS_MAX_FLASH_BANKS 1
#define CONFIG_SYS_FLASH_BASE PHYS_FLASH_1
#define CONFIG_SYS_FLASH_ERASE_TOUT 100*CONFIG_SYS_HZ
#define CONFIG_SYS_FLASH_WRITE_OUT 2*CONFIG_SYS_HZ
#define CONFIG_SYS_MOR_VAL \
(AT91_PMC_MOSCEN | \
(64<<8))
#define CONFIG_SYS_PLLAR_VAL \
(AT91_PMC_PLLA_WR_ERRATA | \
AT91_PMC_PLLCOUNT | \
(AT91_PMC_MUL & (96<<16)) | \
(AT91_PMC_OUT & (2<<14))| \
(AT91_PMC_DIV & (9<<0)))
#define CONFIG_SYS_MCKR1_VAL \
(AT91_PMC_CSS_SLOW | \
AT91_PMC_PRES_1 | \
AT91SAM9_PMC_MDIV_2)
#define CONFIG_SYS_MCKR2_VAL \
(AT91_PMC_CSS_PLLA | \
AT91_PMC_PRES_1 | \
AT91SAM9_PMC_MDIV_2)
#define CONFIG_SYS_WDTC_WDMR_VAL AT91_WDT_WDDIS
/* SDRAMC_MR Mode register */
#define CONFIG_SYS_SDRC_MR_VAL1 0
/* SDRAMC_TR - Refresh Timer register */
#define CONFIG_SYS_SDRC_TR_VAL1 695
/* SDRAMC_CR - Configuration register*/
#define CONFIG_SYS_SDRC_CR_VAL \
(AT91_SDRAMC_NC_9 | \
AT91_SDRAMC_NR_13 | \
AT91_SDRAMC_CAS_2 | \
AT91_SDRAMC_NB_4 | \
AT91_SDRAMC_DBW_32 | \
(2<<8) | \
(7<<12) | \
(2<<16) | \
(2<<20) | \
(5<<24) | \
(8<<28)) /* Exit Self Refresh to Active Delay */
/* Memory Device Register -> SDRAM */
#define CONFIG_SYS_SDRC_MDR_VAL AT91_SDRAMC_MD_SDRAM
#define CONFIG_SYS_SDRC_MR_VAL2 AT91_SDRAMC_MODE_PRECHARGE
#define CONFIG_SYS_SDRAM_VAL1 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRC_MR_VAL3 AT91_SDRAMC_MODE_REFRESH
#define CONFIG_SYS_SDRAM_VAL2 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRAM_VAL3 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRAM_VAL4 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRAM_VAL5 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRAM_VAL6 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRAM_VAL7 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRAM_VAL8 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRAM_VAL9 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRC_MR_VAL4 AT91_SDRAMC_MODE_LMR
#define CONFIG_SYS_SDRAM_VAL10 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRC_MR_VAL5 AT91_SDRAMC_MODE_NORMAL
#define CONFIG_SYS_SDRAM_VAL11 0 /* SDRAM_BASE */
#define CONFIG_SYS_SDRC_TR_VAL2 1200 /* SDRAM_TR */
#define CONFIG_SYS_SDRAM_VAL12 0 /* SDRAM_BASE */
/* setup SMC0, CS0 (NOR Flash) - 16-bit, 15 WS */
#define CONFIG_SYS_SMC0_SETUP0_VAL \
(AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) | \
AT91_SMC_NRDSETUP_(2) | AT91_SMC_NCS_RDSETUP_(1))
#define CONFIG_SYS_SMC0_PULSE0_VAL \
(AT91_SMC_NWEPULSE_(6) | AT91_SMC_NCS_WRPULSE_(7) | \
AT91_SMC_NRDPULSE_(8) | AT91_SMC_NCS_RDPULSE_(8))
#define CONFIG_SYS_SMC0_CYCLE0_VAL \
(AT91_SMC_NWECYCLE_(8) | AT91_SMC_NRDCYCLE_(10))
#define CONFIG_SYS_SMC0_MODE0_VAL \
(AT91_SMC_READMODE | AT91_SMC_WRITEMODE | \
AT91_SMC_DBW_16 | \
AT91_SMC_TDFMODE | \
AT91_SMC_TDF_(1))
/* user reset enable */
#define CONFIG_SYS_RSTC_RMR_VAL \
(AT91_RSTC_KEY | \
AT91_RSTC_PROCRST | \
AT91_RSTC_RSTTYP_WAKEUP | \
AT91_RSTC_RSTTYP_WATCHDOG)
#define CONFIG_SYS_PIOC_PDR_VAL1 0xFFFF0000
#define CONFIG_SYS_PIOC_PPUDR_VAL 0xFFFF0000
#define CONFIG_SYS_MATRIX_EBICSA_VAL \
(AT91_MATRIX_DBPUC | AT91_MATRIX_VDDIOMSEL_3_3V | \
AT91_MATRIX_CS1A_SDRAMC)
|
最后还要改的就是环境有关的配置
#define CONFIG_ENV_IS_IN_FLASH 1
#define CONFIG_SYS_U_BOOT_BASE PHYS_FLASH_1
#define CONFIG_SYS_U_BOOT_SIZE 0x0002e000
#define CONFIG_ENV_ADDR (PHYS_FLASH_1 + 0x0002e000)
#define CONFIG_ENV_SIZE 0x00001000
|
第三部norflash驱动的问题,
两种方法,通过配置直接使用mtd的驱动,还有就是自己在board下增加flash,我现在先直接拷贝了at91rm9200dk里面的flash.c,简单修改,这部分flash主要是后面uboot命令中使用,现在可以先不用,所以我暂时没调试,只是简单添加了sst39vf3201的信息。
在board/atmel/at91sam9260ek的Makefile中添加
COBJS-$(CONFIG_SYS_USE_NORFLASH) +=flash.o
|
这时候make clean all就可以编译出uboot.bin了,下载到板子,串口有各种信息了。。
心得体会:
(1)调试,boot很难调,我想可能指示灯会一个好方式
在汇编中我使用让指示灯亮来看运行情况
ldr r0, =0xfffff400
ldr r1, =0x000001e0 ;假设指示灯pa5,6,7,8
str r1, [r0]
ldr r0, =0xfffff410
ldr r1, =0x000001e0 ;假设指示灯pa5,6,7,8
str r1, [r0]
ldr r0, =0xfffff434
ldr r1, =0x000001e0 ;假设指示灯都是低电平亮
str r1, [r0]
|
在调试频率,我发现在uboot中有个udelay函数可调用,这个udelay(1000000)一秒,灯亮熄,可以看看频率上是否有问题。
(2)外部flash中没有代码时,jtag是不能检测到arm的(我跟硬件工程师说,他居然不相信我,**),是的hjtag不行,flashaccess我试了也不行,就是banyan,有人说行,不知,成功的给指导一下哈。。所以一般外部flash没有代码时候我用内部rom启动,往flash下代码。
下一步工作:
(1)flash的驱动,写擦要ok,我想有可能还是用mtd的驱动
(2)网口驱动,这部分我之前没搞过,称这次把原理搞搞清楚
阅读(3664) | 评论(0) | 转发(0) |