Chinaunix首页 | 论坛 | 博客
  • 博客访问: 198814
  • 博文数量: 103
  • 博客积分: 5051
  • 博客等级: 大校
  • 技术积分: 1155
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-08 11:07
文章分类

全部博文(103)

文章存档

2011年(1)

2010年(2)

2009年(100)

我的朋友

分类: LINUX

2009-05-09 12:50:38

环境变量设置:

 环境变量: export PATH=$PATH:/opt/crosstool/gcc-3.4.5-glibc-2.3.5/arm-linux/bin

编译命令

Make linux2410_config

Make CROSS_COMPILE=arm-linux-

修改顶层Makefile

(1) 在顶层Makefile 中为开发板添加新的配置选项,使用已有的配置项目为例:

 

smdk2410_config : unconfig

@./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

 

linux2410_config : unconfig

@./mkconfig $(@:_config=) arm arm920t linux2410x NULL s3c24x0

创建开发板目录

board 目录创建linux2410 用于存放开发板相关的代码

# cd ./board

# mkdir linux2410

# cp -r smdk2410 linux2410

修改board/linux2410/Makefile

OBJS :=smdk2410.o flash.o 修改为OBJS := linux2410.o flash.o

为开发板添加新的配置文件

cp include/configs/smdk2410.h include/configs/linux2410.h

修改lowlevel_init.S文件

修改board/linux2410x/lowlevel_init.S文件

#define B1_BWSCON (DW16) /* DW32改为DW16 */

board/linux2410/中添加nand_read.c文件:

#include

#include "linux/mtd/mtd.h"

#include "linux/mtd/nand.h"

 

//#define LARGEPAGE_FLASH

 

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

}

 

#ifndef LARGEPAGE_FLASH

#define NAND_SECTOR_SIZE        512

#else

#define NAND_SECTOR_SIZE        2048

#endif

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

    //if ((start_addr & NAND_BLOCK_MASK) /*|| (size > SZ_1M)*/) {

        return -1;      /* invalid alignment */

    }

 

    /* chip Enable */

    NFCONF &= ~0x800;

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

 

    for(i=start_addr; i < (start_addr + size);) {

      /* READ0 */

      NFCMD = NAND_CMD_READ0;

 

      /* Write Address */

#ifndef LARGEPAGE_FLASH

      NFADDR = i & 0xff;

      NFADDR = (i >> 9) & 0xff;

      NFADDR = (i >> 17) & 0xff;

      NFADDR = (i >> 25) & 0xff;

#else

      NFADDR = i & 0xff;

      NFADDR = (i >> 8) & 0x07;

      NFADDR = (i >> 11) & 0xff;

      NFADDR = (i >> 19) & 0xff;

      NFADDR = (i >> 27) & 0x3;

     

      NFCMD = NAND_CMD_READSTART;

#endif

      wait_idle();

 

      for(j=0; j < NAND_SECTOR_SIZE; j++) {

        *buf = (NFDATA & 0xff);

        buf++;

      }

      i += NAND_SECTOR_SIZE;

    }

 

    /* chip Disable */

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

 

    return 0;

 

 

修改board/linux2410/Makefile

修改为:OBJS := linux2410.o flash.o nand_read.o

 

 

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

_start_armboot:    .word start_armboot之后加入

 

#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.align     2

DW_STACK_START:

 .word      STACK_BASE+STACK_SIZE-4

    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

    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_BOOTbl    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

 

修改include/configs/linux2410.h文件

添加如下内容:

 

#ifndef __CONFIG_H

#define __CONFIG_H

 

/*

 * High Level Configuration Options

 * (easy to change)

 */

#define CONFIG_ARM920T        1     /* This is an ARM920T Core */

#define    CONFIG_S3C2410              1     /* in a SAMSUNG S3C2410 SoC     */

#define CONFIG_SMDK2410             1     /* on a SAMSUNG SMDK2410 Board  */

……

……

……

/*-----------------------------------------------------------------------

 * FLASH and environment organization

 */

 

#define CONFIG_AMD_LV400    1     /* uncomment this if you have a LV400 flash */

#if 0

#define CONFIG_AMD_LV800    1     /* uncomment this if you have a LV800 flash */

#endif

 

#define CFG_MAX_FLASH_BANKS    1     /* max number of memory banks */

#ifdef CONFIG_AMD_LV800

#define PHYS_FLASH_SIZE        0x00100000 /* 1MB */

#define CFG_MAX_FLASH_SECT      (19) /* max number of sectors on one chip */

#define CFG_ENV_ADDR           (CFG_FLASH_BASE + 0x0F0000) /* addr of environment */

#endif

#ifdef CONFIG_AMD_LV400

#define PHYS_FLASH_SIZE        0x00080000 /* 512KB */

