基于Ok6410开发板u-boot的移植
我这里是参考江西理工大学09级-朱兆祺同学,以及以下博客的资料,经过几天的痛苦修改后最终移植成功的笔记,在这里感谢他们
参考博客:
http://zhengxianqing1986.blog.163.com/blog/static/180567261201222681150436/
http://blog.csdn.net/l_1054781936/article/details/6567741
http://www.linuxidc.com/Linux/2012-09/69918.htm
http://blog.csdn.net/wletv/article/details/7196206
http://blog.163.com/jlz_325/blog/static/191740009201262423442820
http://blog.sina.com.cn/s/blog_7a7ce1bb01013w3a.html
前提环境:Win7+VirsualBox+ok6410+u-boot-2010.03
一,下载u-boot-2010.03源码
ftp://ftp.denx.de/pub/u-boot
解压,我这里为了避免麻烦,更改了所有文件的权限
tar jxvf u-boot-2010.03.tar.bz2
sudo chmod -R 777 u-boot-2010.03/*
二,修改源码
为了方便修改,查找代码,你看到u-boot下包含了支持众多CPU和不同架构的代码,这里我根据Ok6410开发板的自身情况,将u-boot下代码进行精简:
1,进入u-boot-2010.03/board,把除samsung以外的文件夹删除
2,进入u-boot-2010.03/cpu,把除arm1176以外的文件夹删除
3,进入u-boot-2010.03/include,把asm-*(注意,仅仅是asm-开头的文件夹)中的,除了asm-arm和asm-generic以外的文件夹删除。
4,进入u-boot-2010.03/include/configs,只要留下smdk6400.h,其他的东西删除
5,进入u-boot-2010.03,把lib_*开头的文件夹(注意,仅仅是lib-开头的文件夹),除了lib_arm和lib_generic以外的文件夹删除
6,进入u-boot-2010.03/nand_spl/board,除了samsung以外的文件夹删除
进行这六步操作后:尝试一下编译,仅仅是尝试。
make smdk6400_config
make
7,进入u-boot-2010.03/board/samsung,除了smdk6400的文件夹都删除,建立一个新目录smdk6410,并将smdk6400里面的文件给smdk6410拷贝一份过去。
mkdir smdk6410
cp -R smdk6400/* smdk6410/
8,进入u-boot-2010.03/board/samsung/smdk6410文件夹将smdk6400.c更名为smdk6410.c
a)将smdk6410.c里面的6400全部改为6410。
b)将lowlevel_init.S,将里面的6400改为6410。
c)将Makfile,将里面的6400改为6410。
9,进入u-boot-2010.03\include\asm-arm , 把除了arch-s3c64xx 和proc-armv 之外的文件夹删除。进入arch-s3c64xx,建立s3c6410.h,
将s3c6400.h 内容复制到s3c6410.h。
cp s3c6400.h s3c6410.h
将s3c6410.h,将里面的6400改为6410。
10,进入到 include/configs/ 复制smdk6400.h,并将副本改为smdk6410.h。
cp smdk6400.h smdk6410.h
将s3c6410.h,将里面的6400改为6410。
11,进入u-boot-2010.03/nand_spl/board/samsung/,建立一个新目录smdk6410,并将smdk6400里面的文件给smdk6410拷贝一份过去。
mkdir smdk6410
cp -R smdk6400/* smdk6410/
a)将Makefile,里面的6400改为6410。
12,进入u-boot-2010.03/cpu/arm1176内所有文件以及u-boot-2010.03/cpu/arm1176/s3c64xx/内所有文件中的6400改为6410。
13,进入根目录下的Makefile,将CROSS_COMPILE ?=改成为CROSS_COMPILE ?=arm-linux-
然后搜索6400找到smdk6400的配置代码:
#########################################################################
## ARM1176 Systems
#########################################################################
smdk6400_noUSB_config \
smdk6400_config : unconfig
@mkdir -p $(obj)include $(obj)board/samsung/smdk6400
@mkdir -p $(obj)nand_spl/board/samsung/smdk6400
@echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
@if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then \
echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
$(MKCONFIG) $(@:_config=) arm arm1176 smdk6400 samsung s3c64xx; \
else \
echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
$(MKCONFIG) $(@:_noUSB_config=) arm arm1176 smdk6400 samsung s3c64xx; \
fi
@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
将上面蓝色标注的6400,改成6410
14,进入u-boot-2010.03/cpu/arm1176打开start.S,修改第一处代码:
//#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 /* 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 //#endif
蓝色部分进行了注释操作。
15,继续。还是u-boot-2010.03/cpu/arm1176/start.S文件,修改第二处代码:搜索找到 bl lowlevel_init这行代码:
/********************************** 如果是从nandflash 中启动,那么PC 的值一定在4K 之内。那么执 行完bic r1, pc, r0 之后,r1 为0。_TEXT_BASE 要么等于0x57e0 0000,
要么等于0xC7e0 0000.那么执行完bic r2, r2, r0 之后,r2 为0x00e0 0000,那么不相等,则不跳转,下面应该就是copy_from_nand。 如果是从ram 中启动,那么PC 的值为0x x7e0 0000。那么执行完 bic r1, pc, r0 之后,r1 为0x00e0 0000。_TEXT_BASE 要么等于0x57e0 0000,要么等于0xC7e0 0000.那么执行完bic r2, r2, r0 之后,r2 为 0x00e0 0000,那么相等,跳转到after_copy,也就是不需要copy。 承接上面分析,如果没有完成copy,则接下来就是copy_from_nand。 那么在beq after_copy 后面添加: #ifdef CONFIG_BOOT_NAND mov r0, #0x1000 bl copy_from_nand #endif 如果完成则会跳过这段代码,直接进入after_copy。 **********************************/ /* * Go setup Memory and board specific bits prior to relocation. */ bl lowlevel_init /* go setup pll,mux,memory */ ldr r0,=0xff000fff bic r1,pc,r0 ldr r2,_TEXT_BASE bic r2,r2,r0 cmp r1,r2 beq after_copy #ifdef CONFIG_BOOT_NAND mov r0,#0x1000 bl copy_from_nand #endif
什么意思暂时没弄清楚,不过参考的文章上说是:判断是从nandflash启动还是从ram启动。
16,继续start.S文件,修改第三处代码:在
#ifdef CONFIG_ENABLE_MMU
_mmu_table_base:
.word
mmu_table
#endif
这段代码之后加上如下代码:
/* * 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
17,继续start.S文件,修改第三处代码:
#ifdef CONFIG_ENABLE_MMU
enable_mmu:
/***添加下面这行***/
after_copy:
18,u-boot-2010.03/cpu/arm1176/下新建nand_cp.c文件,代码如下:
#include <common.h> #ifdef CONFIG_S3C64XX #include <asm/io.h> #include <linux/mtd/nand.h> #include <asm/arch/s3c6410.h> static int nandll_read_page (uchar *buf, ulong addr, int large_block) { int i; int page_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; /* Write Address */ NFADDR_REG = 0; if (large_block) NFADDR_REG = 0; NFADDR_REG = (addr) & 0xff; NFADDR_REG = (addr >> 8) & 0xff; NFADDR_REG = (addr >> 16) & 0xff; /* #define NFCMD_REG __REG(ELFIN_NAND_BASE + NFCMMD_OFFSET) #define ELFIN_NAND_BASE 0x70200000 #define NFCMMD_OFFSET 0x08 NFCMD_REG = ( *( (volatile u32 *) (0x70200008) ) ) NFCMMD 0x70200008 NAND Flash ?üá?éè???????÷0 #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 = ( *( (volatile u32 *) (0x70200028) ) ) NFSTAT 0x70200028 NAND Flash 2ù×÷×?ì??????÷ */ NF_TRANSRnB(); /* for compatibility(2460). u32 cannot be used. by scsuh */ for(i=0; i < page_size; i++) { *buf++ = NFDATA8_REG; } /* #define NAND_DISABLE_CE() (NFCONT_REG |= (1 << 1)) #define NFCONT_REG __REG(ELFIN_NAND_BASE + NFCONT_OFFSET) #define __REG(x) (*((volatile u32 *)(x))) #define ELFIN_NAND_BASE 0x70200000 #define NFCONT_OFFSET 0x04 */ NAND_DISABLE_CE(); return 0; } static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block) { uchar *buf = (uchar *)dst_addr; int i; uint page_shift = 9; if (large_block==1) page_shift = 11; /* Read pages */ if(large_block==2) page_shift = 12; if(large_block == 2) { /* Read pages */ for (i = 0; i < 4; i++, buf+=(1<<(page_shift-1))) { nandll_read_page(buf, i, large_block); } /* Read pages */ /* 0x3c000 = 11 1100 0000 0000 0000 */ for (i = 4; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) { nandll_read_page(buf, i, large_block); } } else { for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) { nandll_read_page(buf, i, large_block); } } return 0; } int copy_uboot_to_ram(void) { int large_block = 0; int i; vu_char id; /* #define NAND_ENABLE_CE() (NFCONT_REG &= ~(1 << 1)) #define NFCONT_REG __REG(ELFIN_NAND_BASE + NFCONT_OFFSET) #define __REG(x) (*((volatile u32 *)(x))) #define ELFIN_NAND_BASE 0x70200000 #define NFCONT_OFFSET 0x04 NFCONT_REG = ( *( (volatile u32 *) (0x70200004) ) ) NFCONT 0x70200004 ?á/D?NAND Flash ?????????÷ [0]1£oNAND Flash ?????÷ê1?ü */ NAND_ENABLE_CE(); /* #define NFCMD_REG __REG(ELFIN_NAND_BASE + NFCMMD_OFFSET) #define ELFIN_NAND_BASE 0x70200000 #define NFCMMD_OFFSET 0x08 NFCMD_REG = ( *( (volatile u32 *) (0x70200008) ) ) NFCMMD 0x70200008 NAND Flash ?üá?éè???????÷0 #define NAND_CMD_READID 0x90 */ NFCMD_REG = NAND_CMD_READID; /* #define NFADDR_REG __REG(ELFIN_NAND_BASE + NFADDR_OFFSET) #define ELFIN_NAND_BASE 0x70200000 #define NFADDR_OFFSET 0x0C NFADDR_REG = ( *( (volatile u32 *) (0x7020000C) ) ) NFADDR 0x7020000C NAND Flash μ??·éè???????÷ */ NFADDR_REG = 0x00; /* #define NFDATA8_REG __REGb(ELFIN_NAND_BASE + NFDATA_OFFSET) #define __REGb(x) (*(vu_char *)(x)) NFDATA8_REG = ( *( (vu_char *) (0x70200010) ) ) NFDATA 0x70200010 ?á/D?NAND Flash êy?Y?????÷ NAND Flash ?á/é?D?êy?Y?μó?óúI/O */ /* wait for a while */ for (i=0; i<200; i++); id = NFDATA8_REG; id = NFDATA8_REG; if (id > 0x80) large_block = 1; if(id == 0xd5) large_block = 2; /* read NAND Block. * 128KB ->240KB because of U-Boot size increase. by scsuh * So, read 0x3c000 bytes not 0x20000(128KB). */ /* #define CONFIG_SYS_PHY_UBOOT_BASE (CONFIG_SYS_SDRAM_BASE + 0x07e00000) #define CONFIG_SYS_SDRAM_BASE 0x50000000 CONFIG_SYS_PHY_UBOOT_BASE = 0x57e0 0000 0x3 c000 = 1M */ return nandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE, 0x3c000, large_block); } #endif
19,u-boot-2010.03/cpu/arm1176/Makefile文件:
COBJS =cpu.o nand_cp.o
如上加入nand_cp.o
20,u-boot-2010.03/include/configs/smdk6410.h文件:
加上这个定义:
#define virt_to_phys(x) virt_to_phy_smdk6410(x)
21:继续smdk6410.h文件,找到/* NAND configuration */
/* NAND configuration */ #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_SYS_NAND_BASE 0x70200010 #define CONFIG_SYS_S3C_NAND_HWECC
/* 加上下面三个定义 */ #define NAND_DISABLE_CE()(NFCONT_REG|=(1<<1)) #define NAND_ENABLE_CE()(NFCONT_REG&=~(1<<1)) #define NF_TRANSRnB() do{while(!(NFSTAT_REG&(1<<0)));}while(0)
22:继续smdk6410.h文件,我的ok6410,内存为256MB,则需要修改下面(NandFlash每个块的大小)
//#define PHYS_SDRAM_1_SIZE 0x08000000 /* 128MB in Bank #1 */ #define PHYS_SDRAM_1_SIZE 0x10000000 /* 256 MB in Bank #1 */
23:继续smdk6410.h文件,分配smdk6410的ID号:
//#define MACH_TYPE 1270 #define MACH_TYPE 1626
24,继续smdk6410.h文件,更改内存的分配大小:
//#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 1024 * 1024) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 512 * 1024) #define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes for initial data */
25,继续smdk6410.h文件,更改bootdelay时间:
//#define CONFIG_BOOTDELAY 3 #define CONFIG_BOOTDELAY 10
26,继续smdk6410.h文件,更改SDROM大小:
#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE /* memtest works on */ //#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x7e00000) /* 126MB in DRAM */ #define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x9e00000) /* 256MB in DRAM */
27,继续smdk6410.h文件,修改时间:
//#define CONFIG_SYS_HZ 1000 #define CONFIG_SYS_HZ 1562500
28,继续smdk6410.h文件,修改堆栈大小:
//#define CONFIG_STACKSIZE 0x40000 /* regular stack 256KB */ #define CONFIG_STACKSIZE 0x80000 /* regular stack 512KB */
29,继续smdk6410.h文件,修改:
//#define CONFIG_ENV_SIZE 0x4000 /* Total Size of Environment Sector */ #define CONFIG_ENV_SIZE 0x80000 /* Total Size of Environment Sector */
30,继续smdk6410.h文件,修改CONFIG_BOOTCOMMAND:
//#define CONFIG_BOOTCOMMAND "nand read 0xc0018000 0x60000 0x1c0000;" \ "bootm 0xc0018000" #define CONFIG_BOOTCOMMAND "nand read 0x50018000 0x100000 0x500000;" "bootm 0x50018000"
31,继续smdk6410.h文件,修改:
//#define CONFIG_ENV_OFFSET 0x0040000 #define CONFIG_ENV_OFFSET 0x0080000
32,继续smdk6410.h文件,修改NandFlash每一页的大小:
//#define CONFIG_SYS_NAND_PAGE_SIZE 2048 #define CONFIG_SYS_NAND_PAGE_SIZE 4096
33,继续smdk6410.h文件,修改NandFlash每一块的大小:
//#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024) #define CONFIG_SYS_NAND_BLOCK_SIZE (512 * 1024)
34,继续/smdk6410.h文件,修改校验位:
//#define CONFIG_SYS_NAND_PAGE_COUNT 64 #define CONFIG_SYS_NAND_PAGE_COUNT 128
35,修改u-boot-2010.03/board/samsung/smdk6410下u-boot-nand.lds,添加蓝色部分:
SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { 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) } .... }
36,修改u-boot-2010.03/cpu/arm1176下u-boot.lds,添加蓝色部分:
SECTIONS { . = 0x00000000; . = ALIGN(4); .text : { cpu/arm1176/start.o (.text) board/samsung/smdk6410/lowlevel_init.o (.text) cpu/arm1176/s3c64xx/cpu_init.o (.text) cpu/arm1176/nand_cp.o (.text) *(.text) } .... }
37,进入u-boot-2010.03/nand_spl/board/samsung/smdk6410/,修改Makefile文件:
在$(obj)cpu_init.S:
@rm -f $@
@ln
-s $(TOPDIR)/cpu/arm1176/s3c64xx/cpu_init.S $@
之后添加:
$(obj)nand_cp.c:
@rm -f $@
@ln -s $(TOPDIR)/cpu/arm1176/nand_cp.c $@
三,编译
编译之后,可以在开发板上运行成功,后面有补充,会及时更新。
make smdk6410_config
make