分类: LINUX
2008-04-29 15:10:16
首先,U-Boot1.2.0还没有支持s3c2440,这次移植是用2410的文件稍作修改而成的。其实2440和2410的区别主要是2440的主频更高,增加了摄像头接口和AC‘97音频接口;寄存器方面,除了新增模块的寄存器外,移植所要注意的是NAND FlASH控制器的寄存器有较大的变化、芯片的时钟频率控制寄存器(芯片PLL的寄存器)有一定的变化。其他寄存器基本是兼容的。
一、在U-Boot中建立自己的开发板类型,并测试编译。 0 在工作目录下解压U-Boot。 1 进入U-Boot目录,修改Makefile 2 在/board子目录中建立自己的开发板tekkaman2440目录 $cd board $mkdir tekkaman tekkaman/tekkaman2440 $cp -arf sbc2410x/* tekkaman/tekkaman2440/ $cd tekkaman/tekkaman2440 $mv sbc2410x.c tekkaman2440.c 还要记得修改自己的开发板tekkaman2440目录下的Makefile文件,不然编译时会出错: COBJS := tekkaman2440.o flash.o $vi Makefile $cd ../../.. $cp include/configs/sbc2410x.h include/configs/tekkaman2440.h
前加上“Tab”键) $make 我到这一步测试交叉编译成功!!
1 修改/cpu/arm920t/start.S (0)修改寄存器地址定义 /* turn off the watchdog */ #if defined(CONFIG_S3C2400) # define pWTCON 0x15300000 # define INTMSK 0x14400008 /* Interupt-Controller base addresses */ # define CLKDIVN 0x14800014 /* clock divisor register */ #elif defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440) # define pWTCON 0x53000000 # define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ # define INTSUBMSK 0x4A00001C # define CLKDIVN 0x4C000014 /* clock divisor register */ #endif (1)修改中断禁止部分 #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) ldr r0, =pWTCON mov r1, #0x0 str r1, [r0] /* * mask all IRQs by setting all bits in the INTMR - default */ mov r1, #0xffffffff ldr r0, =INTMSK str r1, [r0] # if defined(CONFIG_S3C2410) ldr r1, =0x7ff //根据2410芯片手册,INTSUBMSK有11位可用, //vivi也是0x7ff,不知为什么U-Boot一直没改过来。 ldr r0, =INTSUBMSK str r1, [r0] # endif # if defined(CONFIG_S3C2440) ldr r1, =0x7fff //根据2440芯片手册,INTSUBMSK有15位可用 ldr r0, =INTSUBMSK str r1, [r0] # endif
/* FCLK:HCLK:PCLK = 1:4:8 */ ldr r0, =CLKDIVN mov r1, #5 str r1, [r0] mrc p15, 0, r1, c1, c0, 0 /*read ctrl register tekkaman*/ orr r1, r1, #0xc0000000 /*Asynchronous tekkaman*/ mcr p15, 0, r1, c1, c0, 0 /*write ctrl register tekkaman*/ #if defined(CONFIG_S3C2440) /*now, CPU clock is 405.00 Mhz tekkaman*/ mov r1, #CLK_CTL_BASE /* tekkaman*/ mov r2, #MDIV_405 /* mpll_405mhz tekkaman*/ add r2, r2, #PSDIV_405 /* mpll_405mhz tekkaman*/ str r2, [r1, #0x04] /* MPLLCON tekkaman */ #endif #if defined(CONFIG_S3C2410) /*now, CPU clock is 202.8 Mhz tekkaman*/ mov r1, #CLK_CTL_BASE /* tekkaman*/ mov r2, #MDIV_200 /* mpll_200mhz tekkaman*/ add r2, r2, #PSDIV_200 /* mpll_200mhz tekkaman*/ str r2, [r1, #0x04] /* MPLLCON tekkaman */ #endif #endif /* CONFIG_S3C2400 || CONFIG_S3C2410|| CONFIG_S3C2440 */ 红色部分是我添加的,利用vivi的代码,将其设为405.00MHz 并在前面加上: #elif defined(CONFIG_S3C2410) # define pWTCON 0x53000000 # define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ # define INTSUBMSK 0x4A00001C # define CLKDIVN 0x4C000014 /* clock divisor register */ #define CLK_CTL_BASE 0x4C000000 /* tekkaman */ #if defined(CONFIG_S3C2440) #define MDIV_405 0x7f << 12 /* tekkaman */ #define PSDIV_405 0x21 /* tekkaman */ #endif #if defined(CONFIG_S3C2410) #define MDIV_200 0xa1 << 12 /* tekkaman */ #define PSDIV_200 0x31 /* tekkaman */ #endif #endif (3)将从Flash启动改成从NAND Flash启动。(特别注意:这和2410的程序有不同,不可混用!!!是拷贝vivi的代码。) 将以下U-Boot的重定向语句段: #ifndef CONFIG_SKIP_RELOCATE_UBOOT relocate: /* relocate U-Boot to RAM */ adr r0, _start /* r0 <- current position of code */ ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ cmp r0, r1 /* don't reloc during debug */ beq stack_setup ldr r2, _armboot_start ldr r3, _bss_start sub r2, r3, r2 /* r2 <- size of armboot */ add r2, r0, r2 /* r2 <- source end address */ copy_loop: ldmia r0!, {r3-r10} /* copy from source address [r0] */ stmia r1!, {r3-r10} /* copy to target address [r1] */ cmp r0, r2 /* until source end addreee [r2] */ ble copy_loop #endif /* CONFIG_SKIP_RELOCATE_UBOOT */ 替换成: #ifdef CONFIG_S3C2440_NAND_BOOT @tekkaman@@@@@@@@@@@@@@@@SSSSSSSSSSSSS @ reset NAND mov r1, #NAND_CTL_BASE ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) ) str r2, [r1, #oNFCONF] ldr r2, [r1, #oNFCONF] ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control str r2, [r1, #oNFCONT] ldr r2, [r1, #oNFCONT] ldr r2, =(0x6) @ RnB Clear str r2, [r1, #oNFSTAT] ldr r2, [r1, #oNFSTAT] mov r2, #0xff @ RESET command strb r2, [r1, #oNFCMD] mov r3, #0 @ wait nand1: add r3, r3, #0x1 cmp r3, #0xa blt nand1 nand2: ldr r2, [r1, #oNFSTAT] @ wait ready tst r2, #0x4 beq nand2 ldr r2, [r1, #oNFCONT] orr r2, r2, #0x2 @ Flash Memory Chip Disable str r2, [r1, #oNFCONT] @ get read to call C functions (for nand_read()) ldr sp, DW_STACK_START @ setup stack pointer mov fp, #0 @ no previous frame, so fp=0 @ copy U-Boot to RAM ldr r0, =TEXT_BASE mov r1, #0x0 mov r2, #0x20000 bl nand_read_ll tst r0, #0x0 beq ok_nand_read bad_nand_read: loop2: b loop2 @ infinite loop ok_nand_read: @ verify mov r0, #0 ldr r1, =TEXT_BASE mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes go_next: ldr r3, [r0], #4 ldr r4, [r1], #4 teq r3, r4 bne notmatch subs r2, r2, #4 beq stack_setup bne go_next notmatch: loop3: b loop3 @ infinite loop #endif @ CONFIG_S3C2440_NAND_BOOT @tekkaman@@@@@@@@@@@@@@@@@@EEEEEEEEE 在“ldr pc, _start_armboot”之前加入: @ LED1 on u-boot stage 1 is ok! mov r1, #GPIO_CTL_BASE add r1, r1, #oGPIO_B ldr r2,=0x155aa str r2, [r1, #oGPIO_CON] mov r2, #0xff str r2, [r1, #oGPIO_UP] mov r2, #0x1c0 str r2, [r1, #oGPIO_DAT] 修改目的:如果看到只有LED1亮了,说明U-Boot的第一阶段已完成! 在 “ _start_armboot: .word start_armboot ” 后加入: .align 2 DW_STACK_START: .word STACK_BASE+STACK_SIZE-4 2 在board/tekkaman/tekkaman2440加入NAND Flash读函数文件,拷贝vivi中的nand_read.c文件到此文件夹即可: 注意:s3c2410与s3c2440的Nand Flash控制器寄存器不同,不能混用!! 3 修改board/tekkaman/tekkaman2440/Makefile文件 4 修改include/configs/tekkaman2440.h文件,添加如下内容(注意:s3c2410与s3c2440的Nand Flash控制器寄存器不同,不能混用!!): /* GPIO */ 5 修改board/tekkaman/tekkaman2440/lowlevel_init.S文件 6 修改/board/tekkaman/tekkaman2440/tekkaman2440.c #elif FCLK_SPEED==1 /* Fout = 405MHz */ ...... /* set up the I/O ports */ ...... /* adress of boot parameters */ gd->bd->bi_boot_params = 0x30000100; icache_enable(); dcache_enable(); gpio->GPBDAT = 0x180; //tekkamanninja //int board_init (void)设置完成后,LED1和LED2会亮起! return 0; } 7 为了实现NAND Flash的读写,再次修改/include/configs/tekkaman2440.h #define CFG_PROMPT "[Tekkaman2440]#" #define ADDR_PAGE 3 #define WRITE_NAND_ADDRESS(d, adr) {rNFADDR = d;} #define WRITE_NAND(d, adr) {rNFDATA = d;} #define READ_NAND(adr) (rNFDATA) #define NAND_WAIT_READY(nand) {while(!(rNFSTAT&(1<<0)));} #define NAND_DISABLE_CE(nand) {rNFCONT |= (1<<1);} #define NAND_ENABLE_CE(nand) {rNFCONT &= ~(1<<1);} #define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d) #define rNFCONF (*(volatile unsigned int *)0x4e000000) #define rNFCONT (*(volatile unsigned int *)0x4e000004) #define rNFCMD (*(volatile unsigned char *)0x4e000008) #define rNFADDR (*(volatile unsigned char *)0x4e00000c) #define rNFDATA (*(volatile unsigned char *)0x4e000010) #define rNFSTAT (*(volatile unsigned int *)0x4e000020) #define rNFECC (*(volatile unsigned int *)0x4e00002c) #endif /* __CONFIG_H */
|