基于OK6410的u-boot2010.03…

来源:互联网 发布:淘宝9块9包邮 编辑:程序博客网 时间:2024/05/21 19:55
原文地址:基于OK6410的u-boot2010.03移植到此结束作者:朱兆祺

ftp://ftp.denx.de/pub/u-boot/中下载u-boot-2010.03,其实我之前用的是u-boot-2010.06,坑爹很久才发现,u-boot-2010.06是一个分界点,u-boot-2010.03是最后一个版本类似u-boot1.1.6.u-boot-2010.06是一个新起点版本。我承认我是一个菜鸟,一个刚买OK6410不久的菜鸟,一个刚刚接触linux的菜鸟,既然是菜鸟,我就要从模仿开始,于是,我拖出u-boot-1.1.6开始研究,开始移植u-boot-2010.03

 

下载好u-boot-2010.03之后,解压缩,这里的一切我都是在XP系统下完成的。

1.进入u-boot-2010.03/board,把除samsung以外的文件夹删除。

2.进入u-boot-2010.03/cpu,把除arm1176以外的文件夹删除。

3.进入u-boot-2010.03include,把asm-*(注意,仅仅是asm-开头的文件夹)中的,除了asm-armasm-generic以外的文件夹删除。

4.进入u-boot-2010.03includeconfigs,只要留下smdk6400.h,其他的东西删除。

5.u-boot-2010.03,把lib_*开头的文件夹,除了lib_armlib_generic以外的文件夹删除。

6.

现在把u-boot-2010.03放入到ubuntu中,先配置:make smdk6400_config,接着make。编译完成之后应该生成了u-boot.bin,其实现在什么都没有完成,我只是尝试了下原版u-boot2010.03能不能行。编译完成之后应该是这个样子:

[转载]基于OK6410的u-boot2010.03移植到此结束

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

好戏还在后头。

我们先来看下删减之后的u-boot-2010.03的构架:

这里交大家一个指令:tree,怎么用呢?我也忘了,没关系,man tree。它会告诉你一切,我们找到我们需要的那条:

[转载]基于OK6410的u-boot2010.03移植到此结束

呵呵,那就是使用tree -L 深度

我们来尝试下:

[转载]基于OK6410的u-boot2010.03移植到此结束

 

其中白色的是文件,蓝色的是目录,绿色的是可执行文件。

 

现在进入u-boot-2010.03boardsamsung, 把除了smdk6400之外的文件夹删除,同时建立一个文件夹smdk6410,把smdk6400文件夹里面的东西复制到smdk6410文件夹中。进入smdk6410文件夹,把smdk6400.c改成smdk6410.c

进入u-boot-2010.03includeasm-arm,把除了arch-s3c64xxproc-armv之外的文件夹删除。进入arch-s3c64xx,建立s3c6410.h,将s3c6400.h文件里面的程序原原本本复制到s3c6410.h

进入根目录下的Makefile,这个我就不加详细分析,我想我也可能分析不过来。找到:

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

这个是smdk6400的配置,现在将它改成smdk6410的配置:

smdk6410_noUSB_config

smdk6410_config:unconfig

@mkdir -p $(obj)include $(obj)board/samsung/smdk6410

@mkdir -p $(obj)nand_spl/board/samsung/smdk6410

@echo "#define CONFIG_NAND_U_BOOT" $(obj)include/config.h

@if -z "$(findstring smdk6410_noUSB_config,$@)" ]; then

echo "RAM_TEXT 0x57e00000" >> $(obj)board/samsung/smdk6410/config.tmp;

$(MKCONFIG) $(@:_config=) arm arm1176 smdk6410 samsung s3c64xx;

else

echo "RAM_TEXT 0xc7e00000" >> $(obj)board/samsung/smdk6410/config.tmp;

$(MKCONFIG) $(@:_noUSB_config=) arm arm1176 smdk6410 samsung s3c64xx;

fi

@echo "CONFIG_NAND_U_BOOT y" >> $(obj)include/config.mk

进入u-boot-2010.03boardsamsungsmdk6410,打开smdk6410.c,把#include <asm/arch/s3c6400.h>改成#include <asm/arch/s3c6410.h>

 

u-boot-2010.03中所有的 6400 改成 6410 

 

 

这是第二版修改,我把下面这段代码做了适当修改:

