----------------------------------------------------------
使用环境
PC: Centos5.4
kernel: 3.0.1
corss: arm-linux-gcc 4.4.1
arm: s3c6410
uboot: uboot-2010-03
----------------------------------------------------------
第一处修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #ifndef CONFIG_NAND_SPL /* * flush v4 I/D caches */ mov r0, #0 mcr p15, 0, r0, c7, c7, 0/* flush v3/v4 cache */ mcr p15, 0, r0, c8, c7, 0/* flush v4 TLB */ /* * disable MMU stuff and caches//////////////////////////////////////////////// */ mrc p15, 0, r0, c1, c0, 0 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) orr r0, r0, #0x00000002 @ set bit 2 (A) Align orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache mcr p15, 0, r0, c1, c0, 0//从后面拷贝过来的 ///////////////////////////////以下的注释掉 /* Prepare to disable the MMU */ //adr r1, mmu_disable_phys /* We presume we're within the first 1024 bytes */ //and r1, r1, #0x3fc //ldr r2, _TEXT_PHY_BASE //ldr r3, =0xfff00000 //and r2, r2, r3 //orr r2, r2, r1 //b mmu_disable //.align 5 /* Run in a single cache-line */ //mmu_disable: // mcr p15, 0, r0, c1, c0, 0 // nop // nop // mov pc, r2 //////////////////////////////////////////////////////////////////// |
第二处修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | bl lowlevel_init /* go setup pll,mux,memory */ 之后 /* when we already run in ram, we don't need to relocate U-Boot.//////////////////////////////////////////////////////////////////// * and actually, memory controller must be configured before U-Boot * is running in ram. */ ldr r0, =0xff000fff bic r1, pc, r0 /* r0 <- current base addr of code */ ldr r2, _TEXT_BASE /* r1 <- original base addr in ram */ bic r2, r2, r0 /* r0 <- current base addr of code */ cmp r1, r2 /* compare r0, r1 */ beq after_copy /* r0 == r1 then skip flash copy */ #ifdef CONFIG_BOOT_NAND mov r0, #0x1000 bl copy_from_nand #endif after_copy://////////////////////////////////////////////////////// #ifdef CONFIG_ENABLE_MMU |
上面的修改是判断到底是从Nand Flash启动还是RAM启动;
1.如果是从nandflash中启动,那么PC的值一定在4K之内。那么执行完bicr1,pc,r0 之后,r1为0。_TEXT_BASE要么等于0x57e00000,要么等于0xC7e00000.那么执行完bicr2,r2,r0 之后,r2为0x00e00000,那么不相等,则不跳转,下面应该就是copy_from_nand。
2.如果是从ram中启动,那么PC的值为0xx7e00000。那么执行完bicr1,pc,r0 之后,r1为0x00e00000。_TEXT_BASE要么等于0x57e00000,要么等于0xC7e00000.那么执行完bicr2,r2,r0 之后,r2为0x00e00000,那么相等,跳转到after_copy,也就是不需要copy。承接上面分析,如果没有完成copy,则接下来就是copy_from_nand。
第三处修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #ifndef CONFIG_NAND_SPL /* * we assume that cache operation is done before. (eg. cleanup_before_linux()) * actually, we don't need to do anything about cache if not use d-cache in * U-Boot. So, in this function we clean only MMU. by scsuh * * void theLastJump(void *kernel, int arch_num, uint boot_params); */ #ifdef CONFIG_ENABLE_MMU .globl theLastJump theLastJump: 之前加上以下语句 /* * copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND) * r0: size to be compared * Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size *//////////////////////////////////////////////////////////////////////////////// .globl copy_from_nand copy_from_nand: mov r10, lr /* save return address */ mov r9, r0 /* get ready to call C functions */ ldr sp, _TEXT_PHY_BASE/* setup temp stack pointer */ sub sp, sp, #12 mov fp, #0 /* no previous frame, so fp=0 */ mov r9, #0x1000 bl copy_uboot_to_ram //此函数需要添加,稍后说明。 3: tst r0, #0x0 bne copy_failed ldr r0, =0x0c000000 ldr r1, _TEXT_PHY_BASE 1: ldr r3, [r0], #4 ldr r4, [r1], #4 teq r3, r4 bne compare_failed/* not matched */ subs r9, r9, #4 bne 1b 4: mov lr, r10 /* all is OK */ mov pc, lr copy_failed: nop /* copy from nand failed */ b copy_failed compare_failed: nop /* compare failed */ b compare_failed |
接着进入u-boot-2010.03/include/configs编辑smdk6410.h,添加下面的宏定义;
1.
1 | #definevirt_to_phys(x) virt_to_phy_smdk6410(x) |
2.
1 | #defineCONFIG_SYS_PROMPT 'SMDK6410#' /*MonitorCommandPrompt */ |
1 | 这里的”SMDK6410”可以自己修改,这就是你进入uboot的命令模式的#前面的文字。 |
1 |
1 2 | //#definePHYS_SDRAM_1_SIZE 0x08000000 /*128MBinBank#1 */ #definePHYS_SDRAM_1_SIZE 0x10000000 /*256MBinBank#1 */ |
1 | 修改SDRAM内存为256M的。 |
1 |
1 2 3 4 | /*NANDconfiguration*/ #defineNAND_DISABLE_CE()(NFCONT_REG|= (1<<1)) #defineNAND_ENABLE_CE()(NFCONT_REG&=~(1<<1)) #defineNF_TRANSRnB() do{while(!(NFSTAT_REG&(1<<0)));}while(0) |
1 | 这里的定义是后面写nand_cp.c要用到的宏定义 |
1 |
1 2 3 4 5 | /* *Architecturemagicandmachinetype */ //#define MACH_TYPE 1270/*smdk6400ID*/ #defineMACH_TYPE 1626/*smdk6410ID*/ |
1 | 6410的ID号; |
1 |
1 2 3 4 5 6 | /* *Sizeofmalloc()pool */ //#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE+1024*1024) #defineCONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE+512*1024) #defineCONFIG_SYS_GBL_DATA_SIZE 128 /*sizeinbytesforinitialdata*/ |
1 | 修改内存大小; |
1 |
1 | #defineCONFIG_BOOTDELAY 3 |
1 | 修改bootdelay延迟时间 |
1 |
1 2 3 4 | //#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE +0x7e00000) /*126MBinDRAM*/ #defineCONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE +0x9e00000) /*256MBinDRAM*/ |
1 | 修改SDROM大小; |
1 |
1 2 3 4 | /*the PWMTImer4usesacounterof15625for10ms,soweneed*/ /*ittowrap100times (total1562500)toget1sec.*/ //#define CONFIG_SYS_HZ 1000 //atPCLK50MHz #defineCONFIG_SYS_HZ 1562500 |
1 | 时钟修改; |
1 | 10. |
1 2 | //#define CONFIG_STACKSIZE 0x40000 /*regularstack256KB*/ #defineCONFIG_STACKSIZE 0x80000 /*regularstack512KB*/ |
1 | 堆栈大小修改; |
1 | 11. |
1 2 | //#define PHYS_SDRAM_1_SIZE 0x08000000 /*128MBinBank#1 */ #definePHYS_SDRAM_1_SIZE0x10000000 /*256MBinBank#1 */ |
1 | Nand Flash每块大小修改; |
1 | 12. |
1 2 | //#define CONFIG_ENV_SIZE 0x4000 /*TotalSizeofEnvironmentSector*/ #defineCONFIG_ENV_SIZE 0x80000 /*TotalSizeofEnvironmentSector*/ |
1 | Total Size of Environment Sector修改; |
1 | 13. |
1 2 3 4 | //#define CONFIG_BOOTCOMMAND 'nand read 0x50018000 0x60000 0x1c0000;' //'bootm0x50018000' #define CONFIG_BOOTCOMMAND 'nand read 0x50018000 0x100000 0x500000;' 'bootm0x50018000' |
1 | CONFIG_BOOTCOMMAND修改 |
1 | 14. |
1 | #defineCONFIG_ENV_OFFSET 0x0080000 |
1 | CONFIG_ENV_OFFSET修改 |
1 | 15. |
1 2 | //#define CONFIG_SYS_NAND_PAGE_SIZE 2048 #defineCONFIG_SYS_NAND_PAGE_SIZE 4096 |
1 | Nand Flash每一页大小的修改 |
1 | 16. |
1 2 3 | /*NANDchipblocksize */ //#define CONFIG_SYS_NAND_BLOCK_SIZE (128*1024) #defineCONFIG_SYS_NAND_BLOCK_SIZE (512*1024) |
1 | Nand Flash每一块大小的修改 |
1 | 17. |
1 2 3 | /*NANDchippageperblockcount */ //#define CONFIG_SYS_NAND_PAGE_COUNT 64 #defineCONFIG_SYS_NAND_PAGE_COUNT 128 |
1 | 校验位修改 |
1 | 并将里面的所有6400除了(#define CONFIG_S3C6400 1)替换为6410 |
1 |
1 | 接下来在u-boot-2010.03/cpu/arm1176/下面新建一个nand_cp.c文件,代码如下: |
1 2 3 4 | #include #ifdefCONFIG_S3C64XX #include #include |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include staticintnandll_read_page(uchar*buf,ulongaddr,intlarge_block) { inti; intpage_size=512; /* 2K */ if(large_block==1) page_size=2048; /* 4K */ if(large_block==2) page_size=4096; NAND_ENABLE_CE(); NFCMD_REG=NAND_CMD_READ0; /*WriteAddress*/ NFADDR_REG=0; if(large_block) NFADDR_REG=0; |
1 2 3 4 5 6 7 8 9 10 | NFADDR_REG=(addr)&0xff; NFADDR_REG=(addr>>8)&0xff; NFADDR_REG=(addr>>16)&0xff; /* #defineNFCMD_REG __REG(ELFIN_NAND_BASE+NFCMMD_OFFSET) #defineELFIN_NAND_BASE 0x70200000 #defineNFCMMD_OFFSET 0x08 NFCMD_REG=(*( (volatileu32*) (0x70200008) )) NFCMMD 0x70200008 NANDFlash命令设置寄存器0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 | #define NAND_CMD_READSTART 0x30 */ if(large_block) NFCMD_REG=NAND_CMD_READSTART; /* define NF_TRANSRnB() do{ while( !( NFSTAT_REG&(1<<0) ) ); }while(0) #define NFSTAT_REG __REG(ELFIN_NAND_BASE+NFSTAT_OFFSET) NFSTAT_REG=(*( (volatileu32*) (0x70200028) )) NFSTAT 0x70200028 NANDFlash操作状态寄存器 */ NF_TRANSRnB(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /*forcompatibility(2460).u32cannotbeused.byscsuh*/ for(i=0;i { *buf++=NFDATA8_REG; } /* #defineNAND_DISABLE_CE()(NFCONT_REG|= (1<<1)) #defineNFCONT_REG __REG(ELFIN_NAND_BASE+NFCONT_OFFSET) #define__REG(x) (*((volatileu32*)(x))) #defineELFIN_NAND_BASE 0x70200000 #defineNFCONT_OFFSET 0x04 */ NAND_DISABLE_CE(); return0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | staticintnandll_read_blocks(ulongdst_addr,ulongsize,int large_block) { uchar*buf=(uchar*)dst_addr; inti; uintpage_shift=9; if(large_block==1) page_shift=11; /*Readpages*/ if(large_block==2) page_shift=12; if(large_block==2) { /*Readpages*/ for(i=0;i<4;i++,buf+=(1<<(page_shift-1))) { nandll_read_page(buf,i,large_block); } /*Readpages*/ /* 0x3c000 = 111100000000000000 */ |
1 2 3 4 5 6 7 8 9 10 11 12 13 | for(i=4;i<(0x3c000>>page_shift);i++,buf+=(1< { nandll_read_page(buf,i,large_block); } } else { for(i=0;i<(0x3c000>>page_shift);i++,buf+=(1< { nandll_read_page(buf,i,large_block); } } return0; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | } intcopy_uboot_to_ram(void) { intlarge_block =0; inti; vu_charid; /* #defineNAND_ENABLE_CE() (NFCONT_REG&=~(1<<1)) #defineNFCONT_REG __REG(ELFIN_NAND_BASE+NFCONT_OFFSET) #define__REG(x) (*((volatileu32*)(x))) #defineELFIN_NAND_BASE 0x70200000 #defineNFCONT_OFFSET 0x04 NFCONT_REG=(*( (volatileu32*) (0x70200004) )) NFCONT0x70200004 读/写NANDFlash控制寄存器 [0]1:NANDFlash控制器使能 */ NAND_ENABLE_CE(); |
1 2 3 4 5 6 7 8 | /* #defineNFCMD_REG __REG(ELFIN_NAND_BASE+NFCMMD_OFFSET) #defineELFIN_NAND_BASE 0x70200000 #defineNFCMMD_OFFSET 0x08 NFCMD_REG=(*( (volatileu32*) (0x70200008) )) NFCMMD 0x70200008 NANDFlash命令设置寄存器0 #defineNAND_CMD_READID 0x90 |
1 2 3 4 5 6 7 8 9 10 11 | */ NFCMD_REG=NAND_CMD_READID; * #defineNFADDR_REG __REG(ELFIN_NAND_BASE+NFADDR_OFFSET) #defineELFIN_NAND_BASE 0x70200000 #defineNFADDR_OFFSET 0x0C NFADDR_REG =(*( (volatileu32*) (0x7020000C) )) NFADDR0x7020000C NANDFlash地址设置寄存器 */ NFADDR_REG= 0x00; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /* #define NFDATA8_REG __REGb(ELFIN_NAND_BASE+NFDATA_OFFSET) #define__REGb(x) (*(vu_char*)(x)) NFDATA8_REG = (*( (vu_char*) (0x70200010) )) NFDATA0x70200010 读/写NANDFlash数据寄存器 NANDFlash 读/烧写数据值用于I/O */ /*waitforawhile*/ for(i=0;i<200;i++); id=NFDATA8_REG; id=NFDATA8_REG; if(id>0x80) large_block=1; if(id ==0xd5) large_block=2; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /*readNANDBlock. *128KB->240KBbecauseofU-Bootsizeincrease.byscsuh *So,read0x3c000bytesnot0x20000(128KB). */ /* #define CONFIG_SYS_PHY_UBOOT_BASE (CONFIG_SYS_SDRAM_BASE+0x07e00000) #define CONFIG_SYS_SDRAM_BASE 0x50000000 CONFIG_SYS_PHY_UBOOT_BASE= 0x57e00000 0x3c000 = 1M */ returnnandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE,0x3c000,large_block); } #endif |
1 |
1 | 修改u-boot-2010.03/cpu/arm1176/Makefile,在COBJS = cpu.o后面加nand_cp.o |
1 | COBJS = cpu.o nand_cp.o |
1 | 修改u-boot-2010.03/board/samsung/smdk6410/u-boot-nand.lds,添加nand_cp.o 如下: |
1 2 3 4 5 6 7 8 | { cpu/arm1176/start.o (.text) cpu/arm1176/s3c64xx/cpu_init.o (.text) board/samsung/smdk6410/lowlevel_init.o (.text) cpu/arm1176/nand_cp.o(.text) lib_arm/board.o (.text) *(.text) } |
上一篇:u-boot2010.03 移植篇(二)-----修改start.S,支持nand启动
下一篇:u-boot2010.03 配置编译目标分析
设计资源 培训 开发板 精华推荐
- LT8570EDD-1 700kHz、-15V 输出反相转换器的典型应用接受 5V 至 35V 输入
- LTC2946CMS-1 双电源、电荷和能量监视器的典型应用,使用单个光耦合器进行电流隔离,并在任一电源出现故障时使用阻塞二极管来保持数据
- 使用 Analog Devices 的 LTC1728HS5-5 的参考设计
- AD8625ARZ单极输出精密放大器典型应用电路
- STM32F030C8T6系统板
- S08PT60-EVK: 面向S08P MCU的评估套件
- LT3091EDE 并联线性稳压器的典型应用
- LT3066EDE-3.3 并联稳压器的典型应用电路,以实现更高的输出电流
- 具有低噪声旁路的 LTM8057MPY 12V 反激式转换器的典型应用电路
- ADR292ERZ 低噪声、微功率 4.096V 精密电压基准的典型应用电路,具有开尔文连接的优势
- CGD和Qorvo将共同革新电机控制解决方案
- 是德科技 FieldFox 手持式分析仪配合 VDI 扩频模块,实现毫米波分析功能
- 贸泽开售可精确测量CO2水平的 英飞凌PASCO2V15 XENSIV PAS CO2 5V传感器
- 玩法进阶,浩亭让您的PCB板端连接达到新高度!
- 长城汽车研发新篇章:固态电池技术引领未来
- 纳芯微提供全场景GaN驱动IC解决方案
- 解读华为固态电池新专利,2030 叫板宁德时代?
- 让纯电/插混车抓狂?中企推全球首款-40℃可放电增混电池,不怕冷
- 智驾域控知多少:中低端车型加速上车,行泊一体方案占主体
- Foresight推出六款先进立体传感器套件 彻底改变工业和汽车3D感知