s3c2440时钟+nandflash拷贝至SDRAM+开启mmu
来源:互联网 发布:天天向上网络版权费 编辑:程序博客网 时间:2024/06/05 15:50
涉及6个文件
head.S,init.c,main.c,makefile,nand.c,out.lds
head.S
.text.global _start_start: b ResetHandleUndef: b HandleUndef HandleSWI: b HandleSWIHandlePrefetchAbort: b HandlePrefetchAbortHandleDataAbort: b HandleDataAbortHandleNotUsed: b HandleNotUsed b HandleIRQHandleFIQ: b HandleFIQReset:ldr r0, =0x53000000mov r1, #0x0str r1, [r0]@disable watchdogmsr cpsr_c, #0xd2@IRQ mode,ARM mode,IRQ disableldr sp, =3072 msr cpsr_c, #0xd3@Supervisor mode,ARM mode,IRQ disableldr sp, =1024*4@set up stack,4Kmsr cpsr_c, #0x53@Supervisor mode,ARM mode,IRQ enableldr sp, =4096bl clock_initbl memsetupbl nand_init ldr r0, =0x30000000@target address(sdram),nand_read 1parameter mov r1, #4096@start address,nand_read 2parameter mov r2, #2048*2@size copy to sdram,nand_read 3parameterbl nand_readbl create_page_tablebl mmu_init ldr sp, =0xB4000000@pstack go to sdramldr lr, =halt_loopldr pc, =mainhalt_loop:b halt_loopHandleIRQ:sub lr, lr, #4stmdb sp!, {r0-r12,lr} ldr lr, =int_return ldr pc, =TIMER_Handle int_return:ldmia sp!, { r0-r12,pc }^
init.c
#defineBWSCON(*(volatile unsigned long *)0x48000000) #defineBANKCON0(*(volatile unsigned long *)0x48000004)#defineBANKCON1(*(volatile unsigned long *)0x48000008)#defineBANKCON2(*(volatile unsigned long *)0x4800000C)#defineBANKCON3(*(volatile unsigned long *)0x48000010)#defineBANKCON4(*(volatile unsigned long *)0x48000014)#defineBANKCON5 (*(volatile unsigned long *)0x48000018)#defineBANKCON6 (*(volatile unsigned long *)0x4800001C)#defineBANKCON7 (*(volatile unsigned long *)0x48000020)#defineREFRESH (*(volatile unsigned long *)0x48000024)#defineBANKSIZE (*(volatile unsigned long *)0x48000028)#defineMRSRB6(*(volatile unsigned long *)0x4800002C)#defineMRSRB7(*(volatile unsigned long *)0x48000030)#defineCLKDIVN(*(volatile unsigned long *)0x4C000014)#defineMPLLCON(*(volatile unsigned long *)0x4C000004)#define S3C2440_MPLL_400MHZ 0x5C011void memsetup(){BWSCON=0x22011110;BANKCON0=0x00000700;//sramBANKCON1=0x00000700;//romBANKCON2=0x00000700;BANKCON3=0x00000700;BANKCON4=0x00000700;BANKCON5=0x00000700;BANKCON6=0x00018005;//sdramBANKCON7=0x00018005;REFRESH=0x008C04F4;BANKSIZE=0x000000B1;MRSRB6=0x00000030;MRSRB7=0x00000030;}void clock_init(){CLKDIVN=0x05;__asm__( "mrc p15, 0, r1, c1, c0, 0\n" "orr r1, r1, #0xc0000000\n" "mcr p15, 0, r1, c1, c0, 0\n" ); MPLLCON=S3C2440_MPLL_400MHZ;}void create_page_table(void){#define MMU_FULL_ACCESS (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) #define MMU_SECDESC (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | MMU_SECTION)#define MMU_SECDESC_WB (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | \ MMU_CACHEABLE | MMU_BUFFERABLE | MMU_SECTION)#define MMU_SECTION_SIZE 0x00100000 unsigned long virtuladdr, physicaladdr; unsigned long *mmu_tlb_base = (unsigned long *)0x30000000; virtuladdr = 0; physicaladdr = 0; *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | MMU_SECDESC_WB;//0~4096 the same virtuladdr = 0x56000000; physicaladdr = 0x56000000; *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | MMU_SECDESC; virtuladdr = 0x4A000000; physicaladdr = 0x4A000000; *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | MMU_SECDESC; virtuladdr = 0x51000000; physicaladdr = 0x51000000; *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | MMU_SECDESC; /*SDRAM to 0xB0000000~0xB4000000*/ virtuladdr = 0xB0000000; physicaladdr = 0x30000000; while (virtuladdr < 0xB4000000) { *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | MMU_SECDESC_WB; virtuladdr += 0x100000; physicaladdr += 0x100000; }}/* * 启动MMU */void mmu_init(void){ unsigned long ttb = 0x30000000;__asm__( "mov r0, #0\n" "mcr p15, 0, r0, c7, c7, 0\n" "mcr p15, 0, r0, c7, c10, 4\n" "mcr p15, 0, r0, c8, c7, 0\n" "mov r4, %0\n" "mcr p15, 0, r4, c2, c0, 0\n" "mvn r0, #0\n" "mcr p15, 0, r0, c3, c0, 0\n" "mrc p15, 0, r0, c1, c0, 0\n" "bic r0, r0, #0x3000\n" "bic r0, r0, #0x0300\n" "bic r0, r0, #0x0087\n" "orr r0, r0, #0x0002\n" "orr r0, r0, #0x0004\n" "orr r0, r0, #0x1000\n" "orr r0, r0, #0x0001\n" "mcr p15, 0, r0, c1, c0, 0\n" : : "r" (ttb) );}
main.c
/*led1 f4,led2 f5,led3 f6,int0 f0*/#defineGPFCON(*(volatile unsigned long *)0x56000050)#defineGPFDAT(*(volatile unsigned long *)0x56000054)#defineGPF4_OUT(1<<(4*2))#defineGPF5_OUT(1<<(5*2))#defineGPF6_OUT(1<<(6*2))#defineGPF4_CON_MSK(3<<(4*2))#defineGPF5_CON_MSK(3<<(5*2))#defineGPF6_CON_MSK(3<<(6*2))#defineGPF4_DAT_MSK(1<<(4))#defineGPF5_DAT_MSK(1<<(5))#defineGPF6_DAT_MSK(1<<(6))#define TIMER0_MSK(1<<(10))#defineTCFG0(*(volatile unsigned long *)0x51000000)#defineTCON(*(volatile unsigned long *)0x51000008)#defineTCNTB0(*(volatile unsigned long *)0x5100000C)#define INTOFFSET(*(volatile unsigned long *)0x4A000014)#define SRCPND(*(volatile unsigned long *)0X4A000000)#define INTMSK(*(volatile unsigned long *)0X4A000008)#define PRIORITY(*(volatile unsigned long *)0x4A00000C)#define INTPND(*(volatile unsigned long *)0X4A000010)void init_timer0(){SRCPND=0x0;INTMSK=~TIMER0_MSK;TCFG0=0xff;TCNTB0=0xffff;TCON=0xa;TCON=0x9;}void led_set_out(){GPFCON&=~(GPF4_CON_MSK|GPF5_CON_MSK|GPF6_CON_MSK); GPFCON|=GPF4_OUT|GPF5_OUT|GPF6_OUT;GPFDAT&=~(GPF4_DAT_MSK);GPFDAT&=~(GPF5_DAT_MSK);GPFDAT&=~(GPF6_DAT_MSK);GPFDAT|=(1<<4);GPFDAT|=(1<<5);GPFDAT|=(1<<6);}void led_reset(int ledn){if(ledn==1){GPFDAT|=(1<<4);}else if(ledn==2){GPFDAT|=(1<<5);}else{GPFDAT|=(1<<6);}}void led_set(int ledn){if(ledn==1){GPFDAT&=~(GPF4_DAT_MSK);}else if(ledn==2){GPFDAT&=~(GPF5_DAT_MSK);}else{GPFDAT&=~(GPF6_DAT_MSK);}}void TIMER_Handle(){int i;led_set(1);for(i=0;i<1000000;i++);led_reset(1);SRCPND=1<<INTOFFSET;INTPND=1<<INTOFFSET;}int main(){int i;led_set_out();init_timer0();while(1){led_reset(2);for(i=0;i<10000000;i++);led_set(2);for(i=0;i<10000000;i++);}return 0;}
makefile
out.bin : head.S main.c nand.c init.carm-linux-gcc -c -o head.o head.Sarm-linux-gcc -c -o main.o main.carm-linux-gcc -c -o nand.o nand.carm-linux-gcc -c -o init.o init.carm-linux-ld -Tout.lds head.o main.o nand.o init.o -o out_elfarm-linux-objcopy -O binary -S out_elf out.binarm-linux-objdump -D -m arm out_elf > out.dis#rm -f out.dis out_elf *.oclean:rm -f out.dis out.bin out_elf *.o
nand.c
#define LARGER_NAND_PAGE#define GSTATUS1 (*(volatile unsigned int *)0x560000B0)#define BUSY 1#define NAND_SECTOR_SIZE 512#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)#define NAND_SECTOR_SIZE_LP 2048#define NAND_BLOCK_MASK_LP (NAND_SECTOR_SIZE_LP - 1)typedef unsigned int S3C24X0_REG32;/* NAND FLASH (see S3C2410 manual chapter 6) */typedef struct { S3C24X0_REG32 NFCONF; S3C24X0_REG32 NFCMD; S3C24X0_REG32 NFADDR; S3C24X0_REG32 NFDATA; S3C24X0_REG32 NFSTAT; S3C24X0_REG32 NFECC;} S3C2410_NAND;/* NAND FLASH (see S3C2440 manual chapter 6, www.100ask.net) */typedef struct { S3C24X0_REG32 NFCONF; S3C24X0_REG32 NFCONT; S3C24X0_REG32 NFCMD; S3C24X0_REG32 NFADDR; S3C24X0_REG32 NFDATA; S3C24X0_REG32 NFMECCD0; S3C24X0_REG32 NFMECCD1; S3C24X0_REG32 NFSECCD; S3C24X0_REG32 NFSTAT; S3C24X0_REG32 NFESTAT0; S3C24X0_REG32 NFESTAT1; S3C24X0_REG32 NFMECC0; S3C24X0_REG32 NFMECC1; S3C24X0_REG32 NFSECC; S3C24X0_REG32 NFSBLK; S3C24X0_REG32 NFEBLK;} S3C2440_NAND;typedef struct { void (*nand_reset)(void); void (*wait_idle)(void); void (*nand_select_chip)(void); void (*nand_deselect_chip)(void); void (*write_cmd)(int cmd); void (*write_addr)(unsigned int addr); unsigned char (*read_data)(void);}t_nand_chip;static S3C2410_NAND * s3c2410nand = (S3C2410_NAND *)0x4e000000;static S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;static t_nand_chip nand_chip;/* 供外部调用的函数 */void nand_init(void);void nand_read(unsigned char *buf, unsigned long start_addr, int size);/* NAND Flash操作的总入口, 它们将调用S3C2410或S3C2440的相应函数 */static void nand_reset(void);static void wait_idle(void);static void nand_select_chip(void);static void nand_deselect_chip(void);static void write_cmd(int cmd);static void write_addr(unsigned int addr);static unsigned char read_data(void);/* S3C2410的NAND Flash处理函数 */static void s3c2410_nand_reset(void);static void s3c2410_wait_idle(void);static void s3c2410_nand_select_chip(void);static void s3c2410_nand_deselect_chip(void);static void s3c2410_write_cmd(int cmd);static void s3c2410_write_addr(unsigned int addr);static unsigned char s3c2410_read_data();/* S3C2440的NAND Flash处理函数 */static void s3c2440_nand_reset(void);static void s3c2440_wait_idle(void);static void s3c2440_nand_select_chip(void);static void s3c2440_nand_deselect_chip(void);static void s3c2440_write_cmd(int cmd);static void s3c2440_write_addr(unsigned int addr);static unsigned char s3c2440_read_data(void);/* S3C2410的NAND Flash操作函数 *//* 复位 */static void s3c2410_nand_reset(void){ s3c2410_nand_select_chip(); s3c2410_write_cmd(0xff); // 复位命令 s3c2410_wait_idle(); s3c2410_nand_deselect_chip();}/* 等待NAND Flash就绪 */static void s3c2410_wait_idle(void){ int i; volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFSTAT; while(!(*p & BUSY)) for(i=0; i<10; i++);}/* 发出片选信号 */static void s3c2410_nand_select_chip(void){ int i; s3c2410nand->NFCONF &= ~(1<<11); for(i=0; i<10; i++); }/* 取消片选信号 */static void s3c2410_nand_deselect_chip(void){ s3c2410nand->NFCONF |= (1<<11);}/* 发出命令 */static void s3c2410_write_cmd(int cmd){ volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFCMD; *p = cmd;}/* 发出地址 */static void s3c2410_write_addr(unsigned int addr){ int i; volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFADDR; *p = addr & 0xff; for(i=0; i<10; i++); *p = (addr >> 9) & 0xff; for(i=0; i<10; i++); *p = (addr >> 17) & 0xff; for(i=0; i<10; i++); *p = (addr >> 25) & 0xff; for(i=0; i<10; i++);}/* 读取数据 */static unsigned char s3c2410_read_data(void){ volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFDATA; return *p;}/* S3C2440的NAND Flash操作函数 *//* 复位 */static void s3c2440_nand_reset(void){ s3c2440_nand_select_chip(); s3c2440_write_cmd(0xff); // 复位命令 s3c2440_wait_idle(); s3c2440_nand_deselect_chip();}/* 等待NAND Flash就绪 */static void s3c2440_wait_idle(void){ int i; volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT; while(!(*p & BUSY)) for(i=0; i<10; i++);}/* 发出片选信号 */static void s3c2440_nand_select_chip(void){ int i; s3c2440nand->NFCONT &= ~(1<<1); for(i=0; i<10; i++); }/* 取消片选信号 */static void s3c2440_nand_deselect_chip(void){ s3c2440nand->NFCONT |= (1<<1);}/* 发出命令 */static void s3c2440_write_cmd(int cmd){ volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD; *p = cmd;}/* 发出地址 */static void s3c2440_write_addr(unsigned int addr){ int i; volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR; *p = addr & 0xff; for(i=0; i<10; i++); *p = (addr >> 9) & 0xff; for(i=0; i<10; i++); *p = (addr >> 17) & 0xff; for(i=0; i<10; i++); *p = (addr >> 25) & 0xff; for(i=0; i<10; i++);}static void s3c2440_write_addr_lp(unsigned int addr){int i;volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;int col, page;col = addr & NAND_BLOCK_MASK_LP;page = addr / NAND_SECTOR_SIZE_LP;*p = col & 0xff;/* Column Address A0~A7 */for(i=0; i<10; i++);*p = (col >> 8) & 0x0f; /* Column Address A8~A11 */for(i=0; i<10; i++);*p = page & 0xff;/* Row Address A12~A19 */for(i=0; i<10; i++);*p = (page >> 8) & 0xff;/* Row Address A20~A27 */for(i=0; i<10; i++);*p = (page >> 16) & 0x03;/* Row Address A28~A29 */for(i=0; i<10; i++);}/* 读取数据 */static unsigned char s3c2440_read_data(void){ volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA; return *p;}/* 在第一次使用NAND Flash前,复位一下NAND Flash */static void nand_reset(void){ nand_chip.nand_reset();}static void wait_idle(void){ nand_chip.wait_idle();}static void nand_select_chip(void){ int i; nand_chip.nand_select_chip(); for(i=0; i<10; i++);}static void nand_deselect_chip(void){ nand_chip.nand_deselect_chip();}static void write_cmd(int cmd){ nand_chip.write_cmd(cmd);}static void write_addr(unsigned int addr){ nand_chip.write_addr(addr);}static unsigned char read_data(void){ return nand_chip.read_data();}/* 初始化NAND Flash */void nand_init(void){#define TACLS 0#define TWRPH0 3#define TWRPH1 0 /* 判断是S3C2410还是S3C2440 */ if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002)) { nand_chip.nand_reset = s3c2410_nand_reset; nand_chip.wait_idle = s3c2410_wait_idle; nand_chip.nand_select_chip = s3c2410_nand_select_chip; nand_chip.nand_deselect_chip = s3c2410_nand_deselect_chip; nand_chip.write_cmd = s3c2410_write_cmd; nand_chip.write_addr = s3c2410_write_addr; nand_chip.read_data = s3c2410_read_data;/* 使能NAND Flash控制器, 初始化ECC, 禁止片选, 设置时序 */ s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); } else { nand_chip.nand_reset = s3c2440_nand_reset; nand_chip.wait_idle = s3c2440_wait_idle; nand_chip.nand_select_chip = s3c2440_nand_select_chip; nand_chip.nand_deselect_chip = s3c2440_nand_deselect_chip; nand_chip.write_cmd = s3c2440_write_cmd;#ifdef LARGER_NAND_PAGE nand_chip.write_addr = s3c2440_write_addr_lp;#elsenand_chip.write_addr = s3c2440_write_addr;#endif nand_chip.read_data = s3c2440_read_data;/* 设置时序 */ s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4); /* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */ s3c2440nand->NFCONT = (1<<4)|(1<<1)|(1<<0); } /* 复位NAND Flash */ nand_reset();}/* 读函数 */void nand_read(unsigned char *buf, unsigned long start_addr, int size){ int i, j;#ifdef LARGER_NAND_PAGE if ((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP)) { return ; /* 地址或长度不对齐 */ }#else if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) { return ; /* 地址或长度不对齐 */ }#endif /* 选中芯片 */ nand_select_chip(); for(i=start_addr; i < (start_addr + size);) { /* 发出READ0命令 */ write_cmd(0); /* Write Address */ write_addr(i);#ifdef LARGER_NAND_PAGE write_cmd(0x30);#endif wait_idle();#ifdef LARGER_NAND_PAGE for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++) {#else for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {#endif *buf = read_data(); buf++; } } /* 取消片选信号 */ nand_deselect_chip(); return ;}
out.lds
SECTIONS { firtst 0x00000000 : { head.o nand.o init.o} second 0xB0000000 : AT(4096) { main.o }}
0 0
- s3c2440时钟+nandflash拷贝至SDRAM+开启mmu
- S3C2440与SDRAM NorFlash NandFlash连线分析
- S3C2440与SDRAM NorFlash NandFlash连线分析
- S3C2440--MMU
- S3C2440-SDRAM
- S3C2440 SDRAM
- Mini2440 SDRAM、NAND、MMU
- NandFlash、NorFlash、DataFlash、SDRAM
- 原来程序是这样从NandFlash拷贝并跳转到SDRAM的
- 06-S3C2440学习之移植2012u-boot到S3C2440(移植过程一)新建单板+修改时钟+SDRAM+UART
- S3C2440-时钟
- s3c2440 mmu 裸机程序
- s3c2440学习笔记 MMU
- S3C2440 MMU内存管理
- S3C2440——MMU
- S3C2440 SDRAM内存驱动
- S3C2440 SDRAM内存驱动
- S3C2440 SDRAM内存驱动
- leetcode:Implement Trie (Prefix Tree)
- Android:获取版本号
- 动态规划——小胖办证
- poj 2002 hash(平面上若干点能够成多少正方形)
- leetcode: Basic Calculator
- s3c2440时钟+nandflash拷贝至SDRAM+开启mmu
- 冥想
- leetcode:Integer to English Words
- 新手
- ubuntu 安装配置 JDK
- leetcode:Remove Invalid Parentheses
- android studio中做断点测试
- Java设计模式(二十二)----调停者模式
- 【C语言】C语言常量和变量