关于s3c2440从nand flash的疑惑

zzfei90 2012-11-29 04:35:13
我知道2440从nand flash启动的时候会先由硬件把前4K的代码搬到片内的sram中去,然后从片内的sram开始运行,再把nand flash中的程序搬到外部sdram里面去,然后程序由内部sram跳到外部sdram去执行,这里我就有个疑惑,把程序从nand flash搬到外部sdram的时候,已经搬到内部sram的那4K还要搬吗?
还有一个问题,也是我最想问的问题,程序从nand flash搬到外部sdram后,中断向量表应该有两份吧,一份在片内sram(地址0x00000000)的起始地址处,一份在片外的sdram中(地址0x30000000),当发生中断的时候,PC会跳到地址0处,如果已经初始化了MMU的话,程序会跳到映射后的地址,也就是0x30000000处,这样的话,中断程序理所当然可以正常执行。但是,如果没有开MMU的话,程序跳到物理地址的0x00000000处,这里也有一份中断向量表啊,应该也能够正常的跳到中断函数去执行啊,可是为什么事实不行呢?手册上有说这4K的sram在启动后可以用作其他用途,但是我没有用啊,那内容应该还是原来的内容,那为什么不能正常跳到中断函数里去呢?问题在哪里?小弟用的是天嵌的开发板,前几天刚到手的。
...全文
282 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
nadleeh 2012-12-03
  • 打赏
  • 举报
回复
你可以看看u-boot中,对应的芯片的star.S 以及该文件下的源码,对你有帮助
nadleeh 2012-12-03
  • 打赏
  • 举报
回复
那前4k,最大的作用是初始化内存和数据总线,不关中断的事
nadleeh 2012-12-03
  • 打赏
  • 举报
回复
你怎么知道前4k有中断向量表
zzfei90 2012-12-03
  • 打赏
  • 举报
回复
引用 15 楼 JQGuardian 的回复:
我老实用我的开发板试了下,在我的板子上使用的异常向量表是被映射到0地址的SRAM上。另外,由于我的TLB把0x0 - 0xa0000000的虚拟地址映射到了对应的实地址,所以不管开没开MMU都是使用的SRAM上的中断向量。 至于你的情况, 一、你在u-boot中检查下SRAM中的内容,是否被改变。 二、检查CP15 c0的V位设置,有源码就看看开,关MMU的语句……
我刚才看了下,我的0x00000000地址不能访问,往里面写数,再读出来,全是0,但是外部sdram的地址0x30000000可以正常访问,真郁闷…
HMGuardian 2012-12-03
  • 打赏
  • 举报
回复
我老实用我的开发板试了下,在我的板子上使用的异常向量表是被映射到0地址的SRAM上。另外,由于我的TLB把0x0 - 0xa0000000的虚拟地址映射到了对应的实地址,所以不管开没开MMU都是使用的SRAM上的中断向量。 至于你的情况, 一、你在u-boot中检查下SRAM中的内容,是否被改变。 二、检查CP15 c0的V位设置,有源码就看看开,关MMU的语句。 如果这个位被置为‘1’,则异常向量表的位置将不再是地址‘0’。 三、异常向量表的跳转指令是否正确。 关MMU不能执行异常中断应该是这三处地方……
zzfei90 2012-12-03
  • 打赏
  • 举报
回复
引用 13 楼 JQGuardian 的回复:
网上查了一下,异常向量表的位置并非总是从0地址开始的,协处理器cp15中有相关设置。 我s3c6410是arm1176jzfs核心的CP15的c1寄存器[13]即‘V’bit可能选择异常向量的位置 0 = Normal exception vectors selected, the Vector Base Address Registers determine th……
呵呵,首先,谢谢你能认真的看并回答我的问题。 以下是我的开发板资料中启动代码中的一段: void RdNF2SDRAM( ) { U32 i; U32 start_addr = 0x0; unsigned char * to = (unsigned char *)0x30000000; U32 size = 0x100000; rNF_Init(); switch(rNF_ReadID()) { case 0x76: for(i = (start_addr >> 9); size > 0; ) { rSB_ReadPage(i, to); size -= 512; to += 512; i ++; } break; case 0xf1: case 0xda: case 0xdc: case 0xd3: for(i = (start_addr >> 11); size > 0; ) { rLB_ReadPage(i, to); size -= 2048; to += 2048; i ++; } break; } } 从上面代码看,在从nand flash往sdram复制程序的时候,是从地址0开始复制的,也就是全部都复制到了sdram里面去了,而且我在网上查了,有的说是全部,有的说是不带前4k,这个好像有不一样的。 下面是我2440init.s里面的一段内容的汇编后代码: __ENTRY ResetEntry $a Init 0x00000000: eafffffe .... B ResetHandler ; 0x120 0x00000004: eafffffe .... B HandlerUndef ; 0x78 0x00000008: eafffffe .... B HandlerSWI ; 0x90 0x0000000c: eafffffe .... B HandlerPabort ; 0xc0 0x00000010: eafffffe .... B HandlerDabort ; 0xa8 0x00000014: eafffffe .... B {pc} ; 0x14 0x00000018: e59ff0dc .... LDR HandlerIRQ 0x0000001c: eafffffe .... B HandlerFIQ ; 0x48 0x00000020: eafffffe .... B EnterPWDN ; 0x3f4 这个2440init.s在链接器里面是设置过的放在生成目标文件的最开始的部分的,也就是0x0的地方,从汇编过的代码来看,在0x00-0x1c地址处,放的也正是中断向量表,所以在生成的.bin文件中,这个中断向量表应该也是在最开始的地方,将.bin下载到nand flash里面后,也应该在最开始的地方,而上电后,nand控制器将前4k的内容自动复制到片内sram内,所以,在sram开始的位置,肯定是有一份中断向量表的。那么不开mmu的时候,如果发生中断,程序应该会跳到这个地方来的,可是为什么这里的跳转不能正确将程序引导到中断处理函数中去呢?跳转指令我改过了,用的是ldr,用绝对地址来跳
HMGuardian 2012-12-03
  • 打赏
  • 举报