#ifndef CONFIG_NAND_SPL

 

movr0, #0

mcrp15, 0, r0, c7, c7, 0

mcrp15, 0, r0, c8, c7, 0

 

 

mrcp15, 0, r0, c1, c0, 0

bicr0, r0, #0x00002300clear bits 13, 9:8 (--V- --RS)

bicr0, r0, #0x00000087clear bits 7, 2:0 (B--- -CAM)

orrr0, r0, #0x00000002set bit (A) Align

orrr0, r0, #0x00001000set bit 12 (I) I-Cache

mcrp15, 0, r0, c1, c0, 0

 

#endif

 

start.S中,bl lowlevel_init之前的代码都无需更改,直到这句话之后需要添加下面代码:

 

 ldr r0, =0xff000fff

 bic r1, pc, r0  

 ldr r2, _TEXT_BASE  

 bic r2, r2, r0  

 cmp     r1, r2        

 beq     after_copy  

这段代码是判断到底是从nandflash中启动还是从ram中启动。

1.如果是从nandflash中启动,那么PC的值一定在4K之内。那么执行完bic r1, pc, r0 之后,r10_TEXT_BASE要么等于0x57e0 0000,要么等于0xC7e0 0000.那么执行完 bic r2, r2, r0 之后,r20x00e0 0000,那么不相等,则不跳转,下面应该就是copy_from_nand

2.如果是从ram中启动,那么PC的值为0x x7e0 0000。那么执行完bic r1, pc, r0 之后,r10x00e0 0000_TEXT_BASE要么等于0x57e0 0000,要么等于0xC7e0 0000.那么执行完 bic r2, r2, r0 之后,r20x00e0 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

OK,在u-boot-2010.03cpuarm1176下面新建一个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;

 

 

 if (large_block==1)

   page_size 2048;

 

 

 if (large_block==2)

  page_size 4096;

 

        NAND_ENABLE_CE();

 

        NFCMD_REG NAND_CMD_READ0;

 

        

        NFADDR_REG 0;

 

 if (large_block)

        NFADDR_REG 0;

 

 

 NFADDR_REG (addr) 0xff;

 NFADDR_REG (addr >> 8) 0xff;

 NFADDR_REG (addr >> 16) 0xff;

 

 

 

 if (large_block)

  NFCMD_REG NAND_CMD_READSTART;

 

 

        NF_TRANSRnB();

 

 

 

 for(i=0; page_size; i++) 

