IPB

Welcome Guest ( Log In | Register )

 
Reply to this topicStart new topic
> [转]移植U-Boot手记, InfoHunter‘s Blog
猫猫草
post 2007-04-26 16:09:18, Thu
Post #1


猫猫猫
***

Group: Power Cat
Posts: 626
Joined: 2006-12-8
Member No.: 2



一直想弄弄u-boot,却一直没时间弄。现在终于放假了,准备趁此清闲机会好好研究研究bootloader,于是从昨天开始往s3c2410板子上移植uboot,目前可以实现uboot在Nand Flash上的启动,擦写NF和引导Linux内核还没整明白。

一开始准备上sourceforge下的,不知怎么回事,就是上不去,于是改去www.denx.de上下载个最新版本的u-boot 1.2.0。下来之后在/usr/src中tar jxvf u-boot-1.2.0.tar.bz2解压缩了,进入代码目录,然后把board/smdk2410目录给cp成board/py2410,这个 py2410是我给自己板子起的名字,其他名字也可以,无特定要求。然后cd board/py2410,把里面的smdk2410.c改名称py2410.c(要与板子名称一致)。并且把 include/configs/smdk2410.h给cp成include/configs/py2410.h。最后退到源代码目录的根处,把 Makefile里面加上:
代码
py2410_config: unconfig
  @$(MKCONFIG) $(@:_config=) arm arm920t py2410 NULL s3c24x0

并找到
代码
ifeq($(ARCH), arm)
CROSS_COMPILE = arm-linux

在这里修改交叉编译工具的路径。这里有个问题,第一次我使用的是2.95.3的arm-linux-gcc,编译了一下不好使,说是一个什么符号不识别。然后我就改用了3.3.2版本的工具,然后问题解决。因为在网上搜帖子看到的大部份人编译uboot 1.1.3用的是2.95.3,难道1.2.0的时候不好使了?所以比较疑惑,有时间再研究一下这个地方。
做好以上工作之后就可以build一下了
引用

make py2410_config
make all
一阵编译之后,没有问题,生成了u-boot.bin等文件,但是这个如果现在就下载到板子上用,那基本上是不好使的,所以接下来就开始修改一些参数,添加一些代码,使其能正常工作。

上网搜索了一下uboot移植的帖子,以下这个比较不错,很详细:
这个帖子说的是移植到arm7上的,可以参考一下移植过程以及了解一下uboot工作的方式
http://www.icwin.net/ShowArtitle.ASP?art_i...8&cat_id=16
所谓修改参数主要是指修改在include/configs/py2410.h中定义的一些宏,这个文件里定义了像CPU频率,网卡地址,SDRAM的某些设置也都在这里。主要修改如下:
代码
/*cs8900网卡的设置*/
#define CONFIG_DRIVER_CS8900   1         //使用cs8900的驱动
#define CS8900_BASE         0x19000300   //网卡的地址,如要变动,则需查阅板子的手册
#define CS8900BUS16         1
/*设置波特率*/
#define CONFIG_BAUDRATE       115200

下面是选择要编译的命令,这些命令是在uboot启动之后可以在提示符下使用的,具体含义README中有详细说明,需要指出的是,ping的功能得自己手动加上去,CONFIG_CMD_DEL中没有ping,将这里修改如下:
代码
#define CONFIG_COMMANDS
(CONFIG_CMD_DFL |
CFG_CMD_CACHE |
/*CFG_CMD_NAND | */
/*CFG_CMD_EEPROM |*/
/*CFG_CMD_I2C |*/
/*CFG_CMD_USB |*/
CFG_CMD_PING   |
CFG_CMD_REGINFO |
CFG_CMD_DATE |
CFG_CMD_ELF)

这里关于nand的命令先没加上,因为擦写nand的功能还没搞明白
下面是关于网络的一些环境变量的设置(这些变量都可以在uboot起来之后重新修改):
代码
#define CONFIG_BOOTDELAY   5
#define CONFIG_BOOTARGS   "root=/dev/mtdblock2 loadramfs=0 devfs=mount mem=64M init=/linuxrc console=ttyS0,115200"
#define CONFIG_ETHADDR       00:00:C0:FF:EE:08
#define CONFIG_NETMASK       255.255.255.0
#define CONFIG_IPADDR       10.0.0.110
#define CONFIG_SERVERIP       10.0.0.100