回复
网上查了一下,异常向量表的位置并非总是从0地址开始的,协处理器cp15中有相关设置。 我s3c6410是arm1176jzfs核心的CP15的c1寄存器[13]即‘V’bit可能选择异常向量的位置 0 = Normal exception vectors selected, the Vector Base Address Registers determine the address range, reset value. 1 = High exception vectors selected, address range = 0xFFFF0000-0xFFFF001C. 当值为0时,CP15的c12还可以进一步设置异常向量的基地址,当然,默认情况下是0x0。 建议你阅读和你CPU核心相关的文档并参看你的u-boot源码看看! 不过,我的开发板的异常向量在物理地址57e00000虚拟地址为c7e00000,但找了半天没看到设置CP15的c12寄存器,对于这个情况相当不解,有待继续查找原因…………
HMGuardian 2012-12-03
  • 打赏
  • 举报
回复
嗯,认真看了一下你的描述。 先说第一个问题吧: 从u-boot-2012.10源码中我开发板的情况来看是没有复制前4K的内容的,注意下面函数的第二个参数。 板配置文件中的宏定义: #define CONFIG_SYS_NAND_U_BOOT_OFFS (4 * 1024) 加载nand中的u-boot到dram的加载函数的声明。 //函数声明 static int nand_load(struct mtd_info *mtd, unsigned int offs, unsigned int uboot_size, uchar *dst) //加载nand中的u-boot到dram的加载函数调用 nand_load(&nand_info, CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE, (uchar *)CONFIG_SYS_NAND_U_BOOT_DST); 这是u-boot关于nand起动的通常情况。但具体的要看你开发板对于这个功能的实现,以及对于u-boot镜像的构造情况。 通常的nand起动的镜像是由根目录下的u-boot和nand_spl下的u-boot-spl这两部分的所构成的。从根目录makefile中的目标可以看出这个过程: $(obj)u-boot-nand.bin: nand_spl $(obj)u-boot.bin cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin 还是那句话,这是通常情况………… 第二种情况,前面说了一点,我开发板运行于SRAM的4K代码是没有中断向量的也没有中断处理程序。至于开MMU,后我开发板的地址映射是0x0 - 0xA000000的虚拟地址和实地址是一一映射,所以有点糊涂了,脑袋一时转不过了……^_^
HMGuardian 2012-12-03
  • 打赏
  • 举报
回复
这是我从u-boot2012.10/arch/arm/cpu/arm1176/start.S中复制的部分代码。由IROM复制到SRAM中的前4K代码是木有中断向量表滴,这4K代码是同nand_spl//board/下面你开发板相关文件夹里面的Makefile生成的,其中最重要的就是生成CONFIG_NAND_SPL宏及make变量。再根据下面的代码,中断向量表当然是要被跳过编译啰!!

.globl _start
_start: b	reset
#ifndef CONFIG_NAND_SPL
	ldr	pc, _undefined_instruction
	ldr	pc, _software_interrupt
	ldr	pc, _prefetch_abort
	ldr	pc, _data_abort
	ldr	pc, _not_used
	ldr	pc, _irq
	ldr	pc, _fiq
所以,大部分的u-boot中两份中断向量表是不存在的。
nadleeh 2012-12-03
  • 打赏
  • 举报
回复
引用 9 楼 zzfei90 的回复:
如果不开mmu的话,发生了中断程序会跳转到0x0去执行,这个物理0x0地址就在sram中,所以跟中断还是有关的,只不过平时大家用的时候都开了mmu所以才看起来无关
中断发生了,会跳转到0x0偏转若干字节(4的整数倍),去执行放再那的指令,但是这里只有4个字节,你的中断函数放的下么,那里要放自己写的异常向量处理,系统起来的话系统已经帮你做了这个工作,裸板自己必须写。 再说如果中断就直接跳过去执行你的东西去了,那么cpu中断时的执行的东西岂不是丢了,那你的函数执行完了怎么回去呢?
zzfei90 2012-12-03
  • 打赏
  • 举报
回复
如果不开mmu的话,发生了中断程序会跳转到0x0去执行,这个物理0x0地址就在sram中,所以跟中断还是有关的,只不过平时大家用的时候都开了mmu所以才看起来无关
zzfei90 2012-12-03
  • 打赏
  • 举报
回复
引用 5 楼 nadleeh123 的回复:
你怎么知道前4k有中断向量表
这个是肯定的,因为0x0到0x1c处存放的就是中断向量表
zzfei90 2012-12-01
  • 打赏
  • 举报
回复
引用 3 楼 nadleeh123 的回复:
也就是条b 指令
这个肯定是有的啊,nand flash里面的前4k内容不也是从内部sram复制过去的吗?只要nand flash里面有,sram里面肯定也有的啊
nadleeh 2012-11-30
  • 打赏
  • 举报
回复
也就是条b 指令
nadleeh 2012-11-30
  • 打赏
  • 举报
回复
按你的说法的确那2个地方的确是放异常入口的地方,但是那里前提是要有东西
wesley 2012-11-30
  • 打赏
  • 举报
回复
我最近也在弄,同样疑惑中。。。

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