#define CFG_MAX_FLASH_SECT      (11) /* max number of sectors on one chip */

#define CFG_ENV_ADDR           (CFG_FLASH_BASE + 0x070000) /* addr of environment */

#endif

 

/* timeout values are in ticks */

#define CFG_FLASH_ERASE_TOUT   (5*CFG_HZ) /* Timeout for Flash Erase */

#define CFG_FLASH_WRITE_TOUT  (5*CFG_HZ) /* Timeout for Flash Write */

 

#define    CFG_ENV_IS_IN_FLASH    1

#define CFG_ENV_SIZE              0x10000  /* Total Size of Environment Sector */

 

/*-----------------------------------------------------------------------

 *  NAND FLASH BOOT

 */

#define    CONFIG_S3C2410_NAND_BOOT      1

#define    STACK_BASE                     0x33f00000

#define    STACK_SIZE                   0x8000

 

 

#define    NAND_CTL_BASE                     0x4e000000

#define    bINT_CTL(Nb)                   _REG(INT_CTL_BASE+(Nb))

 

 

#define    oNFCONF                           0x00

#define    oNFCMD                            0x04

#define    oNFADDR                           0x08

#define    oNFDATA                           0x0c

#define    oNFSTAT                            0x10

#define    oNFECC                      0x14

 

/*-----------------------------------------------------------------------

 * NAND flash settings

 */

#define    CFG_NAND_LEGACY         1

#define    NFCE_LOW          0

#define    NFCE_HIGH         1

#define NAND_MAX_CHIPS             1

 

#if (CONFIG_COMMANDS & CFG_CMD_NAND)  

#define CFG_MAX_NAND_DEVICE   1     /* Max number of NAND devices        */

#define    CFG_NAND_BASE            0x4E000000

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

/* #undef CONFIG_MTD_NAND_VERIFY_WRITE */

#endif     /* CONFIG_COMMANDS & CFG_CMD_NAND */

 

 

 

 

加入自己的Nand Flash芯片型号

include/linux/mtd/nand_ids.h 中,对如下结构体赋值进行修改:

static struct nand_flash_dev nand_flash_ids[] = {

....

{"Samsung K9F1208VOM 64Mb", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},

....

};

U-BOOT添加NAND FLASH驱动

 

1、在drivers/nand_legacy/nand_legacy.c 中添加如下:

/**********************************************************************/

/* My ADD  */

#if (CONFIG_SMDK2410)

#include 3c2410.h>

 

#if (CONFIG_COMMANDS & CFG_CMD_NAND)

/*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)

static inline void NF_SetCE(int 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 1

#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\n", (ulong)nand);

#endif

       printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);

}

 

 

 

#endif      /*CONFIG_COMMANDS & CFG_CMD_NAND*/

#endif        /*CONFIG_SMDK23410*/

 

 

 

修改include/configs/linux2410.h如下:

……

……

/***********************************************************

 * Command definition

 ***********************************************************/

#define CONFIG_COMMANDS \

                     (CONFIG_CMD_DFL   | \

                     CFG_CMD_CACHE      | \

                     CFG_CMD_NAND       | \

                     /*CFG_CMD_EEPROM |*/ \

                     /*CFG_CMD_I2C  |*/ \

                     /*CFG_CMD_USB |*/ \

                     CFG_CMD_REGINFO  | \

                     CFG_CMD_DATE  | \

                     CFG_CMD_ELF)

……

……

 

 

 

修改drivers/nand_legacy/nand_legacy.c如下:

/*    for (i=0; i

        if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN)

                    {

            nand = &nand_dev_desc[i];

            break;

        }

    }

*/

nand = &nand_dev_desc[0]; 代替 nand = &nand_dev_desc[i];

修改在include/configs/linux2410.h中定义的一些宏

文件定义了CPU频率,网卡地址,SDRAM的某些设置也都在这里。主要修改如下:

/*cs8900网卡的设置*/

#define CONFIG_DRIVER_CS8900   1         //使用cs8900的驱动

#define CS8900_BASE         0x19000300   //网卡的地址,如要变动,则需查阅板子的手册

#define CS8900BUS16         1

/*设置波特率*/

#define CONFIG_BAUDRATE       115200

 

网络的一些环境变量的设置

#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

 

下面代码放到common/cmd_nand.c

#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)后边放

 

#if (CONFIG_SMDK2410)

#include 3c2410.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) */

 

 

 

再把以下代码放到include/configs/linux2410.h

#define CFG_ENV_SIZE     0x10000 /* TOtal Size of Environment Sector */之后

 

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

#define CONFIG_MTD_NAND_ECC_JFFS2 1

#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */

 

 

重新编译 make all ARCH=arm

 

阅读(655) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2010-05-07 10:58:18

dfg