有关于网卡mac地址,ip地址,以及tftp服务器的ip的设置,还有linux内核启动的参数等
接下来非常重要,使关于SDRAM的设置:
代码
#define CONFIG_NR_DRAM_BANKS     1        
#define PHYS_SDRAM_1           0x30000000   //SDRAM的开始地址
#define PHYS_SDRAM_1_SIZE       0x04000000   //SDRAM的大小,这里是64MB

py2410.h中基本修改这些就可以了,然后打开board/py2410/lowlevel_init.S文件:
按照板子上的实际情况的分配来修改以下寄存器的值。我是按照原来板子上给的bootloader中的设置修改的:
代码
#define BWSCON 0x48000000       //这个是SFR区中控制SDRAM的寄存器的基址

/* BWSCON */
#define DW8   (0x0)
#define DW16   (0x1)
#define DW32   (0x2)
#define WAIT   (0x1<<2)
#define UBLB   (0x1<<3)

#define B1_BWSCON   (DW32)
#define B2_BWSCON   (DW16)
#define B3_BWSCON   (DW16 + WAIT + UBLB)
#define B4_BWSCON   (DW16)
#define B5_BWSCON   (DW16)
#define B6_BWSCON   (DW32)
#define B7_BWSCON   (DW32)

/* BANK0CON */
#if 0
#define B0_Tacs   0x0 /* 0clk */
#define B0_Tcos   0x0 /* 0clk */
#define B0_Tacc   0x7 /* 14clk */
#define B0_Tcoh   0x0 /* 0clk */
#define B0_Tah   0x0 /* 0clk */
#define B0_Tacp   0x0
#define B0_PMC   0x0 /* normal */
#endif

#define B0_Tacs   0x3 /* 0clk */
#define B0_Tcos   0x3 /* 0clk */
#define B0_Tacc   0x7 /* 14clk */
#define B0_Tcoh   0x3 /* 0clk */
#define B0_Tah   0x3 /* 0clk */
#define B0_Tacp   0x1
#define B0_PMC   0x0 /* normal */

/* BANK1CON */

#define B1_Tacs   0x3 /* 0clk */
#define B1_Tcos   0x3 /* 0clk */
#define B1_Tacc   0x7 /* 14clk */
#define B1_Tcoh   0x3 /* 0clk */
#define B1_Tah   0x3 /* 0clk */
#define B1_Tacp   0x3
#define B1_PMC   0x0

#define B2_Tacs   0x0
#define B2_Tcos   0x0
#define B2_Tacc   0x7
#define B2_Tcoh   0x0
#define B2_Tah   0x0
#define B2_Tacp   0x0
#define B2_PMC   0x0

#define B3_Tacs   0x0 /* 0clk */
#define B3_Tcos   0x0 /* 4clk */
#define B3_Tacc   0x7 /* 14clk */
#define B3_Tcoh   0x0 /* 1clk */
#define B3_Tah   0x0 /* 0clk */
#define B3_Tacp   0x0   /* 6clk */
#define B3_PMC   0x0 /* normal */

#define B4_Tacs   0x0 /* 0clk */
#define B4_Tcos   0x0 /* 0clk */
#define B4_Tacc   0x7 /* 14clk */
#define B4_Tcoh   0x0 /* 0clk */
#define B4_Tah   0x0 /* 0clk */
#define B4_Tacp   0x0
#define B4_PMC   0x0 /* normal */

#define B5_Tacs   0x0 /* 0clk */
#define B5_Tcos   0x0 /* 0clk */
#define B5_Tacc   0x7 /* 14clk */
#define B5_Tcoh   0x0 /* 0clk */
#define B5_Tah   0x0 /* 0clk */
#define B5_Tacp   0x0
#define B5_PMC   0x0 /* normal */

#define B6_MT   0x3 /* SDRAM */
#define B6_Trcd   0x1
#define B6_SCAN   0x1 /* 9bit */

#define B7_MT   0x3 /* SDRAM */
#define B7_Trcd   0x1 /* 3clk */
#define B7_SCAN   0x1 /* 9bit */

/* REFRESH parameter */
#define REFEN   0x1 /* Refresh enable */
#define TREFMD   0x0 /* CBR(CAS before RAS)/Auto refresh */
#define Trp   0x0 /* 2clk */
#define Trc   0x3 /* 7clk */
#define Tchr   0x2 /* 3clk */
#define REFCNT   1113 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
/**************************************/

别的基本不用动了,然后重新编译uboot:
引用

make distclean
make py2410_config
make all

把生成的u-boot.bin通过原来板子上厂家给的bootloader下载到内存中去,然后用原来的bootloader运行u-boot.bin,这时应该可以看到串口上输出的信息了:
引用

