2、 ok6410 uboot移植u-boot2010.03为蓝本,支持dm9000

时间:2021-04-30 17:13:04

转载自             http://blog.sina.com.cn/s/blog_79abea8a01012ruj.html

         http://blog.163.com/tianjunqiang666@126/blog/static/87259119201243034639891/   

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是一个新起点版本。

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

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

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

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

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

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

6.

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


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

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


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

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

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

进入u-boot-2010.03\include\asm-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 samsungs3c64xx; \

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 samsungs3c64xx; \

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.03\board\samsung\smdk6410,打开smdk6410.c,把#include<asm/arch/s3c6400.h>改成#include<asm/arch/s3c6410.h>

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

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

#ifndef CONFIG_NAND_SPL

mov r0, #0

mcr p15, 0, r0, c7, c7, 0

mcr p15, 0, r0, c8, c7, 0

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

mcr p15, 0, r0, c1, c0, 0

#endif

start.S中,bllowlevel_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的值一定在8K之内。那么执行完bicr1,pc,r0之后,r10_TEXT_BASE要么等于0x57e00000,要么等于0xC7e00000.那么执行完bicr2,r2,r0之后,r20x00e00000,那么不相等,则不跳转,下面应该就是copy_from_nand

2.如果是从ram中启动,那么PC的值为0xx7e00000。那么执行完bicr1,pc,r0之后,r10x00e00000_TEXT_BASE要么等于0x57e00000,要么等于0xC7e00000.那么执行完bicr2,r2,r0之后,r20x00e00000,那么相等,跳转到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.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,intlarge_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; i < 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; i < 4; i++, buf+=(1<<(page_shift-1)))

{

nandll_read_page(buf, i, large_block);

}

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;

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.03\cpu\arm1176makefile中:

COBJS = cpu.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

b copy_failed

compare_failed:

nop

b compare_failed

接着进入u-boot-2010.03\include\configs下面的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_SIZE 0x08000000

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

#define PHYS_SDRAM_1_SIZE 0x1000 0000

为什么?

我们来分析一下:

我们知道2^10=1KB, 2^20=1MB,那么0x10000000=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_TYPE 1270

#define MACH_TYPE 1626

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_SIZE 128

3.修改bootdelay时间

#define CONFIG_BOOTDELAY 10

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_HZ 1000 // at PCLK 50MHz

#define CONFIG_SYS_HZ 1562500

6.堆栈大小的修改

//#define CONFIG_STACKSIZE 0x40000

#define CONFIG_STACKSIZE 0x80000

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

//#define PHYS_SDRAM_1_SIZE 0x08000000

#define PHYS_SDRAM_1_SIZE 0x10000000

8.Total Size of Environment Sector 的修改

//#define CONFIG_ENV_SIZE 0x4000

#define CONFIG_ENV_SIZE 0x80000

9.CONFIG_BOOTCOMMAND的修改

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

"bootm 0x50018000"

修改为:

#define CONFIG_BOOTCOMMAND "nand read 0x50008000 0x100000 0x500000;" \

"bootm 0x50018000"

10.CONFIG_ENV_OFFSET的修改:

#define CONFIG_ENV_OFFSET 0x0080000

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

//#define CONFIG_SYS_NAND_PAGE_SIZE 2048

#define CONFIG_SYS_NAND_PAGE_SIZE 4096

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_COUNT 64

#define CONFIG_SYS_NAND_PAGE_COUNT 128

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

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_spl\board除去samsung文件夹以外的文件夹,进入samsung,复制一个smdk6410.

进入makefile

COBJS = nand_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开发版,可以看到下面效果:


于是乎,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_TIMEOUT 5000UL

修改成:

# define ARP_TIMEOUT 5

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 0 #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 ms\n",

TftpTimeoutMSecs);

TftpTimeoutMSecs = 1000;

}

debug("TFTP blocksize = %i, timeout = %ld ms\n",

TftpBlkSizeOption, TftpTimeoutMSecs);

#endif

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


放进去OK6410效果:


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

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

进入dm9000x.c,找到staticintdm9000_rx(structeth_device*netdev)函数,把for(;;){}修改成do{}while.

do之前添加:

DM9000_ior(DM9000_MRRH);

DM9000_ior(DM9000_MRRL);

static void dm9000_halt(struct eth_device *netdev)

{

DM9000_DBG("%s\n", __func__);

//phy_write(0, 0x8000);

//DM9000_iow(DM9000_GPR, 0x01);

//DM9000_iow(DM9000_IMR, 0x80);

//DM9000_iow(DM9000_RCR, 0x00);

}

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

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

Nand flash读写:

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

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

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

{

nandll_read_page(buf, i, large_block);

}

for (i = 4; i < (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 =0x57e00000.

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

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

{

nandll_read_page(buf, i, large_block);

}

i = 0 ,buf = buf + 2^(12-1) = buf+2K;

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

for (i = 4; i < (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了,但是,这是我在启动瞬间接下来的图:


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

没办法,找吧!

1.将s3c6410.h中的:

#define DMC1_MEM_CFG 0x00010012

#define DMC1_CHIP0_CFG 0x150F8

修改成如下:

#define DMC1_MEM_CFG 0x0001001a

#define DMC1_CHIP0_CFG 0x150F0

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!


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

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

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

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

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

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

#include <common.h>

#include <command.h>

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

{

printf("mynameiszhuzhaoqi!\n");

return0;

}

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,现在编译、运行:


我现在小试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 flash\n");

if (argc < 3)

goto usage;

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

run_command ("nand erase 0 100000", 0);

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

size = 0x1000;

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

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

}

加上之后,编译运行:


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

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

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

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

static struct mtd_partition ok6410_nand_part[] = {

{

.name = "Bootloader",

.offset = 0,

.size = (1 * SZ_1M),

.mask_flags = MTD_CAP_NANDFLASH,

},

{

.name = "Kernel",

.offset = (1 * SZ_1M),

.size = (5*SZ_1M) ,

.mask_flags = MTD_CAP_NANDFLASH,

},

{

.name = "User",

.offset = (6 * SZ_1M),

.size = (120*SZ_1M) ,

},

{

.name = "File System",

.offset = MTDPART_OFS_APPEND,

.size = MTDPART_SIZ_FULL,

}

};

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