一个人跌跌撞撞终于来到了Uboot的移植,经过这几天对uboot源代码的分析,可以说得上是获益匪浅,也可以说收获不多吧,唉,知识实在是匮乏啊,Uboot代码中相当多的句子看不明白,很多都是猜测性的,或许我有生之年也写出那样的代码吧,不发牢骚了,开始今天的学习了。
好吧,既然是Uboot的移植,那么我们首先搞清楚为什么要对Uboot进行移植呢?两个原因,uboot虽然名为通用的bootloader,但是这个通用得打上引号。每个人手上开发板的架构以及外设资源是不一样的,所以,我们需要对Uboot上的一些驱动程序等加以修改,称为板级移植,此为原因之一;同样根据我们使用的CPU不同,那么我们uboot上一些寄存器等也需要进行修改,称为片级移植,此为原因之二。
恩,原因已经分稍稍分析了一下,那就开始uboot的移植吧!
一、 移植前的准备
1、 arm-linux-gcc4.3.2;2、u-boot-2010.03;3、OK6410开发板;redhat5.0;4、SD卡(用于烧写uboot,没网络啊!)。
二、 第一步:删繁取简
得到UBOOT后,将u-boot-2010.03.tar FZ到redhat中去,(为避免出现不必要的麻烦。个人建议一切 *** 作在linux下面进行,好像xp下面的空格和linux下面的空格是不一样的,装个tools一切麻烦解决)解压后得到u-boot-2010.03。
1、 进入u-boot-2010.03根目录下面的board文件夹,删除samsung之外的所有文件夹。
2、 进入u-boot-2010.03.根目录下面的cpu文件夹 ,删除arm1176之外的所有文件夹。
3、 进入u-boot-2010.03.根目录下面的include文件夹,删除以asm-开头的(一定要注意)除asm-arm、asm-generic之外的文件夹。
4、 回到根目录下面,删除以lib_开头的出去lib_arm、lib_generic之外的文件夹。
5、 进入 u-boot-2010.03\include\configs,删除 smdk6400.h以外的 其它的东西。
6、 修改u-boot-2010.03下面的makefile,将CROSS_COMPILE ?=修改为CROSS_COMPILE?=arm-linux-,增添交叉编译工具链。
7、 初步尝试 make smdk6400_config,然后执行make。编译完成后可以看到下面的信息。
注意在第一步的过程中可能会出现如下问题
这肯定的是你没有按步骤删除导致的,也就是删了一些不该删除得东西。初步编译后的uboot还是不能给我么开发板用的,下面就开始做一定修改。
还有一点就是需要进入u-boot-2010.03根目录才能执行make。。我之前经常犯这种错误。。。
三、 第二歩:对号入座
先make distclean吧。
1、 进入 u-boot-2010.03\board\samsung, 把除了 smdk6400 之外的文件夹删除, 同时建立一个文件夹 smdk6410, 把 smdk6400 文件夹里面的东西复制到smdk6410 文件夹中。进入 smdk6410 文件夹,将smdk6410文件夹下面所有文件中出现了6400的改为6410(保险起见)。
2、 进入 u-boot-2010.03\include\asm-arm ,把除了 arch-s3c64xx 、proc-armv 之外的文件夹删除。进入 arch-s3c64xx,建立 s3c6410.h,将 s3c6400.h 文件里面的程序原原本本复制到s3c6410.h。同时将arch-s3c64xx文件夹下面所有出现了smdk6400的改为smdk6410。
3、 进入u-boot-2010.03\nand_spl\board\samsung,建立smdk6410文件夹,同事把smdk6400中的内容FZ到smdk6410中去,接着把smdk6410中所有文件中出现了6400的地方改成6410。
4、 进入u-boot-2010.03/include/configs,复制smdk6400.h,并且将副本改为smdk6410.h,同时里面出现了的6400全部改为6410.
5、 进入u-boot-2010.03根目录的makefile文件,将里面的6400全部改为6410。
6、 执行make smdk6410_config、make。这时候会出现下面的编译结果,唯一的区别就是6400变成了6410。但是还是不能用,完事之后,就开始深度修改吧,幸好之前分析了一下uboot源码,不然,真特么是“黑匣子”移植呀!
四、 第三步:初步移植
1、 打开start.S,之前已经分析了启动代码,现在就不细述,第一个修改地方,增加了一条协处理命令。
2、 第二个代码修改的地方,用#if 0注释掉以下代码。
3、 在bl lowlevel_init后面插入如下代码,判断启动方式。
4、在 u-boot-2010.03\cpu\arm1176 下面新建一个 nand_cp.c 文件,c文件中的代码如下:
#include<common.h> #ifdef CONFIG_S3C64XX #include<asm/io.h> #include<linux/mtd/nand.h> #include<asm/arch/s3c6410.h> static intnandll_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) #defineELFIN_NAND_BASE 0x70200000 #define NFCMMD_OFFSET0x08 NFCMD_REG = ( *((volatile u32 *) (0x70200008) ) ) NFCMMD 0x70200008NAND Flash 命令设置寄存器 0 #defineNAND_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 0x70200028NAND Flash *** 作状态寄存器 */ NF_TRANSRnB(); /* forcompatibility(2460). u32 cannot be used. by scsuh */ for(i=0; i <page_size; i++) { *buf++ = NFDATA8_REG; } /* #defineNAND_DISABLE_CE() (NFCONT_REG |= (1 << 1)) #define NFCONT_REG __REG(ELFIN_NAND_BASE+ NFCONT_OFFSET) #define __REG(x)(*((volatile u32 *)(x))) #defineELFIN_NAND_BASE 0x70200000 #define NFCONT_OFFSET0x04 */ NAND_DISABLE_CE(); return 0; } static intnandll_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 11000000 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; } intcopy_uboot_to_ram(void) { int large_block = 0; int i; vu_char id; /* #defineNAND_ENABLE_CE() (NFCONT_REG &= ~(1 << 1)) #define NFCONT_REG __REG(ELFIN_NAND_BASE+ NFCONT_OFFSET) #define __REG(x)(*((volatile u32 *)(x))) #defineELFIN_NAND_BASE 0x70200000 #define NFCONT_OFFSET0x04 NFCONT_REG = ( *((volatile u32 *) (0x70200004) ) ) NFCONT 0x70200004 读/写 NAND Flash 控制寄存器 [0]1:NAND Flash 控制器使能 */ NAND_ENABLE_CE(); /* #define NFCMD_REG __REG(ELFIN_NAND_BASE+ NFCMMD_OFFSET) #defineELFIN_NAND_BASE 0x70200000 #define NFCMMD_OFFSET0x08 NFCMD_REG = ( *((volatile u32 *) (0x70200008) ) ) NFCMMD 0x70200008NAND Flash 命令设置寄存器 0 #defineNAND_CMD_READID 0x90 */ NFCMD_REG = NAND_CMD_READID; /* #define NFADDR_REG __REG(ELFIN_NAND_BASE+ NFADDR_OFFSET) #defineELFIN_NAND_BASE 0x70200000 #define NFADDR_OFFSET0x0C NFADDR_REG = ( *((volatile u32 *) (0x7020000C) ) ) NFADDR 0x7020000CNAND 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 读/写 NAND Flash 数据寄存器 NAND Flash 读/烧写数据值用于 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 ->240KBbecause of U-Boot size increase. by scsuh * So, read 0x3c000bytes not 0x20000(128KB). */ /* #defineCONFIG_SYS_PHY_UBOOT_BASE (CONFIG_SYS_SDRAM_BASE+ 0x07e00000) #defineCONFIG_SYS_SDRAM_BASE 0x50000000 CONFIG_SYS_PHY_UBOOT_BASE= 0x57e0 0000 0x3 c000 = 1M */ returnnandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE, 0x3c000, large_block); } #endif
5、在 u-boot-2010.03\cpu\arm1176 的 makefile 中增加创建目标
6、进入u-boot-2010.03\nand_spl\board\samsung \smdk6410,修改makefile中的内容,修改后如下。
接下来就是
7、在第二个#ifndef CONFIG_NAND_SPL后面增加如下代码,这里的顺序可不能搞错了,否则就会报错,如果编译过程中出现了未定义,那八成就是这里出问题了。
/******************************************************************************************************************************/ /* copy U-Boot toSDRAM and jump to ram (from NAND or OneNAND) * r0: size to becompared * Load 1'st 2blocksto RAM because U-boot's size is larger than 1block(128k) size */ .globl copy_from_nand copy_from_nand: mov r10, lr /* savereturn address */ mov r9, r0 /* get ready to callC functions */ ldr sp,_TEXT_PHY_BASE /* setup temp stack pointer */ sub sp, sp, #12 mov fp, #0 /* noprevious 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 /* allis OK */ mov pc, lr copy_failed: nop /* copy from nandfailed */ b copy_failed compare_failed: nop /* compare failed*/ b compare_failed /******************************************************************************************************************************/
到这里为止,start.s中的修改初步完成了。
7、 接下来就是对板子的配置进行修改了,这里面的一些东西和你板子的硬件资源密切相关,所以总得知道你板子的配置吧,这个就不多说了,打开u-boot-2010.03\include\configs \smdk6410.h文件查看吧,在新添加的nand_cp.c文件中含有3个宏没有定义,需要在这里定义,如下图示。
8、 最后还需要修改链接脚本那!
u-boot.lds和u-boot_nand.lds两个链接脚本中都需要做修改,路径分别为u-boot-2010.03 /CPU/ARM1176/uboot.lds, u-boot-2010.03/BOARD/SAMSUNG/SMDK6410/u-boot_nand.lds,修改内容如下:
10、还是一样编译吧,make了,由于没有网络,不好检测网卡移植是否成功,所以网卡移植就先不说了,最后贴上串口上打印的信息如下:
好了,一下又到了12点多了,不能再熬下去了,脸上长包啦~~~,这学期被这东西整的人不像人的,没办法啊,今天的总结就写到这里了,睡觉去。。。。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)