U-Boot 1.2.0 (Feb 2 2007 - 00:49:08)

DRAM: 64 MB
Flash: 512 kB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
PY2410 #
然后ping一下tftp服务器(事先要准备好tftp server,这里地址是10.0.0.100)
引用

PY2410 #ping 10.0.0.100
host 10.0.0.100 is alive
PY2410 #

说明网络功能ok,试着下载一个zImage,然后用go运行一下,结果内核解压缩之后就停在那里了,可能是文件系统没load进去?目前还没解决引导的问题。
至此,uboot已经可以在ram中跑了,下面弄nand flash boot,好把它给烧到flash中去
上网再搜索一番,发现了一篇相当不错的文章:
http://blog.csdn.net/bekars/archive/2006/05/06/710888.aspx
照着文章开始修改u-boot,主要修改如下:
1)先在board/py2410目录下新建一个nand_read.c,内容如下:
代码
#include <config.h>

#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCMD __REGb(NF_BASE + 0x4)
#define NFADDR __REGb(NF_BASE + 0x8)
#define NFDATA __REGb(NF_BASE + 0xc)
#define NFSTAT __REGb(NF_BASE + 0x10)

#define BUSY 1
inline void wait_idle(void) {
  int i;

  while(!(NFSTAT & BUSY))
    for(i=0; i<10; i++);
}

#define NAND_SECTOR_SIZE 512
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)

/* low level nand read function */
int
nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
  int i, j;

  if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
    return -1; /* invalid alignment */
  }

  /* chip Enable */
  NFCONF &= ~0x800;
  for(i=0; i<10; i++);

  for(i=start_addr; i < (start_addr + size);) {
    /* READ0 */
    NFCMD = 0;

    /* Write Address */
    NFADDR = i & 0xff;
    NFADDR = (i >> 9) & 0xff;
    NFADDR = (i >> 17) & 0xff;
    NFADDR = (i >> 25) & 0xff;

    wait_idle();

    for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
*buf = (NFDATA & 0xff);
buf++;
    }
  }

  /* chip Disable */
  NFCONF |= 0x800; /* chip disable */

  return 0;
}

2)修改board/py2410下的Makefile,要不没法编译:
代码
OBJS := py2410.o flash.o nand_read.o

3)在cpu/arm920t/start.S的
代码
ldr pc, _start_armboot

前加入
代码
#ifdef CONFIG_S3C2410_NAND_BOOT
bl   copy_myself

@ jump to ram
ldr   r1, =on_the_ram
add pc, r1, #0
nop
nop
1:   b   1b       @ infinite loop

on_the_ram:
#endif