{

                *buf++ NFDATA8_REG;

        }

 

 

 

        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;

 

 

        

 if(large_block==2)

  page_shift 12;

 

 if(large_block == 2)

 {

  

  for (i 0; 4; i++, buf+=(1<<(page_shift-1))) 

{

         nandll_read_page(buf, i, large_block);

  }

 

 

  

 

  for (i 4; (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) 

{

         nandll_read_page(buf, i, large_block);

  }

 }

 

 

 else

 {

  for (i 0; (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;

 

 

 

       NAND_ENABLE_CE();

 

 

 

       NFCMD_REG NAND_CMD_READID;

 

 

 

       NFADDR_REG  0x00;

 

 

 

 

 

 

        for (i=0; i<200; i++);

 id NFDATA8_REG;

 id NFDATA8_REG;

 

 

 if (id 0x80)

  large_block 1;

 if(id == 0xd5)

  large_block 2;

 

 

 

 

 

 

 return nandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE, 0x3c000, large_block);

 

  

#endif  

 

u-boot-2010.03cpuarm1176makefile中:

COBJScpu.o nand_cp.o

其中nand_cp.o是新加。

 

然后返回start.S,在:

#ifdef CONFIG_ENABLE_MMU

enable_mmu:

这段代码之前添加上:

after_copy:

 

 

接着在:

#ifdef CONFIG_ENABLE_MMU

 .globl theLastJump

theLastJump:

 

这段代码之前添加下面代码:

 

.globl copy_from_nand

copy_from_nand:

 

 mov r10, lr  

 

 mov r9, r0

 

 ldr sp, _TEXT_PHY_BASE 

 sub sp, sp, #12

 mov 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 

 subs r9, r9, #4

 bne 1b

 

 

4: mov lr, r10  

 mov pc, lr

 

 

copy_failed:

 nop   

 copy_failed

 

 

compare_failed:

 nop   

 compare_failed

 

 

 

接着进入u-boot-2010.03includeconfigs下面的smdk6410.h文件,

 

1.新添加下面代码,由于是宏定义,只要在smdk6410.h中,任何一个“可以”放置的地方放置都行,注意,是“可以”放置,自己体会什么意思:

#define virt_to_phys(x)   virt_to_phy_smdk6410(x)

 

2.这句代码:

#define CONFIG_SYS_PROMPT"SMDK6400 "

其中"SMDK6400 "是由你自己进行修改,我改成了:"zhuzhaoqi#"这个随个人嘛。

 

3.注意下面这条宏定义:

#define PHYS_SDRAM_1_SIZE0x08000000

这里是适应于内存为128MBOK6410,但是我购买的OK6410A内存为256MB,所以要对这句话进行修改:

#define PHYS_SDRAM_1_SIZE0x1000 0000

为什么?

我们来分析一下:

我们知道2^10=1KB 2^20=1MB,那么0x1000 0000 1*2^(4*7) =2^28 (2^8)*(2^20) ,即为(2^8)MB,也就是256MB

 

4.为了对号入座,我们就把nand_cp.c中用到的宏定义添加在

 

下面:

#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)

上面3个宏定义在前面的nand_cp.c中我已经分析了,这里就不多费口舌。

 

这里也是第二版修改,额外加上了如下改动:

1.第一版没有更改6410ID号!

 

//#define MACH_TYPE1270 

#define MACH_TYPE1626 

smdk6400ID注释掉,添加smdk6410ID

2.更改内存的分配大小

 

//#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_SIZE128

3.修改bootdelay时间

#define CONFIG_BOOTDELAY10

4.修改SDROM大小

//#define CONFIG_SYS_MEMTEST_END(CONFIG_SYS_SDRAM_BASE 0x7e00000) 

#define CONFIG_SYS_MEMTEST_END(CONFIG_SYS_SDRAM_BASE 0x9e00000) 

5.时间的修改

 

 

//#define CONFIG_SYS_HZ1000// at PCLK 50MHz

#define CONFIG_SYS_HZ1562500

6.堆栈大小的修改

//#define CONFIG_STACKSIZE0x40000

#define CONFIG_STACKSIZE0x80000

7.Nand flash每个块的大小修改

//#define PHYS_SDRAM_1_SIZE0x08000000

#define PHYS_SDRAM_1_SIZE0x10000000

8.Total Size of Environment Sector 的修改

//#define CONFIG_ENV_SIZE0x4000

#define CONFIG_ENV_SIZE0x80000

9.CONFIG_BOOTCOMMAND的修改

#define CONFIG_BOOTCOMMAND"nand read 0x50018000 0x60000 0x1c0000;" 

"bootm 0x50018000"

修改为:

#define CONFIG_BOOTCOMMAND"nand read 0x50018000 0x100000 0x500000;" 

"bootm 0x50018000"

10.CONFIG_ENV_OFFSET的修改:

#define CONFIG_ENV_OFFSET0x0080000

11.Nand flash每一页大小的修改:

//#define CONFIG_SYS_NAND_PAGE_SIZE2048

#define CONFIG_SYS_NAND_PAGE_SIZE4096

12.Nand flash每一块大小的修改:

 

//#define CONFIG_SYS_NAND_BLOCK_SIZE(128 1024)

#define CONFIG_SYS_NAND_BLOCK_SIZE(512 1024)

13.校验位

 

//#define CONFIG_SYS_NAND_PAGE_COUNT64

#define CONFIG_SYS_NAND_PAGE_COUNT128

 

在这里还需要一步完成,这里也是第二版本添加:

1.u-boot-nand.lds中添加:

{

  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)

}

2.u-boot.lds中添加:

{

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)

}

3.删除nand_splboard除去samsung文件夹以外的文件夹,进入samsung,复制一个smdk6410.

进入makefile

COBJSnand_boot.o nand_ecc.o s3c64xx.o nand_cp.o

在下面代码

from SoC directory

$(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 $@

 

 

在编译之前还有一个地方需要修改:

lowlevel_init.S修改LED灯的测试代码,这个参考6410手册进行修改。

 

配置,编译,生成u-boot.bin

[转载]基于OK6410的u-boot2010.03移植到此结束

放进去OK6410开发版,可以看到下面效果:

[转载]基于OK6410的u-boot2010.03移植到此结束

于是乎,OKu-boot-2010.03的移植就完成了第一步。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

接下来就是网卡了。

U-boot-2010.03默认的网卡支持是CS8900,但是OK6410使用的是DM9000.

smdk6410.h中将CS8900的宏定义注释掉:

//#define CONFIG_NET_MULTI

//#define CONFIG_CS8900   

//#define CONFIG_CS8900_BASE   0x18800300

//#define CONFIG_CS8900_BUS16  

 

然后添加DM9000网卡的宏定义:

 

 

#define CONFIG_NET_MULTI 1

 

#define CONFIG_DM9000_NO_SROM   1

#define CONFIG_dm9000

 

 

#define CONFIG_DRIVER_DM9000 1

#define CONFIG_DM9000_BASE   0x18800300

#define DM9000_IO CONFIG_DM9000_BASE

#define DM9000_DATA (CONFIG_DM9000_BASE+4)

#define CONFIG_DM9000_USE_16BIT

 

#define CONFIG_ETHADDR  00:40:5c:26:0a:5b

#define CONFIG_NETMASK          255.255.255.0

#define CONFIG_IPADDR  172.16.114.20

#define CONFIG_SERVERIP      172.16.114.10

#define CONFIG_GATEWAYIP     172.16.114.1

//#define CONFIG_DM9000_DEBUG

 

 

 

上面的IP和网关、子网掩码等根据自己的具体情况进行修改。

 

接着打开u-boot-2010.03/net/eth.c,并且进入到函数int eth_initialize(bd_t *bis)中,在

#if defined(CONFIG_DB64460) || defined(CONFIG_P3Mx)

mv6446x_eth_initialize(bis);

#endif

后面添加下面代码:

 

 

#if defined(CONFIG_DRIVER_DM9000)

      dm9000_initialize(bis);

#endif

 

 

 

 

同样在u-boot-2010.03/net/net.c

1.//# define ARP_TIMEOUT5000UL

修改成:

define ARP_TIMEOUT5

 

 

2.if ((t NetArpWaitTimerStart) ARP_TIMEOUT)

修改成:

if ((t NetArpWaitTimerStart) ARP_TIMEOUT*CONFIG_SYS_HZ)

 

3.//NetSetTimeout (10000UL, PingTimeout);

修改成:

NetSetTimeout (10*CONFIG_SYS_HZ, PingTimeout);

 

 

 

 

接着进入u-boot-2010.03/net/tftp.c,找到void

TftpStart (void)函数,用#if   #endif注释掉下面的程序:

#if 0

 

if ((ep getenv("tftpblocksize")) != NULL)

TftpBlkSizeOption simple_strtol(ep, NULL, 10);

 

if ((ep getenv("tftptimeout")) != NULL)

TftpTimeoutMSecs simple_strtol(ep, NULL, 10);

 

if (TftpTimeoutMSecs 1000) {

printf("TFTP timeout (%ld ms) too low, "

"set minimum 1000 msn",

TftpTimeoutMSecs);

TftpTimeoutMSecs 1000;

}

 

debug("TFTP blocksize %i, timeout %ld msn",

TftpBlkSizeOption, TftpTimeoutMSecs);

 

#endif

 

网卡驱动终究完成。编译:

[转载]基于OK6410的u-boot2010.03移植到此结束

放进去OK6410效果:

[转载]基于OK6410的u-boot2010.03移植到此结束

 

上图即为移植好网卡后的效果图。

 

这是我移植u-boot的第一个版本,日后会渐渐在这份资料上进行完善。下一次更新在半月之后。

 

 

进入dm9000x.c,找到static int dm9000_rx(struct eth_device *netdev)函数,把for(;;){}修改成do{}while.

 

do之前添加:

 

 

DM9000_ior(DM9000_MRRH);

DM9000_ior(DM9000_MRRL);

 

 

 

static void dm9000_halt(struct eth_device *netdev)

{

DM9000_DBG("%sn", __func__);

 

 

//phy_write(0, 0x8000);

//DM9000_iow(DM9000_GPR, 0x01);

//DM9000_iow(DM9000_IMR, 0x80);

//DM9000_iow(DM9000_RCR, 0x00);

}

 

再把上面的//后面的程序屏蔽

这里是网络ping通之后的效果:

[转载]基于OK6410的u-boot2010.03移植到此结束

 

Nand flash读写:

nand flash的控制都是这个套路,因为这就是硬件协议,先使能芯片->发送命令->发送地址序列->读或写数据寄存器->判断准备就绪状态->禁止芯片,这是对nand flash操作的大体过程,根据发送命令的不同还有些区别。

 

nand_cp.c中有这么一段代码很有意思,现在拿出来分析一下:

 

  for (i 0; 4; i++, buf+=(1<<(page_shift-1))) 

{

         nandll_read_page(buf, i, large_block);

  }

 

 

  

 

  for (i 4; (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) 

{

         nandll_read_page(buf, i, large_block);

 

  }

 

 

 

首先我们来看下buf是什么?

uchar *buf (uchar *)dst_addr;

 

dst_addr又是什么?

static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)  

 

我们再看一下下面这条程序:

return nandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE, 0x3c000, large_block);

 

也就是说buf的地址就是CONFIG_SYS_PHY_UBOOT_BASE。前面我们就分析过CONFIG_SYS_PHY_UBOOT_BASE 0x57e0 0000.

好了,我们现在开始分析第个for语句:

for (i 0; 4; i++, buf+=(1<<(page_shift-1))) 

{

         nandll_read_page(buf, i, large_block);

  }

 

,buf buf 2^(12-1) buf 2K;

注意,每次是2K的操作,单独一句不奇怪,Ok,我们接着看第二个for语句。

for (i 4; (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) 

{

         nandll_read_page(buf, i, large_block);

但是执行四次之后每次是4K的操作,为什么?之前刚好执行了8K!!!

关键的8K代码不是在K9GAG08U0D型号(每页4K)的前两页存放,也不是在K9GAG08U0E型号(每页8K)的第一页存放,而是在K9GAG08U0E型号或者K9GAG08U0D型号的前四页中存放的,前四页分为每页2K,总共8K,这是由s3c6410芯片本身所规定的。这8K字节外后面的数据就是按实际的页数存放了,K9GAG08U0D型号每页存放4K字节,K9GAG08U0E型号每页存放8K字节。 

 

再者,进入nand.ids,作如下修改:

 

 

//{"NAND 2GiB 3,3V 8-bit",0xD5, 0, 2048, 0, LP_OPTIONS},

{"NAND 2GiB 3,3V 8-bit",0xD5, 4096, 2048, 512*1024, LP_OPTIONS},

 

 

 

我把生成的u-boot烧写到OK6410当中运行,在u-boot上:

Set bootdelay 20 

Sav 

按理说我复位启动之后应该是20S了,但是,这是我在启动瞬间接下来的图:

[转载]基于OK6410的u-boot2010.03移植到此结束

说明我们的环境变量没有储存在nand flash,why!!!

没办法,找吧!

 

1.将s3c6410.h中的:

#define DMC1_MEM_CFG0x00010012

#define DMC1_CHIP0_CFG0x150F8

修改成如下:

#define DMC1_MEM_CFG0x0001001a

#define DMC1_CHIP0_CFG0x150F0

2.include/linux/mtd/mtd.h

将结构体struct erase_info{}中的

//uint64_t addr;

//uint64_t len;

//uint64_t fail_addr;

改成:

u_int32_t addr;

u_int32_t len;

u_int32_t fail_addr;

 

将结构体struct mtd_erase_region_info{}中的

//uint64_t offset;

改成:

 u_int32_t  offset;

3.int env_init(void)

if (!crc1_ok && !crc2_ok) {

gd->env_addr  0;

gd->env_valid 0;

 

return 0;

else if (crc1_ok && !crc2_ok) {

gd->env_valid 1;

}

改成:

if (!crc1_ok && !crc2_ok) {

//gd->env_addr  0;

//gd->env_valid 0;

gd->env_valid 1;

return 0;

else if (crc1_ok && !crc2_ok) {

gd->env_valid 1;

}

其实这步是违规的。但是只有这样强制性才能达到我想要的目标,至于为什么,请求高手指点。编译运行,OK!

[转载]基于OK6410的u-boot2010.03移植到此结束

 

按理说,u-boot的移植到此就应该结束了,但是什么都要智能化,那么现在我们就完成智能化。

U-boot有许多指令,nand info, set 等等。现在我们来给u-boot添加我们想要的指令。

我们进入include/command.h头文件中 

可以找到 cmd_tbl_t这个结构体,u-boot中每个命令都用这样的一个结构体来描述,类型定义如下:

typedef struct cmd_tbl_s cmd_tbl_t;
 struct cmd_tbl_s {
                char *name;        // 命令的名称
                int maxargs;        // 最多支持的参数的个数
                int repeatable;        // 是否可重复执行
                int (*cmd)(struct cmd_tbl_s *, int, int, char *const[]);        // 命令对应的处理函数
                char *usage;        // 命令简要使用信息
                char *help;        // 命令详细帮助信息
        }

 

在commad.h文件夹下面新建一个cmd_hello.c文件:

#include <common.h>

#include <command.h>

 

int do_hello(cmd_tbl_t *cmdtp, int flag, int argc, char const argv[])

{

                       printf("my name is zhuzhaoqi!n");

                       return 0;

}

 

U_BOOT_CMD(hello, CONFIG_SYS_MAXARGS, 1, do_hello, "usage info",  "help info");

然后在common/Makefile中的#command添加如下内容:         COBJS-$(CONFIG_CMD_TEST) += cmd_hello.o

Ok,现在编译、运行:

[转载]基于OK6410的u-boot2010.03移植到此结束

我现在小试hello的指令,好了,我现在添加其他的指令。

 

我们现在在cmd_nand.c的基础上添加一个自动下载u-boot到nand flash中的指令,这个是第二版本新加。

进入cmd_nand.c中,在:

if (strcmp(cmd, "biterr") == 0) {

 

return 1;

}

之后添加:

 

if(strcmp(cmd,"uboot")==0)

{

printf("Re-program the u-boot to nand flashn");

if (argc 3)

goto usage;

 

addr (ulong)simple_strtoul(argv[2], NULL, 16);

run_command ("nand erase 100000", 0);

//printf("nand erase 100000......n");

size 0x1000;

 

puts("nwrite u-boot to nand flash......1 n");

for (i 0; 4; i++, addr += 0x800) 

{    

nand_write_skip_bad(nand, size*i, &size, (u_char *)(addr));

}

puts("write u-boot to nand flash......2 n");

for(i=4; i< 64; i++, addr += 0x1000)

{

nand_write_skip_bad(nand, size*i, &size, (u_char *)(addr));

}

 

return 0;

}

 

加上之后,编译运行:

[转载]基于OK6410的u-boot2010.03移植到此结束

这就是我们添加nand uboot 之后的效果。

 

接下来就是内核的引导了。这个就要根据内核来编译了。所以引导内核linux不同也会有所细微不同。

1.由于uboot只能引导uImage,因此需要把编译成的zImage转换成uImage,先进入u-boot根目录下,把tools/下mkimage复制到虚拟机/bin目录下,然后进入到linux-2.6.36/下输入指令:make uImage

2.#define CONFIG_BOOTARGS    "root=/dev/mtdblock2 rootfstype=cramfs console=ttySAC0,115200"是在smdk6410.h里面。这要根据linux内核mach-ok6410.c中的:

static struct mtd_partition ok6410_nand_part[] {

{

.name"Bootloader",

.offset0,

.size(1 SZ_1M),

.mask_flagsMTD_CAP_NANDFLASH,

},

 

{

.name"Kernel",

.offset(1 SZ_1M),

.size(5*SZ_1M) ,

.mask_flagsMTD_CAP_NANDFLASH,

},

 

{

.name"User",

.offset(6 SZ_1M),

.size(120*SZ_1M) ,

},

 

{

.name"File System",

.offsetMTDPART_OFS_APPEND,

.sizeMTDPART_SIZ_FULL,

}

};

分区而定。否则就算用这个可行的u-boot还是无法引导飞凌公司提供的编译好了的linux内核。

 

U-boot-2010.03的移植到此结束,历时2个月。想想我真的很菜,2个月才把u-boot2010.03移植成功。在此期间,牺牲了很多个周末和晚上休息时间,没办法,白天要去可恶的大教室上课。

本资料仅供初学u-boot者使用,因为里面可能会有错误,请各位指点。

借此五一放假,为了遵守我之前所说:[转载]基于OK6410的u-boot2010.03移植到此结束

我把资料在此整理了一遍。希望会对初学者有用。——宁静致远

原创粉丝点击