u-boot1.1.6移植

时间:2023-02-15 06:34:20

思路:

. 移植前准备:u-boot源码,编译工具与开发平台等,阅读必要资料等

. 着手移植:

 

1.精简代码.

2.建立自己的开发板文件

3.增加对S3C2440的支持

4.配置NOR Flash

5.添加对NAND Flash的支持

6.添加网卡DM9000的支持

7.添加NAND Flash启动

8.内核引导.

9.支持烧写Yaffs文件系统

 

约定:

(1)PC 的命令表示方法:在 PC 的终端使用的命令,均在其前面加  #  号。

比如:解压源码: # tar -jxvf u-boot-1.1.6.tar.bz2  -C /opt/Zac/

(2)开发板的命令表示方法:在开发板的终端(也就是 PC 的超级终端或别的串口软件)上面运行的基于开发板的命令,均在其前面加  $  号。

比如:  $ tftp 0x32000000 u-boot.bin 

                            $ nfs 0x32000000 192.168.0.110:/opt/Zac/nfs_download/u-boot.bin

(3) 关于参考本手册输入命令时出错的问题的处理:请注意命令和参数间的空格,不要漏掉了。原因:在 Linux使用命令和参数之间是使用空格隔开的, 1 个空格和多个空格是等效的,在本手册中为了保持页面的整洁,对命令和参数之间使用了 1 个空格,可能因为空格的字体类型导致空格和非空格之间区别不是很明显,敬请谅解

(4)内核及各种文件路径(Linux):/opt/Zac/

如内核2.6.30.4的路径为:/opt/Zac/linux-2.6.30.4/

nfs共享文件夹路径为:/opt/Zac/nfs_download/

(5)主机Linux(虚拟机上)IP:192.168.0.110

   开发板IP:202.38.214.111

 

说明:这是我自己阅读了前人资料,结合自身的理解和操作而写的学习笔记,有些部分是摘抄别人的,但是由于一些来源不知道是哪里的,这里就不注明了,如果有异议,可以告知.另外,限于本人各方面的水平,肯定有不少错误,望指正与见谅.

                                                              Written by:Zac

 

 

u-boot-1.1.6移植(2)4-5NOR NAND Flash--Zac

 

1.  配置NOR Flash

上一步的测试中,发现SDRAM64M,Flash只有512K,这是因为我们还没有添加对Flash的支持.此步骤将完成对NOR Flash的支持.

(1) 根据你自己的硬件配置NOR Flash.u-boot-1.1.6对与NOR Flash的支持仅有AMD_LV400,AMD_LV800,我使用的开发板上刚好就是 AMD的芯片,因此就不需要修改 flash ID 号了.但是是AMD_LV160,因此只需做少许改动,就可以将AMD_LV800用于AMD_LV160使用了. 如果你的NOR Flash与之相近则任然可以使用,如果不一样则可以参考文档1(ARM79出品-u-boot移植手册.pdf)P21.

打开配置文件:include/configs/ZacV1.h(又修改配置文件,此处为了NOR Flash),修改如下(163)

 

#if 0

#define CONFIG_AMD_LV400  1   

#endif

#define CONFIG_AMD_LV800  1   

 

#define CFG_MAX_FLASH_BANKS 1 

#ifdef CONFIG_AMD_LV800

#define PHYS_FLASH_SIZE    0x00200000

#define CFG_MAX_FLASH_SECT  (19) 

#define CFG_ENV_ADDR    (CFG_FLASH_BASE + 0x1F0000)

#endif

#ifdef CONFIG_AMD_LV400

#define PHYS_FLASH_SIZE    0x00080000

#define CFG_MAX_FLASH_SECT  (11) 

#define CFG_ENV_ADDR    (CFG_FLASH_BASE + 0x070000)

#define CFG_FLASH_ERASE_TOUT  (5*CFG_HZ)

#define CFG_FLASH_WRITE_TOUT  (5*CFG_HZ)

 

#define  CFG_ENV_IS_IN_FLASH  1

#define CFG_ENV_SIZE    0x20000 

 

(2) 编译测试

最后make一下,没有错误,

#make clean

#make all

