收藏 分销(赏)

uboot-2010-03移植到tq2440记录.doc

上传人:xrp****65 文档编号:7668230 上传时间:2025-01-11 格式:DOC 页数:59 大小:386KB 下载积分:10 金币
下载 相关 举报
uboot-2010-03移植到tq2440记录.doc_第1页
第1页 / 共59页
uboot-2010-03移植到tq2440记录.doc_第2页
第2页 / 共59页


点击查看更多>>
资源描述
uboot-2010-03移植tq2440记录 (by fengyong(vonbrave@)) 一.移植环境 (1) Vmware6.5---Ubuntu8.04 (2) 使用的开发板是TQ2440,配有Nor Flash大小为2MB; NandFlash 256MB。型号是三星的K9F2GU08A。页的大小是2KB. 我们的开发板NandFlash是64MB的,三星的型号是K9F1208。页的大小是512K。 (3) 交叉编译器的版本是EABI-4.3.3_EmbedSky_20100610.tar.bz2。 编译器的选择我们选择4.3.3 (4) 移植的U-Boot版本号为u-boot-2010-03。其官方下载地址 ftp://ftp.denx.de/pub/u-boot/。 在该版本中,仍然不支持s3c2440的处理器,因此必须以smdk2410为原型,在此基础上进行U-Boot的移植工作。 二.建立自己的开发板目录并测试编译环境 (1) 新建一个开发板的相应目录和文件(检测配置问题,看能不能编译出u-boot.bin) 为了不破坏原来的结构目录和代码,在board目录下建立一个目录embedsky,将samsung/smdk2410目录复制到embedsky目录下,并将文件夹改名smdk2440。 (2) 将smdk2440/smdk2410.c改名为smdk2440.c。 (3) 在include/configs目录下,将smdk2410.h直接复制为smdk2440.h (4) 修改顶层的Makefile文件,在其中添加如下的两行: smdk2440_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t smdk2440 embedsky s3c24x0 上面第二行一定要记得加TAB键,这是Makefile的规则 说明:arm :CPU的架构(ARCH) arm920t:CPU的类型 smdk2440 :对应在board目录下建立新的开发板项目的目录 embedsky:新开发板项目目录的上级目录,如直接在board下建立新的开发板项目的目录,则这里就为NULL s3c24x0:CPU型号 注意:编译选项格式的第二行要用Tab键开始,否则编译会出错,这是Makefile文件的规则.当Make出错的时候就应该查看是不是,这里写错! (5)修改board/embedsky/smdk2440目录下的Makefile文件,因为前面将smdk2410.c文件改名为smdk2440.c: COBJS := smdk2410.o flash.o 改为 COBJS := smdk2440.o flash.o (6) 修改根目录下Makefile 将__LIBS := $(subst $(obj),,$(LIBS)) $(subst $(obj),,$(LIBBOARD)) 改为__LIBS := $(subst $(obj),,$(LIBBOARD)) $(subst $(obj),,$(LIBS)) 或修改cpu/arm920t/u-boot.lds文件的 .text : { cpu/arm920t/start.o (.text) board/embedsky/smdk2440/lowlevel_init.o (.text) board/embedsky/smdk2440/nand_read.o (.text) *(.text) } (7)进入u-boot-2010.03目录,验证环境 先 #make distclean 清理所有以前的编译生成项 然后# make smdk2440_config Configuring for smdk2440 board... 生成一个适合smdk2440的config #make 到此,就已经建立了自己的目录,还有测试了编译的环境,如果都正确的话,就可以进行下面的移植工作了。 三、修改u-boot-2010.03中的文件,以便支持smdk2440 1.修改/cpu/arm920t/start.S文件,使U-BOOT可以从NandFlash启动 (1)删除掉LED的代码 #include <common.h> #include <config.h> start_code: /* * set the cpu to SVC32 mode */ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0xd3 msr cpsr,r0 @ bl coloured_LED_init @ bl red_LED_on (2) 修改寄存器的地址 # if defined(CONFIG_S3C2400) # define pWTCON 0x15300000 # define INTMSK 0x14400008 /* Interupt-Controller base addresses */ # define CLKDIVN 0x14800014 /* clock divisor register */ #else # define pWTCON 0x53000000 # define INTMSK 0x4A000008 /* Interupt-Controller base addresses */ # define INTSUBMSK 0x4A00001C # define CLKDIVN 0x4C000014 /* clock divisor register */ # endif 后增加: #define CLK_CTL_BASE 0x4C000000 #define MDIV_405 (0x7f << 12) #define PSDIV_405 (0x21) #define MDIV_200 (0xa1 <<12) #define PSDIV_200 (0x31) #endif (3)修改中断禁止 /* * 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 ldr r0, =INTSUBMSK str r1, [r0] # endif #if defined(CONFIG_S3C2440) ldr r1,=0x7fff //2440的位宽多点 ldr r0,=INTSUBMSK str r1,[r0] #endif (4) 修改时钟设置(2440的主频为405MHz。) #if defined(CONFIG_S3C2440) ldr r0,=CLKDIVN mov r1,#5 str r1,[r0] mrc p15,0,r1,c1,c0,0 orr r1,r1,#0xc0000000 mcr p15,0,r1,c1,c0,0 mov r1,#CLK_CTL_BASE mov r2,#MDIV_405 add r2,r2,#PSDIV_405 str r2,[r1,#0x04] #else /* FCLK:HCLK:PCLK = 1:2:4 */ /* default FCLK is 120 MHz ! */ ldr r0, =CLKDIVN mov r1, #3 str r1, [r0] mrc p15,0,r1,c1,c0,0 orr r1,r1,#0xc0000000 mcr p15,0,r1,c1,c0,0 mov r1,#CLK_CTL_BASE mov r2,#MDIV_200 addr r2,r2,#PSDIV_200 str r2,[r2,#0x04] #endif #endif /* CONFIG_S3C24x0 */ (5)将原来的从NorFlash启动,转换为从NandFlash 启动 #ifndef CONFIG_AT91RM9200 #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 {r3-r10} /* copy from source address [r0] */ stmia {r3-r10} /* copy to target address [r1] */ cmp r0, r2 /* until source end addreee [r2] */ ble copy_loop #endif /* CONFIG_SKIP_RELOCATE_UBOOT */ #endif 在上述代码后面增加下面的代码: //下面添加对 Nand Flash的支持,下面的这段代码主要实现的功能就把u-boot的程序可以复制的RAM中,该汇编代码调用了用C语言写的函数nand_read_ll() /****** NAND_BOOT ********/ #define LENGTH_UBOOT 0x60000 #define NAND_CTL_BASE 0x4E000000 #ifdef CONFIG_S3C2440 /* Offset */ #define oNFCONF 0x00 #define oNFCONT 0x04 #define oNFCMD 0x08 #define oNFSTAT 0x20 初始化nand控制寄存器 @ reset NAND mov r1, #NAND_CTL_BASE ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) ) str r2, [r1, #oNFCONF] ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control str r2, [r1, #oNFCONT] ldr r2, =(0x6) @ RnB Clear str r2, [r1, #oNFSTAT] mov r2, #0xff @ RESET command strb r2, [r1, #oNFCMD] mov r3, #0 @ wait 设置延迟 nand1: add r3, r3, #0x1 cmp r3, #0xa 延迟10次 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, #LENGTH_UBOOT 长度 0x60000 bl nand_read_ll 调用nand_read.c函数的处理 tst r0, #0x0 beq ok_nand_read 检查返回值,如果返回0,走bad_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 将nand的前4K数据放入r3 ldr r4, [r1], #4 将TEXT_BASE的前4K数据放入r4 teq r3, r4 比较 bne notmatch 跳转到死循环 subs r2, r2, #4 将r2-4进行比较 beq stack_setup bne go_next notmatch: loop3: b loop3 @ infinite loop #endif 在ldr pc, _start_armboot _start_armboot: .word start_armboot之后添加 #define STACK_BASE 0x33f00000 #define STACK_SIZE 0x10000 .align 2 DW_STACK_START:.word STACK_BASE+STACK_SIZE - 4 2 在board/embedsky/smdk2440/目录下加入NAND Flash读取函数(start.S中需要的nand_read_ll函数)文件nand_read.c, 新建nand_read.c,支持2K/512字节Page size 的Nand Flash读操作 #include <common.h> #include <linux/mtd/nand.h> #define __REGb(x) (*(volatile unsigned char *)(x)) #define __REGw(x) (*(volatile unsigned short *)(x)) #define __REGi(x) (*(volatile unsigned int *)(x)) #define NF_BASE 0x4e000000 #if defined(CONFIG_S3C2410) #define NFCONF __REGi(NF_BASE + 0x0) #define NFCMD __REGb(NF_BASE + 0x4) #define NFADDR __REGb(NF_BASE + 0x8) #define NFDATA __REGb(NF_BASE + 0xc) #define NFSTAT __REGb(NF_BASE + 0x10) #define NFSTAT_BUSY 1 #define nand_select() (NFCONF &= ~0x800) #define nand_deselect() (NFCONF |= 0x800) #define nand_clear_RnB() do {} while (0) #elif defined(CONFIG_S3C2440) #define NFCONF __REGi(NF_BASE + 0x0) #define NFCONT __REGi(NF_BASE + 0x4) #define NFCMD __REGb(NF_BASE + 0x8) #define NFADDR __REGb(NF_BASE + 0xc) #define NFDATA __REGb(NF_BASE + 0x10) #define NFDATA16 __REGw(NF_BASE + 0x10) #define NFSTAT __REGb(NF_BASE + 0x20) #define NFSTAT_BUSY 1 #define nand_select() (NFCONT &= ~(1 << 1)) 第一位清0 #define nand_deselect() (NFCONT |= (1 << 1)) #define nand_clear_RnB() (NFSTAT |= (1 << 2))清RNB 信号 #endif static inline void nand_wait(void) { int i; while (!(NFSTAT & NFSTAT_BUSY)) 等待RnB信号 for (i=0; i<10; i++); } struct boot_nand_t { int page_size; 页的大小 int block_size; int bad_block_offset; 坏块的偏移 }; static int is_bad_block(struct boot_nand_t * nand, unsigned long i) { unsigned char data; unsigned long page_num; nand_clear_RnB(); if (nand->page_size == 512) { NFCMD = NAND_CMD_READOOB; /* 0x50 */ NFADDR = nand->bad_block_offset & 0xf; NFADDR = (i >> 9) & 0xff; NFADDR = (i >> 17) & 0xff; NFADDR = (i >> 25) & 0xff; } else if (nand->page_size == 2048) { page_num = i >> 11; /* addr / 2048 */ 除2048从第三个周期对齐 NFCMD = NAND_CMD_READ0; NFADDR = nand->bad_block_offset & 0xff; NFADDR = (nand->bad_block_offset >> 8) & 0xff; NFADDR = page_num & 0xff; NFADDR = (page_num >> 8) & 0xff; NFADDR = (page_num >> 16) & 0xff; NFCMD = NAND_CMD_READSTART; 读命令 } else { return -1; } nand_wait(); data = (NFDATA & 0xff); if (data != 0xff) 判断是否是坏块 return 1; 返回1表示是坏块 return 0; } static int nand_read_page_ll(struct boot_nand_t * nand, unsigned char *buf, unsigned long addr) 读一个页的buf的数据 { unsigned short *ptr16 = (unsigned short *)buf; buf指针 unsigned int i, page_num; nand_clear_RnB(); NFCMD = NAND_CMD_READ0; 读命令 if (nand->page_size == 512) { /* Write Address */ NFADDR = addr & 0xff; NFADDR = (addr >> 9) & 0xff; NFADDR = (addr >> 17) & 0xff; NFADDR = (addr >> 25) & 0xff; } else if (nand->page_size == 2048) { page_num = addr >> 11; /* addr / 2048 */ /* Write Address */ NFADDR = 0; NFADDR = 0; NFADDR = page_num & 0xff; NFADDR = (page_num >> 8) & 0xff; NFADDR = (page_num >> 16) & 0xff; NFCMD = NAND_CMD_READSTART; } else { return -1; } nand_wait(); #if defined(CONFIG_S3C2410) for (i = 0; i < nand->page_size; i++) { *buf = (NFDATA & 0xff); buf++; } //2440 #elif defined(CONFIG_S3C2440) for (i = 0; i < (nand->page_size>>1); i++) { *ptr16 = NFDATA16; 16位总线读方式 ptr16++; } #endif return nand->page_size; 返回读的大小 } static unsigned short nand_read_id() 返回读的ID { unsigned short res = 0; NFCMD = NAND_CMD_READID; NFADDR = 0; res = NFDATA; 第一个字节 res = (res << 8) | NFDATA; 第二个字节 return res; 合并为16字节的 返回 } extern unsigned int dynpart_size[]; /* low level nand read function */ int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size) { int i, j; unsigned short nand_id; struct boot_nand_t nand; /* chip Enable */ nand_select(); nand_clear_RnB(); for (i = 0; i < 10; i++) ; nand_id = nand_read_id(); 16位的id if (0) { /* dirty little hack to detect if nand id is misread */ unsigned short * nid = (unsigned short *)0x31fffff0; *nid = nand_id; } if (nand_id == 0xec76) { /* Samsung K9F1208 */芯片寄存器设置数据发送指令的返回值,在芯片图里面 nand.page_size = 512; nand.block_size = 16 * 1024; nand.bad_block_offset = 5; } else if (nand_id == 0xecf1 || /* Samsung K9F1G08U0B */ nand_id == 0xecda || /* Samsung K9F2G08U0B */ nand_id == 0xecd3 ) { /* Samsung K9K8G08 */ nand.page_size = 2048; nand.block_size = 128 * 1024; nand.bad_block_offset = nand.page_size; } else { return -1; } if ((start_addr & (nand.block_size-1)) || (size & ((nand.block_size-1)))) return -1; /* invalid alignment */ 判断块对齐 for (i=start_addr; i < (start_addr + size);) { 开始读数据 #ifdef CONFIG_S3C2410_NAND_SKIP_BAD 检查是否是坏块 if (i & (nand.block_size-1)== 0) { if (is_bad_block(&nand, i) || is_bad_block(&nand, i + nand.page_size)) { /* Bad block */ i += nand.block_size; size += nand.block_size; continue; } } #endif j = nand_read_page_ll(&nand, buf, i); 读的最小单位按页读 i += j; buf += j; } /* chip Disable */ nand_deselect(); return 0; } 在添加完nand_read.c文件后,记得修改board/smdk2440/Makefile文件,将nand_read.c编译进u-boot。 COBJS := smdk2440.o nand_read.o flash.o 3 修改board/smdk2440/lowlevel_init.S文件 将:对bank的设置 #define B3_Tacs 0x0 /* 0clk */ #define B3_Tcos 0x3 /* 4clk */ #define B3_Tacc 0x7 /* 14clk */ #define B3_Tcoh 0x1 /* 1clk */ #define B3_Tah 0x0 /* 0clk */ #define B3_Tacp 0x3 /* 6clk */ #define B3_PMC 0x0 /* normal */ => 改为: #define B3_Tacs 0xc #define B3_Tcos 0x7 #define B3_Tacc 0xf #define B3_Tcoh 0x1 #define B3_Tah 0x0 #define B3_Tacp 0x0 #define B3_PMC 0x0 将: #define B5_Tacs 0x0 /* 0clk */ #define B5_Tcos 0x0 /* 0clk */ #define B5_Tacc 0x7 /* 14clk */ #define B5_Tcoh 0x0 /* 0clk */ #define B5_Tah 0x0 /* 0clk */ #define B5_Tacp 0x0 #define B5_PMC 0x0 /* normal */ #define B6_MT 0x3 /* SDRAM */ #define B6_Trcd 0x1 #define B6_SCAN 0x1 /* 9bit */ => 改为: #define B5_Tacs 0xc #define B5_Tcos 0x7 #define B5_Tacc 0xf #define B5_Tcoh 0x1 #define B5_Tah 0x0 #define B5_Tacp 0x0 #define B5_PMC 0x0 #define B6_MT 0x3 /* SDRAM */ #define B6_Trcd 0x2 /* 0x1*/ #define B6_SCAN 0x1 /* 9bit */ 将: /* REFRESH parameter */ #define REFEN 0x1 /* Refresh enable */ #define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */ #define Trp 0x0 /* 2clk */ #define Trc 0x3 /* 7clk */ #define Tchr 0x2 /* 3clk */ #define REFCNT 1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */ => 改为: /* REFRESH parameter */ #define REFEN 0x1 /* Refresh enable */ #define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */ #define Trc 0x3 /* 7clk */ #define Tchr 0x2 /* 3clk */ #if defined(CONFIG_S3C2440) #define Trp 0x2 /* 4clk */ #define REFCNT 1012 #else #define Trp 0x0 /* 2clk */ #define REFCNT 0x0459 #endif 4、修改/board/smdk2440/smdk2440.c 如下: #include <common.h> #include <netdev.h> #include <asm/arch/s3c24x0_cpu.h> #if defined(CONFIG_CMD_NAND) #include <linux/mtd/nand.h> #endif DECLARE_GLOBAL_DATA_PTR; #define FCLK_SPEED 1 #if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */ #define M_MDIV 0xC3 #define M_PDIV 0x4 #define M_SDIV 0x1 #elif FCLK_SPEED==1 /* Fout = 202.8MHz */ #if defined(CONFIG_S3C2410) /* Fout = 202.8MHz */ #define M_MDIV 0xA1 #define M_PDIV 0x3 #define M_SDIV 0x1 #endif #if defined(CONFIG_S3C2440) /* Fout = 405MHz */ #define M_MDIV 0x7f #define M_PDIV 0x2 #define M_SDIV 0x1 #endif #endif #define USB_CLOCK 1 #if USB_CLOCK==0 #define U_M_MDIV 0xA1 #define U_M_PDIV 0x3 #define U_M_SDIV 0x1 #elif USB_CLOCK==1 #if defined(CONFIG_S3C2410) #define U_M_MDIV 0x48 #define U_M_PDIV 0x3 #endif #if defined(CONFIG_S3C2440) #define U_M_MDIV 0x38 #define U_M_PDIV 0x2 #endif #define U_M_SDIV 0x2 2440的分频 #endif static inline void delay (unsigned long loops) { __asm__ volatile ("1:\n" "subs %0, %1, #1\n" "bne 1b":"=r" (loops):"0" (loops)); } /* * Miscellaneous platform dependent initialisations */ int board_init (void) { struct s3c24x0_clock_power * const clk_power = s3c24x0_get_base_clock_power(); struct
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 教育专区 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服