然后在最后加上:
代码
#ifdef CONFIG_S3C2410_NAND_BOOT
copy_myself:
mov r10, lr
@ reset NAND
mov r1, #NAND_CTL_BASE
ldr   r2, =0xf830       @ initial value
str   r2, [r1, #oNFCONF]
ldr   r2, [r1, #oNFCONF]
bic r2, r2, #0x800         @ enable chip
str   r2, [r1, #oNFCONF]
mov r2, #0xff       @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0             @ wait

1:add r3, r3, #0x1
cmp r3, #0xa
blt   1b
2:ldr   r2, [r1, #oNFSTAT]     @ wait ready
tst   r2, #0x1
beq 2b
ldr   r2, [r1, #oNFCONF]
orr r2, r2, #0x800         @ disable chip
str   r2, [r1, #oNFCONF]

@ get read to call C functions (for nand_read())
ldr   sp, DW_STACK_START     @ setup stack pointer
mov fp, #0             @ no previous frame, so fp=0

@ copy vivi to RAM
ldr   r0, =UBOOT_RAM_BASE
mov   r1, #0x0
mov r2, #0x20000
bl   nand_read_ll
tst   r0, #0x0
beq ok_nand_read

#ifdef CONFIG_DEBUG_LL
bad_nand_read:
ldr   r0, STR_FAIL
ldr   r1, SerBase
bl   PrintWord
1:b   1b       @ infinite loop
#endif

ok_nand_read:
#ifdef CONFIG_DEBUG_LL
ldr   r0, STR_OK
ldr   r1, SerBase
bl   PrintWord
#endif

@ verify
mov r0, #0
ldr   r1, =UBOOT_RAM_BASE
mov r2, #0x400   @ 4 bytes * 1024 = 4K-bytes
go_next:
ldr   r3, [r0], #4
ldr   r4, [r1], #4
teq   r3, r4
bne notmatch
subs r2, r2, #4
beq done_nand_read
bne go_next

notmatch:
#ifdef CONFIG_DEBUG_LL
sub r0, r0, #4
ldr   r1, SerBase
bl   PrintHexWord
ldr   r0, STR_FAIL
ldr   r1, SerBase
bl   PrintWord
#endif
1:b   1b
done_nand_read:
#ifdef CONFIG_DEBUG_LL
ldr   r0, STR_OK
ldr   r1, SerBase
bl   PrintWord
#endif
mov pc, r10
@ clear memory
@ r0: start address
@ r1: length
mem_clear:
mov r2, #0
mov r3, r2
mov r4, r2
mov r5, r2
mov r6, r2
mov r7, r2
mov r8, r2
mov r9, r2

clear_loop:
stmia     r0!, {r2-r9}
subs r1, r1, #(8 * 4)
bne clear_loop
mov pc, lr

#endif @ CONFIG_S3C2410_NAND_BOOT

  .align   2
DW_STACK_START:
.word     STACK_BASE+STACK_SIZE-4

这几段的意思是说uboot把自己copy到SDRAM中,然后在ram中执行_start_armboot开始的程序
4)最后一步,在include/configs/py2410.h中加上:
代码
/*
* Nandflash Boot
*/
#define CONFIG_S3C2410_NAND_BOOT 1
#define STACK_BASE   0x33f00000
#define STACK_SIZE   0x8000
#define UBOOT_RAM_BASE   0x33f80000
/* NAND Flash Controller */
#define NAND_CTL_BASE         0x4E000000
#define bINT_CTL(Nb)     __REG(INT_CTL_BASE + (Nb))
/* Offset */
#define oNFCONF           0x00
#define oNFCMD           0x04
#define oNFADDR           0x08
#define oNFDATA           0x0c
#define oNFSTAT           0x10
#define oNFECC           0x14

这是定义了SFR区中和Nand Flash控制器相关的寄存器地址,具体参见芯片手册
最后重新编译u-boot:
引用
make distclean
make py2410_config
make all

把生成的u-boot.bin烧写到板子上Nand Flash的0x0处,reset开发板,就可以看到启动信息了。

目前只进行到这里,还有u-boot读写flash的功能以及bootloader最重要的引导操作系统的功能还没整出来,网上的资料很多都是1.1.x 版本的uboot,与1.2.0版本有些不同,比如在说擦写falsh的问题时,不少人指出uboot里的nand_init函数没有实现,需要自己添加,但是在1.2.0版本的uboot中是存在这个函数的(drivers/nand/nand.c里,这个版本比1.1.x多了个nand目录),总之看来区别还是不少,具体情况准备明天去denx.de看看文档再说。

PS:我用的是优龙的板子,他们给的jtag小板的并口接头外面居然多了一个铁圈,还有两边的那种可以拧进去螺丝的螺丝,好像是准备让别的母口的头插进来似的,于是没辙,只能拿钳子把螺丝给卸了,现在并口插头上就是25根“针头”,插在笔记本后面晃晃荡荡的
Go to the top of the page
 
+Quote Post
猫猫草
post 2007-04-26 16:23:26, Thu
Post #2


猫猫猫
***

Group: Power Cat
Posts: 626
Joined: 2006-12-8
Member No.: 2



昨天把u-boot给勉强跑通了,但是还无法读写Nand Flash和启动内核。今天忙活了一天,最后终于没坚持住,放弃了u-boot 1.2.0 + arm-linux 3.3.2,改用1.1.4 + arm-linux 2.95.3,在网上借鉴,copy了无数高手之成果,u-boot终于TNND被俺给整成能读写Nand的了。下面请听详细~~~报道:

今天已开始就接着昨天的弄,昨天发现1.2.0的u-boot变化挺大,但是网上很多都是说1.1.4或之前的版本。低版本的u-boot里有个void nand_init(void)函数没有实现(在lib_arm/board.c中),自然,把这个给实现了就完事了。但是在1.2.0里,整出来了 drivers/nand和drivers/nand_legacy两个目录,里面因该是nand的驱动吧,上网上查了一圈,发现cu的pywj777兄给了比较明确的解释,原文链接如下:
http://bbs2.chinaunix.net/viewthread.php?tid=855860
文中提到了nand_legacy的问题,说是有个叫CFG_NAND_LEGACY的宏,如果没定义这个宏,就是按照默认规定,调用 drivers/nand/nand.c中的nand_init函数(该函数在1.2.0已经被实现),但还有个board_nand_init给咱留着呢,咱的任务就是把这个函数给填上。那么如果定义了CFG_NAND_LEGACY,就变成了不使用默认的nand_init,得自己写 nand_init了。于是按照文中的做法,自己加了一些代码,不过由于俺对2410的硬件是在是太不了解了,一直都没调明白,加上对1.2.0代码中那些nand的驱动没彻底弄明白,混乱的很,最后不得已,放弃了1.2.0,改用1.1.4的u-boot,这个版本里对nand的支持似乎很少,但是也决定了这个版本在移植的过程中思路会很清晰。

下载了之后改用2.95.3的交叉编译器,上来还是像以前那么做,自己弄个 board/py2410出来,修改各种参数,不在话下。一些妥当之后,make了一下,然后就是错误,是那个apcs-gnu什么的那个选项无效。这也是个经典问题了,所以直接按网上说的,把cpu/arm920t/config.mx给改了,然后重新编译,顺利通过。

之后我发现了一个超级无敌的帖子,在此要严重感谢作者贡献此妙文,俺之所以能把u-boot移植成功,就是因为看了这个:
http://xianzilu.spaces.live.com/blog/
这里作者写了一篇关于nand flash驱动的文章,俺看了之后就照着去做,具体如下:
把下面代码放到common/cmd_nand.c中
代码
#if (CONFIG_SMDK2410)

#include <s3c2410.h>

typedef enum {
    NFCE_LOW,
    NFCE_HIGH
} NFCE_STATE;

static inline void NF_Conf(u16 conf)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFCONF = conf;
}

static inline void NF_Cmd(u8 cmd)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFCMD = cmd;
}

static inline void NF_CmdW(u8 cmd)
{
    NF_Cmd(cmd);
    udelay(1);
}

static inline void NF_Addr(u8 addr)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFADDR = addr;
}

static inline void NF_SetCE(NFCE_STATE s)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    switch (s) {
    case NFCE_LOW:
      nand->NFCONF &= ~(1<<11);
      break;
    case NFCE_HIGH:
      nand->NFCONF |= (1<<11);
      break;
    }
}

static inline void NF_WaitRB(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    while (!(nand->NFSTAT & (1<<0)));
}

static inline void NF_Write(u8 data)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFDATA = data;
}

