Mini2440 SDRAM、NAND、MMU

1. SDRAM

   当加电默认从NAND启动时,先将4K代码复制到Steppingstone内RAM执行,在执行Steppingstone代码时,会将剩余的代码复制到SDRAM执行,但是使用SDRAM必须先对其有关SDRAM的寄存器进行初始化,以便能使用SDRAM

   主要包括寄存器: BWSCON、BANKCON0~7、REFRESH、BANKSIZE、MRSRB6~7

   这些寄存器要根据相应的单板进行设置,如下为Mini2440默认设置

 0x22011110,     //BWSCON 
 0x00000700,     //BANKCON0
 0x00000700,     //BANKCON1
 0x00000700,     //BANKCON2
 0x00000700,     //BANKCON3  
 0x00000700,     //BANKCON4
 0x00000700,     //BANKCON5
 0x00018005,     //BANKCON6
 0x00018005,     //BANKCON7
 0x008C07A3,     //REFRESH
 0x000000B1,     //BANKSIZE
 0x00000030,     //MRSRB6
 0x00000030,     //MRSRB7

    0x22011110  ;       @ BWSCON     //对不同的128M块进行设置
    0x00000700  ;   @ BANKCON0  //块0的设置,以下类同
    。。。
    0x00018005     ; @ BANKCON6  //主要考虑内存的列地址的位数,下一个类同
    。。。
    0x008C07A3    ; @ REFRESH       //这个值要注意晶振频率导致的差异,Mini440初始晶振=12mhz
    0x000000B1     ; @ BANKSIZE   
//内存块选取的设置
    0x00000030     ; @ MRSRB6       //对SDRAM时间参数进行设置

   对块初始化为例,如下

#define MEM_CTL_BASE 0x48000000

void memsetup(void)
{
	unsigned long const mem_cfg_val[] = {0x22011110,
										0x00000700,
										0x00000700,
										0x00000700,
										0x00000700,
										0x00000700,
										0x00000700,
										0x00018005,
										0x008c07a3,
										0x000000b1,
										0x00000030,
										0x00000030,
										};
	int i;
	volatile unsigned long* p = (volatile unsigned long*)MEM_CTL_BASE;
	for(i = 0; i<13; i++ )
	{
		p[i] = mem_cfg_val[i];
	}
}

这里将存储控制器所有的块以及特殊寄存器的设置都放到数组里,然后对他们一一初始化

2. MMU(内存管理单元)

     一般主要设置页表和内存的地址映射问题,先看一段启动的汇编代码

	AREA head,CODE,READONLY
	ENTRY
	CODE32
start
	ldr sp,=4096
	bl disable_watch_dog
	bl memsetup
	bl copy_2th_to_sdram
	bl create_page_table
	bl mmu_init
	ldr sp,=0xb4000000
	ldr pc,=0xb0004000
halt_loop
	b halt_loop
	END

这里可以看到主要有create_page_table 和mmu_init两部分进行MMU的设置,主要是地址的映射

下面看create_page_table虚拟地址的映射

void create_page_table(void)
{
	unsigned long virtaddr,physaddr;
	unsigned long *mmu_tlb_base = (unsigned long *)0x30000000;
	
#define MMU_FULL_ACESS  (3<<10)
#define MMU_DOMAIN      (0<<5)
#define MMU_SPECIAL     (1<<4)
#define MMU_CACHEABLE   (1<<3)
#define MMU_BUFFERABLE  (1<<2)
#define MMU_SECTION     (2<<0)
#define MMU_SECDESC     (MMU_FULL_ACESS | MMU_DOMAIN | MMU_SPECIAL | MMU_SECTION)
#define MMU_SECTION_WB  (MMU_SECDESC | MMU_CACHEABLE | MMU_BUFFERABLE)

	virtaddr = 0;
	physaddr = 0;
  //这个应该为mmu_tlb_base&fff00000
	*(mmu_tlb_base + (virtaddr>>20)) = (physaddr&0xfff00000)|MMU_SECTION_WB;


	virtaddr = 0xa0000000;
	physaddr = 0x56000000;
	*(mmu_tlb_base + (virtaddr>>20)) = (physaddr&0xfff00000)|MMU_SECTION;


	virtaddr = 0xb0000000;
	physaddr = 0x30000000;
	while(virtaddr < 0xb4000000)
	{
		*(mmu_tlb_base + (virtaddr>>20)) = (physaddr&0xfff00000)|MMU_SECTION_WB;
		physaddr += 0x100000;
		virtaddr += 0x100000;
	}
}


这个主要是虚拟地址的映射

virtaddr = 0xb0000000;     //虚拟地址,即连接后的地址
 physaddr = 0x30000000; //物理地址,实际程序在内存的运行地址
 while(virtaddr < 0xb4000000)
 {
  *(mmu_tlb_base + (virtaddr>>20)) = (physaddr&0xfff00000)|MMU_SECTION_WB;
  physaddr += 0x100000;
  virtaddr += 0x100000;
 }

这里是一级页表也就是采用段的方式,将页表的内存放到虚拟地址去,怎么放呢?

首先怎么得到页表?(physaddr&0xfff00000)段基址  MMU_SECTION_WB设置段的访问权限

那么如何放到虚拟地址呢?首先他一般是需要TLB寄存器的值和MVA的值组成,MVA即是virtaddr,TLB即是mmu_tlb_base,各位怎么放置请看手册

对于为何physaddr、virtaddr都是加0x100000? 这里段默认是只能访问1M的空间,而0x100000正好是1M

对于如何实现MMU呢?

void mmu_init(void)
{
	__asm{
	mov r0,#0
	mcr p15,0,r0,c7,c7,0  //使无效Icache和Dcache
	
	mcr p15,0,r0,c7,c10,0 
	mcr p15,0,r0,c8,c7,0  //使无效指令,数据TLB
	
	mov r4,#0
	mcr p15,0,r4,c2,c0,0 //设置页表寄存器
	
	mov r0,#0
	mcr p15,0,r0,c3,c0,0 //域访问控制寄存器,不进行权限检查
	
	
	mrc p15,0,r0,c1,c0,0 //读取控制寄存器
	
	bic r0,r0,#0x3000    //清除V、I位
	bic r0,r0,#0x300     //清除R、S位
	bic r0,r0,#0x0087    //清除B、C、A、M位
	
	orr r0,r0,#0x0002    //对齐检查
	orr r0,r0,#0x0004    //开启Dcache
	orr r0,r0,#0x1000    //开启Icache
	orr r0,r0,#0x0001    //使能MMU
	
	mcr p15,0,r0,c1,c0,0 //写入寄存器
	}
}	


请看右侧的注释    

3.NAND设置

    请先看如下设置图示

   

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值