加载到内存中运行正常。运行结果如下:

U-Boot 1.1.6 (Oct 20 2011 - 16:50:50)

 

DRAM:  64 MB

Flash:  2 MB

*** Warning - bad CRC, using default environment

 

In:    serial

Out:   serial

Err:   serial

[ZacV1]$

注意到此时的Flash不在是512K,而是变成了2MB

 

PS:

其中Nor Flash的操作函数在board/ZacV1/flash.c中实现,它支持AM29LV400AM29LV800。需要注意的有:flash_init函数里面对flash_id的识别,不同flash参考其手册

        flash_info[i].flash_id =

#if defined(CONFIG_AMD_LV400)

            (AMD_MANUFACT & FLASH_VENDMASK) |

            (AMD_ID_LV400B & FLASH_TYPEMASK);

#elif defined(CONFIG_AMD_LV800)

            (AMD_MANUFACT & FLASH_VENDMASK) |

            (AMD_ID_LV800B & FLASH_TYPEMASK);

#else

#error "Unknown flash configured"

#endif

至于NOR Flash的驱动可以参考资料:NOR Flash 烧写指南

(http://ishare.iask.sina.com.cn/f/19707567.html) 和对应的芯片手册进行学习

 

 

5:添加对NAND Flash的支持

浏览u-boot-1.1.6的源码(lib_arm/board.c),你会发现默认情况下是不支持nand.

(1) 增加Nand Flash驱动.cpu/arm920t/s3c24x0目录下增加文件nand_flash.c直接复制TQnand_flash驱动,以后有时间再学习如何编写NAND Flash驱动.

代码如下:

 

 

#include <common.h>

 

#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)

#include <s3c2410.h>

#include <nand.h>

 

DECLARE_GLOBAL_DATA_PTR;

 

#define S3C2410_NFSTAT_READY    (1<<0)

#define S3C2410_NFCONF_nFCE     (1<<11)

 

#define S3C2440_NFSTAT_READY    (1<<0)

#define S3C2440_NFCONT_nFCE     (1<<1)

 

 

 

static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)

{

    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

 

    if (chip == -1) {

        s3c2410nand->NFCONF |= S3C2410_NFCONF_nFCE;

    } else {

        s3c2410nand->NFCONF &= ~S3C2410_NFCONF_nFCE;

    }

}

 

 

static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd)

{

    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

    struct nand_chip *chip = mtd->priv;

 

    switch (cmd) {

    case NAND_CTL_SETNCE:

    case NAND_CTL_CLRNCE:

        printf("%s: called for NCE\n", __FUNCTION__);

        break;

 

    case NAND_CTL_SETCLE:

        chip->IO_ADDR_W = (void *)&s3c2410nand->NFCMD;

        break;

 

    case NAND_CTL_SETALE:

        chip->IO_ADDR_W = (void *)&s3c2410nand->NFADDR;

        break;

 

       

       

    default:

        chip->IO_ADDR_W = (void *)&s3c2410nand->NFDATA;

        break;

    }

}

 

 

static int s3c2410_nand_devready(struct mtd_info *mtd)

{

    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

 

    return (s3c2410nand->NFSTAT & S3C2410_NFSTAT_READY);

}

 

 

 

static void s3c2440_nand_select_chip(struct mtd_info *mtd, int chip)

{

    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

 

    if (chip == -1) {

        s3c2440nand->NFCONT |= S3C2440_NFCONT_nFCE;

    } else {

        s3c2440nand->NFCONT &= ~S3C2440_NFCONT_nFCE;

    }

}

 

 

static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)

{

    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

    struct nand_chip *chip = mtd->priv;

 

    switch (cmd) {

    case NAND_CTL_SETNCE:

    case NAND_CTL_CLRNCE:

        printf("%s: called for NCE\n", __FUNCTION__);

        break;

 

    case NAND_CTL_SETCLE:

        chip->IO_ADDR_W = (void *)&s3c2440nand->NFCMD;

        break;

 

    case NAND_CTL_SETALE:

        chip->IO_ADDR_W = (void *)&s3c2440nand->NFADDR;

        break;

 

       

       

    default:

        chip->IO_ADDR_W = (void *)&s3c2440nand->NFDATA;

        break;

    }

}

 

 