static inline u8 NF_Read(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    return(nand->NFDATA);
}

static inline void NF_Init_ECC(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    nand->NFCONF |= (1<<12);
}

static inline u32 NF_Read_ECC(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    return(nand->NFECC);
}

extern ulong nand_probe(ulong physadr);

static inline void NF_Reset(void)
{
  int i;
  NF_SetCE(NFCE_LOW);
  NF_Cmd(0xFF); /* reset command */
  for(i = 0; i < 10; i++); /* tWB = 100ns. */
  NF_WaitRB(); /* wait 200~500us; */
  NF_SetCE(NFCE_HIGH);
}

static inline void NF_Init(void)
{
#if 0 /* a little bit too optimistic */
#define TACLS   0
#define TWRPH0 3
#define TWRPH1 0
#else
#define TACLS   0
#define TWRPH0 4
#define TWRPH1 2
#endif
  NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
  /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
  /* 1 1   1   1,   1     xxx, r xxx,   r xxx */
  /* En 512B 4step ECCR nFCE=H tACLS   tWRPH0   tWRPH1 */
  NF_Reset();
}

void nand_init(void)
{
    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
    NF_Init();
    #ifdef DEBUG
    printf("NAND flash probing at 0x%.8lX ", (ulong)nand);
    #endif
    printf ("%4lu MB ", nand_probe((ulong)nand) >> 20);
}

#endif /* (CONFIG_SMDK2410) */

不过我把#if CONFIG_SMDK2410/#endif给去掉了,因为感觉没啥必要,还多打些字

再把以下代码放到include/configs/py2410.h中
代码
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
#define SECTORSIZE 512
#define ADDR_COLUMN 1
#define ADDR_PAGE 2
#define ADDR_COLUMN_PAGE 3
#define NAND_ChipID_UNKNOWN 0x00
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
#define NAND_WAIT_READY(nand) NF_WaitRB()
#define NAND_DISABLE_CE(nand) NF_SetCE(NFCE_HIGH)
#define NAND_ENABLE_CE(nand) NF_SetCE(NFCE_LOW)

