[置顶] 0K6410学习之初步Uboot移植

一个人跌跌撞撞终于来到了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,之前已经分析了启动代码,现在就不细述,第一个修改地方,增加了一条协处理命令。

[置顶] 0K6410学习之初步Uboot移植_第1张图片

 

2、  第二个代码修改的地方,用#if 0注释掉以下代码。

[置顶] 0K6410学习之初步Uboot移植_第2张图片

 

3、  在bl lowlevel_init后面插入如下代码,判断启动方式。

[置顶] 0K6410学习之初步Uboot移植_第3张图片

 

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中的内容,修改后如下。

 

接下来就是

[置顶] 0K6410学习之初步Uboot移植_第4张图片

 

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个宏没有定义,需要在这里定义,如下图示。

[置顶] 0K6410学习之初步Uboot移植_第5张图片

 

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,修改内容如下:

[置顶] 0K6410学习之初步Uboot移植_第6张图片

 

10、还是一样编译吧,make了,由于没有网络,不好检测网卡移植是否成功,所以网卡移植就先不说了,最后贴上串口上打印的信息如下:

[置顶] 0K6410学习之初步Uboot移植_第7张图片

 

好了,一下又到了12点多了,不能再熬下去了,脸上长包啦~~~,这学期被这东西整的人不像人的,没办法啊,今天的总结就写到这里了,睡觉去。。。。            

 

你可能感兴趣的:(Boot)