static int s3c2440_nand_devready(struct mtd_info *mtd)

{

    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

 

    return (s3c2440nand->NFSTAT & S3C2440_NFSTAT_READY);

}

 

 

static void s3c24x0_nand_inithw(void)

{

    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

 

#define TACLS   0

#define TWRPH0  4

#define TWRPH1  2

 

    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)

    {

       

        s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);

    }

    else

    {

       

        s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);

       

        s3c2440nand->NFCONT = (1<<4)|(0<<1)|(1<<0);

    }

}

 

 

void board_nand_init(struct nand_chip *chip)

{

    S3C2410_NAND * const s3c2410nand = S3C2410_GetBase_NAND();

    S3C2440_NAND * const s3c2440nand = S3C2440_GetBase_NAND();

 

    s3c24x0_nand_inithw();

 

    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410) {

        chip->IO_ADDR_R    = (void *)&s3c2410nand->NFDATA;

        chip->IO_ADDR_W    = (void *)&s3c2410nand->NFDATA;

        chip->hwcontrol    = s3c2410_nand_hwcontrol;

        chip->dev_ready    = s3c2410_nand_devready;

        chip->select_chip  = s3c2410_nand_select_chip;

        chip->options      = 0;

    } else {

        chip->IO_ADDR_R    = (void *)&s3c2440nand->NFDATA;

        chip->IO_ADDR_W    = (void *)&s3c2440nand->NFDATA;

        chip->hwcontrol    = s3c2440_nand_hwcontrol;

        chip->dev_ready    = s3c2440_nand_devready;

        chip->select_chip  = s3c2440_nand_select_chip;

        chip->options      = 0;

    }

 

    chip->eccmode       = NAND_ECC_SOFT;

}

 

#endif

 

(2)添加了nand_flash.c这个文件,自然要将其添加到编译去,因此修改该目录下的 Makefile:29

OBJS  = i2c.o interrupts.o serial.o speed.o  \

  usb_ohci.o  nand_flash.o

 

(3)nand_flash.c中使用了结构体S3C2410_NAND, S3C2440_NAND(注意:s3c2410s3c2440 的nand flash控制器有区别.)在 include/s3c24x0.h 中定义 S3C2440_NAND 结构体:168 行

 

 

typedef struct {

    S3C24X0_REG32   NFCONF;

    S3C24X0_REG32   NFCMD;

    S3C24X0_REG32   NFADDR;

    S3C24X0_REG32   NFDATA;

    S3C24X0_REG32   NFSTAT;

    S3C24X0_REG32   NFECC;

} S3C2410_NAND;

 

 

typedef struct {

    S3C24X0_REG32   NFCONF;

    S3C24X0_REG32   NFCONT;

    S3C24X0_REG32   NFCMD;

    S3C24X0_REG32   NFADDR;

    S3C24X0_REG32   NFDATA;

    S3C24X0_REG32   NFMECCD0;

    S3C24X0_REG32   NFMECCD1;

    S3C24X0_REG32   NFSECCD;

    S3C24X0_REG32   NFSTAT;

    S3C24X0_REG32   NFESTAT0;

    S3C24X0_REG32   NFESTAT1;

    S3C24X0_REG32   NFMECC0;

    S3C24X0_REG32   NFMECC1;

    S3C24X0_REG32   NFSECC;

    S3C24X0_REG32   NFSBLK;

    S3C24X0_REG32   NFEBLK;

} S3C2440_NAND;

 

PS:这里顺带修改此文件,将其变得更加的通用(支持2440)

修改85,95,99,110,149,421:

#ifdef CONFIG_S3C2410  ===> #if defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)

 

(4)类似与(3),添加2440的对应函数,在 include/s3c2410.h 中复制96-99行到100-103行并修改

static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)

{

  return (S3C2440_NAND * const)S3C2410_NAND_BASE;

}

 