#define WRITE_NAND_COMMAND(d, adr) NF_Cmd(d)
#define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d)
#define WRITE_NAND_ADDRESS(d, adr) NF_Addr(d)
#define WRITE_NAND(d, adr) NF_Write(d)
#define READ_NAND(adr)   NF_Read()
/* the following functions are NOP's because S3C24X0 handles this in hardware */
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)
/* #define CONFIG_MTD_NAND_VERIFY_WRITE 1 */
/* This definition above is commented by Lu Xianzi. 2006.05.28
  Because there's no definition of a macro called __mem_pci,
  there will be a link error.
*/
#define CONFIG_MTD_NAND_ECC_JFFS2 1
#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */

其中红字是作者发现的一个问题,说得把CONFIG_MTD_NAND_VERIFY_WRITE这个宏给注释掉,要不链接时会出问题。

整个思路非常清晰,步骤也很简单,弄完之后重新make一遍,把生成的u-boot.bin通过串口下载到板子上,然后再板子的旧u-boot中执行这个新的u-boot,结果大跌眼镜,没出现Nand: 64 MB的字样,打help命令也没出现nand的命令解释,nand command没加上,但是编译的时候CFG_CMD_NAND已经开开了啊,怎么会这样,百思不解。后来突然想到以前在厂家给的bootloader中运行从Nand启动的u-boot时也不好使,后来把u-boot用jtag烧到板子上就好了。于是再次使用jtag把u-boot烧到nand flash中,reset开发板,这次ok了,然后随便执行了几个nand的命令,都挺好使,呵呵

接下来就是弄内核了,不过要想把内核调通了肯定还得是一场恶战啊
Go to the top of the page
 
+Quote Post
猫猫草
post 2007-04-26 16:46:13, Thu
Post #3


猫猫猫
***

Group: Power Cat
Posts: 626
Joined: 2006-12-8
Member No.: 2



前几天移植了u-boot,但是始终无法加载内核。使用的内核是优龙给的现成的,在优龙的bootloader下引导没有问题,但是在u-boot下无法成功引导,每当解压结束之后就halt了。
一连困扰了很多天,一开始以为是参数传不进去就把参数写死到内核了,还是不行,于是想到可能是引导内核前环境设置的不对,而对u-boot的代码不是很懂,不会修改,于是想出了一个方法:参照优龙的bootloader引导内核的代码,向u-boot添加了一个新的命令,用于引导Linux内核。

添加pyboot命令:
上网查了一下资料,了解了一下向u-boot中加命令的方法,首先在include/cmd_confdefs.h中加入新命令对应的宏,该文件中已经有了很多的命令,添加的时候定义的值不要和其他命令重复就行,而且必须是某一位为1,其他都是0的值,这里添加如下:
代码
#define CFG_CMD_PYBOOT   0x8000000000000000ULL

然后在common下新建一个cmd_pyboot.c文件,这个文件是pyboot命令的具体实现代码,在include下新建pyboot.h文件,该文件是cmd_pyboot.c所使用的头文件。之后修改common下的Makefile,在
代码
COBJS = xxxxxxxxx\
              xxxxxxxxx\
              .......

加入cmd_pyboot.o,让编译的时候编译cmd_pyboot文件。
最后回到开发板的配置文件处(include/configs/py2410.h),在这里的命令列表中加上CFG_CMD_PYBOOT,告诉u-boot编译进pyboot命令。然后make一下,下载到开发板上就可以了。
pyboot能够使用的前提是板子上的kernel以及cramfs都是优龙自带的,自己编译的内核可不可以现在未知。

比较关键的是cmd_pyboot.c文件,里面填充了一个指向0x30000100的params_struct结构体,用来存放内核参数,并且将Nand Flash上的kernel读到内存的0x30200000处,不知道为什么不是0x30008000???
cmd_pyboot.c的框架如下:
代码
#include <common.h>
#include <config.h>
#include <command.h>
#include <pyboot.h>

#ifdef (CFG_COMMAND & CFG_CMD_PYBOOT)
..........
do_pyboot(...)
{
    ............
}

U_BOOT_CMD(
  pyboot, 1, 1, do_pyboot,
  "Help Infos\n",
  "Long Help Infos\n"
);
#endif

do_pyboot是命令的主函数,使用U_BOOT_CMD宏来向系统注册一个命令。
另外值得一提的是,这次使用了source insight来看优龙的代码,这个东西真是不错啊,功能强大,适合用来查看/编辑大型的程序
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
3 User(s) are reading this topic (3 Guests and 0 Anonymous Users)
0 Members:

 



Lo-Fi Version Time is now: 2024-12-25 01:52