实际上由于24402410还是有很多的区别的,因此如果有兴趣可以自行根据include/s3c2410.h制作一个include/s3c2440.h,两者之间大部分内容是一致的,只是需要将2410没有而在2440中有的配置参照类似的或其他配置进行仿写.如果写好了这个文件,并且想根据实际配置2410还是2440进行条件编译和使用,则还需要修改某些文件的一些地方,如将include/configs/ZacV1.h中的

#define CONFIG_S3C2410 1  变为 #define CONFIG_S3C2440 1

 

(5)添加了nand,自然要修改配置文件include/configs/ZacV1.h(又修改了配置文件,此处修改支持nand flash),修对 Flash 的配置和增加 NAND 设置:188

//#define   CFG_ENV_IS_IN_FLASH     1

#define CFG_ENV_IS_IN_NAND      1

#define CFG_ENV_OFFSET          0x40000//

#define CFG_ENV_SIZE64          0xc000 

#define CFG_ENV_SIZE            0x20000

(注意这里要设置正确,此处设置为256MBNand Flash,如果为64MB,则应该为:

#define CFG_ENV_SIZE            0xc000  )

 

 

#define CFG_NAND_BASE           0

#define CFG_MAX_NAND_DEVICE     1

#define NAND_MAX_CHIPS          1

 

(6)修改配置文件 include/configs/ZacV1.h,增加 NAND 命令,87 行

#define CONFIG_COMMANDS \

      (CONFIG_CMD_DFL   |  \

      CFG_CMD_CACHE   |  \

      CFG_CMD_NAND   |  \

      \

        \

        \

      CFG_CMD_REGINFO  |  \

      CFG_CMD_DATE   |  \

      CFG_CMD_ELF)

(7)编译测试

make一下,没有错误

#make clean

#make all

编译成功后加载到 0x33000000 SDRAM  中运行会有 NAND 信息,输入 saveenv(save)

命令后保存没有错误,输入 help  命令会多了 nand 和 nboot 命令,如下所示

 

 

U-Boot 1.1.6 (Oct 21 2011 - 19:51:11)

 

DRAM:  64 MB

Flash:  2 MB

NAND:  256 MiB

In:    serial

Out:   serial

Err:   serial

Hit any key to stop autoboot:  0

Unknown command 'boot_zImage' - try 'help'

[ZacV1] $ save

Saving Environment to NAND...

Erasing Nand...Writing to Nand... done

[ZacV1] $ ?

?       - alias for 'help'

autoscr - run script from memory

base    - print or set address offset

bdinfo  - print Board Info structure

boot    - boot default, i.e., run 'bootcmd'

bootd   - boot default, i.e., run 'bootcmd'

bootelf - Boot from an ELF image in memory

bootm   - boot application image from memory

bootp   - boot image via network using BootP/TFTP protocol

bootvx  - Boot vxWorks from an ELF image

cmp     - memory compare

coninfo - print console devices and information

cp      - memory copy

crc32   - checksum calculation

date    - get/set/reset date & time

dcache  - enable or disable data cache

echo    - echo args to console

erase   - erase FLASH memory

flinfo  - print FLASH memory information

go      - start application at address 'addr'

help    - print online help

icache  - enable or disable instruction cache

iminfo  - print header information for application image

imls    - list all images found in flash

itest   - return true/false on integer compare

loadb   - load binary file over serial line (kermit mode)

loads   - load S-Record file over serial line

loady   - load binary file over serial line (ymodem mode)

loop    - infinite loop on address range

md      - memory display

mm      - memory modify (auto-incrementing)

mtest   - simple RAM test

mw      - memory write (fill)

nand    - NAND sub-system

nboot   - boot from NAND device

nfs     - boot image via network using NFS protocol

nm      - memory modify (constant address)

printenv- print environment variables

protect - enable or disable FLASH write protection

rarpboot- boot image via network using RARP/TFTP protocol

reset   - Perform RESET of the CPU

run     - run commands in an environment variable

saveenv - save environment variables to persistent storage

setenv  - set environment variables

sleep   - delay execution for some time

tftpboot- boot image via network using TFTP protocol

version - print monitor version

 

 

至此,我们的uboot移植又进一步了,已经可以看到NOR FlashNAND Flash的信息了,说明uboot支持我们自身硬件的NORNAND.高兴一下吧,哈哈哈哈!!!