鲁班锁八角球解法:移植uboot1.3.1到s3c2410

来源:百度文库 编辑:九乡新闻网 时间:2024/07/04 21:41:43
移植uboot1.3.1到s3c2410(1)--建立开发板 (2009-07-30 17:15)分类: Bootloader相关

1        在U-Boot中建立自己的开发板类型,并测试编译

开发板取名叫: edukit2410

开发板基本配置:

                            处理芯器片   S3C2410

                            NANDFLASHK9F1208U0B 64M

                            NorFLASH      AM29LV160DB

                            网卡芯片:        DM9000AEP

                            SDRAM          HY57V561620 32M * 2

                            LCD                LQ080V3DG01 TFT

移植u-boot版本:

                            U-boot:                u-boot1.3.1

1)  在工作目录下解压U-Boot

$ tar -xjvf u-boot-1.3.1.tar.bz2  

2)进入U-Boot目录,修改Makefile

$ cd u-boot-1.3.1

$ kwrite Makefile

#edukit2410建立编译项(建议从sbc2410_config复制后做相应的修改)。

sbc2410x_config: unconfig

    @$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s3c24x0

edukit2410_config    :    unconfig

        @$(MKCONFIG) $(@:_config=) arm arm920t edukit2410 Embest s3c24x0

各项的意思如下:

         arm: CPU的架构(ARCH)

         arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录;

         edukit2410: 开发板的型号(BOARD),对应于board/Embest/edukit2410目录;

         Embest: 开发者/或经销商(vender)

         s3c24x0: 片上系统(SOC)

设置交叉编译工具。

$ source /usr/crosstool/gcc-3.4.5-glibc-2.3.6/arm-linux/path.sh

 

3)在/board子目录中建立自己的开发板edukit2410目录

由于我在上一步板子的开发者/或经销商(vender)中填了 Embest ,所以开发板edukit2410目录一定要建在/board子目录中的Embest目录下 ,否则编译会出错。

$ cd board

$ mkdir Embest Embest/edukit2410

$ cp -arf sbc2410x/* Embest/edukit2410/

$ cd Embest/edukit2410/

$ mv sbc2410x.c edukit2410.c

还要记得修改自己的开发板edukit2410目录下的Makefile文件,不然编译时会出错:

$ kwrite Makefile

COBJS    := edukit2410.o flash.o

4)在include/configs/中建立配置头文件

$ cd ../../..

$ cp include/configs/sbc2410x.h include/configs/edukit2410.h

5)测试编译能否成功

(1)配置

$ make edukit2410_config

Configuring for edukit2410 board...

如果出现:

      $ make edukit2410_config

      Make1927: *** 遗漏分隔符 停止。

      请在Uboot的根目录下的Makefile

        @$(MKCONFIG) $(@:_config=) arm arm920t edukit2410 Embest)

       前加上“Tab”

2)测试编译

$make

测试通过后进行下一步。

2        修改U-boot文件,以支持nandflash读写

2.1        修改/cpu/arm920t/start.S

#include

#include

#if    defined(CONFIG_AT91RM9200DK)

#include     /*这是针对AT91RM9200DK开发板的。对于SCB2440V4也有4个LED指示灯,我用来指示程序用行的进度。*/

#endif

......

/*

 * the actual start code

 */

 

start_code:

    /*

     * set the cpu to SVC32 mode

     */

    mrs    r0,cpsr

    bic    r0,r0,#0x1f

    orr    r0,r0,#0xd3

    msr    cpsr,r0

#if    defined(CONFIG_AT91RM9200DK)

    bl coloured_LED_init

    bl red_LED_on

#endif

1)        修改寄存器地址定义

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)

    /* turn off the watchdog */

 

#if defined(CONFIG_S3C2400)

#define pWTCON        0x15300000

#define INTMSK        0x14400008    /* Interupt-Controller base addresses */

#define CLKDIVN    0x14800014    /* clock divisor register */

#else

#define pWTCON        0x53000000

#define INTMSK        0x4A000008    /* Interupt-Controller base addresses */

#define INTSUBMSK    0x4A00001C

#define CLKDIVN    0x4C000014    /* clock divisor register */

#endif

#define CLK_CTL_BASE 0x4C000000 /* Embest */

#define MDIV_405 0x7f << 12 /* Embest */

#define PSDIV_405 0x21 /* Embest */

#define MDIV_200 0xa1 << 12 /* Embest */

#define PSDIV_200 0x31 /* Embest */

   

......

2)        修改中断禁止部分

#if defined(CONFIG_S3C2410)

    ldr r1, =0x7ff /*根据2410芯片手册,INTSUBMSK有11位可用,

                       vivi也是0x7ff,U-Boot一直没改过来。*/

    ldr r0, =INTSUBMSK

    str r1, [r0]

#endif

3)        修改时钟设置

    /* FCLK:HCLK:PCLK = 1:2:4 */

    /* default FCLK is 12 MHz ! 在这里U-Boot有一个错误:以为默认时钟为120MHz。其实如果没有添加以下设置FCLK的语句,芯片内部的PLL是无效的,即FCLK为 12MHz。S3C24x0的芯片手册说得很明白。我一开始没有注意到这一点,是 CalmArrow提醒了我并和我讨论过,他也做过实验证实了这点。在这里对CalmArrow表示感谢和敬意!*/

    ldr    r0, =CLKDIVN

    mov    r1, #3

    str    r1, [r0]

 

    mrc p15, 0, r1, c1, c0, 0 /*read ctrl register Embest*/

    orr r1, r1, #0xc0000000 /*Asynchronous Embest*/

    mcr p15, 0, r1, c1, c0, 0 /*write ctrl register Embest*/

 

    /*now, CPU clock is 202.8 Mhz Embest*/

    mov r1, #CLK_CTL_BASE /* Embest*/

    mov r2, #MDIV_200 /* mpll_200mhz Embest*/

    add r2, r2, #PSDIV_200 /* mpll_200mhz Embest*/

    str r2, [r1, #0x04]

 

#endif    /* CONFIG_S3C2400 || CONFIG_S3C2410 */

 

4)        将从Flash启动改成从NAND Flash启动。

在以下UBoot的重定向语句段:

#ifdef    CONFIG_AT91RM9200

 

#ifndef CONFIG_SKIP_RELOCATE_UBOOT

relocate:                /* relocate U-Boot to RAM     */

    adr    r0, _start        /* r0 <- current position of code */

    ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */

    cmp r0, r1 /* don't reloc during debug */

    beq stack_setup

 

    ldr    r2, _armboot_start

    ldr    r3, _bss_start

    sub    r2, r3, r2        /* r2 <- size of armboot */

    add    r2, r0, r2        /* r2 <- source end address*/

 

copy_loop:

    ldmia     {r3-r10}        /* copy from source address [r0] */

    stmia     {r3-r10}        /* copy to target address [r1] */

    cmp    r0, r2            /* until source end addreee [r2] */

    ble    copy_loop

#endif    /* CONFIG_SKIP_RELOCATE_UBOOT */

#endif

的后面添加上:

#ifdef CONFIG_S3C2410_NAND_BOOT

@ 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

nand1:

  add r3, r3, #0x1

  cmp r3, #0xa

  blt nand1

 

nand2:

  ldr r2, [r1, #oNFSTAT] @ wait ready

  tst r2, #0x1

  beq nand2

 

  ldr r2, [r1, #oNFCONF]

  orr r2, r2, #0x800 @ disable chip

  str r2, [r1, #oNFCONF]

 

@ get read to call C s (for nand_read())

  ldr sp, DW_STACK_START @ setup stack pointer

  mov fp, #0 @ no previous , so fp=0

 

@ copy U-Boot to RAM

  ldr r0, =TEXT_BASE

  mov r1, #0x0

  mov r2, #0x30000

  bl nand_read_ll

  tst r0, #0x0

  beq ok_nand_read

 

bad_nand_read:

loop2: b loop2 @ infinite loop

 

 

ok_nand_read:

@ verify

  mov r0, #0

  ldr r1, =TEXT_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 stack_setup

  bne go_next

 

notmatch:

loop3: b loop3 @ infinite loop

 

#endif @ CONFIG_S3C2410_NAND_BOOT

 

“ldr    pc, _start_armboot”之前加入:

# if defined(CONFIG_edukit2410_LED)

@ LED1 on u-boot stage 1 is

ldr    r0, =0x56000060

ldr    r1, =0xff4af769

str    r1, [r0]

 

ldr    r0, =0x56000068

ldr    r1, =0xffff

str    r1, [r0]

 

ldr    r0, =0x21180000

ldr    r1, =0xfc

strb  r1, [r0]

#endif

//修改目的:如果看到只有LED1亮了,说明U-Boot的第一阶段已完成!

“  _start_armboot:    .word start_armboot  ” 后加入:

.align 2

DW_STACK_START: .word STACK_BASE+STACK_SIZE-4

2.2        创建nandflash读函数

board/Embest/edukit2410加入NAND Flash读函数文件,拷贝vivi中的nand_read.c文件到此文件夹即可:

#include

 

#define __REGb(x) (*(volatile unsigned char *)(x))

#define __REGi(x) (*(volatile unsigned int *)(x))

#define NF_BASE 0x4e000000

 

# if defined(CONFIG_S3C2410)

 

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

}

/* low level nand read */

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;

}

# endif

2.3        修改board/Embest/edukit2410/Makefile文件

......

OBJS := edukit2410.o nand_read.o flash.o

......

2.4        修改include/configs/edukit2410.h文件

1)        在文件末添加如下内容:

......

/*

 * Nandflash Boot

 */

#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

 

# if defined(CONFIG_S3C2410)

#define CONFIG_S3C2410_NAND_BOOT 1

/* Offset */

#define oNFCONF 0x00

#define oNFCMD 0x04

#define oNFADDR 0x08

#define oNFDATA 0x0c

#define oNFSTAT 0x10

#define oNFECC 0x14

#define rNFCONF (*(volatile unsigned int *)0x4e000000)

#define rNFCMD (*(volatile unsigned char *)0x4e000004)

#define rNFADDR (*(volatile unsigned char *)0x4e000008)

#define rNFDATA (*(volatile unsigned char *)0x4e00000c)

#define rNFSTAT (*(volatile unsigned int *)0x4e000010)

#define rNFECC (*(volatile unsigned int *)0x4e000014)

#define rNFECC0 (*(volatile unsigned char *)0x4e000014)

#define rNFECC1 (*(volatile unsigned char *)0x4e000015)

#define rNFECC2 (*(volatile unsigned char *)0x4e000016)

#endif

 

/*JFFS2 Support  */

#undef CONFIG_JFFS2_CMDLINE

#define CONFIG_JFFS2_NAND 1

#define CONFIG_JFFS2_DEV  "nand0"

#define CONFIG_JFFS2_PART_SIZE  0x4c0000

#define CONFIG_JFFS2_PART_OFFSET 0x40000

/*JFFS2 Support  */

 

/* USB Support 080218 */

#define CONFIG_USB_OHCI

#define CONFIG_USB_STORAGE

#define CONFIG_USB_KEYBOARD

#define CONFIG_DOS_PARTITION

#define CFG_DEVICE_DEREGISTER

#define CONFIG_SUPPORT_VFAT

#define LITTLEENDIAN

/* USB Support 080218 */

 

/*yaffs support*/

#define CFG_NAND_YAFFS1_NEW_OOB_LAYOUT  1

#define ENABLE_CMD_NAND_YAFFS 1

#define ENABLE_CMD_NAND_YAFFS_SKIPFB  1

#define CFG_NAND_YAFFS1_NEW_OOB_LAYOUT  1

/*yaffs support*/

 

#endif /* __CONFIG_H */

2)        选择串口端口,使信息能够通过uart1进行打印

因为linux内核中配置的打印端口为uart1

/*

 * select serial console configuration

 */

#define CONFIG_SERIAL2          1       /* we use SERIAL 2(uart1) on edukit */

2.1        修改board/Embest/edukit2410/lowlevel_init.S文件

依照开发板的内存区的配置情况, 修改board/Embest/edukit2410/lowlevel_init.S文件,

......

#define B1_BWSCON          (DW32)

#define B2_BWSCON          (DW16)

#define B3_BWSCON          (DW16+UBLB)

#define B4_BWSCON          (DW16)

#define B5_BWSCON          (DW16)

#define B6_BWSCON          (DW32)

#define B7_BWSCON          (DW32)......

 

……

 

//#define B3_Tacs               0xc

 

//#define B3_Tcos               0x7

 

//#define B3_Tacc               0xf

 

//#define B3_Tcoh                     0x1

 

#define B3_Tacs                 0x0

 

#define B3_Tcos                 0x0

 

#define B3_Tacc                 0x7

 

#define B3_Tcoh                 0x0

 

#define B3_Tah                  0x0

 

#define B3_Tacp                 0x0

 

#define B3_PMC                 0x0

 

......

 

//#define B5_Tacs               0xc

 

//#define B5_Tcos               0x7

 

//#define B5_Tacc               0xf

 

//#define B5_Tcoh                     0x1

 

#define B5_Tacs                 0x0

 

#define B5_Tcos                 0x0

 

#define B5_Tacc                 0x7

 

#define B5_Tcoh                 0x0

 

#define B5_Tah                  0x0

 

#define B5_Tacp                 0x0

 

#define B5_PMC                 0x0

 

......

 

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

 

……

 

.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)

.word 0x32

.word 0x30

.word 0x30

2.2        修改/board/Embest/edukit2410/edukit2410.c

 修改其对GPIOPLL的配置(请参阅开发板的硬件说明和芯片手册)

......

#define FCLK_SPEED 1

 

#if FCLK_SPEED==0        /* Fout = 203MHz, Fin = 12MHz for Audio */

#define M_MDIV    0xC3

#define M_PDIV    0x4

#define M_SDIV    0x1

#elif FCLK_SPEED==1       

 

#if defined(CONFIG_S3C2410)

/* Fout = 202.8MHz */

#define M_MDIV     0xA1

#define M_PDIV     0x3

#define M_SDIV     0x1

#endif

 

#endif

#define USB_CLOCK 1

 

#if USB_CLOCK==0

#define U_M_MDIV    0xA1

#define U_M_PDIV    0x3

#define U_M_SDIV    0x1

#elif USB_CLOCK==1

 

#if defined(CONFIG_S3C2410)

#define U_M_MDIV    0x48

#define U_M_PDIV    0x3

#endif

 

#if defined(CONFIG_S3C2440)

#define U_M_MDIV 0x38

#define U_M_PDIV 0x2

#endif

 

#define U_M_SDIV    0x2

#endif

......

/* set up the I/O ports */

gpio->GPACON = 0x5fbfff;

gpio->GPBCON = 0x155559;

gpio->GPBUP = 0x7ff;

gpio->GPCCON = 0xaaaa55aa;

gpio->GPCUP = 0xffff;

gpio->GPDCON = 0xAAAAAAAA;

gpio->GPDUP = 0x0000FFFF;

gpio->GPECON = 0xa6aaaaaa;

gpio->GPEUP = 0xffff;

//gpio->GPEDATA = 0x2000;

gpio->GPFCON = 0x000055AA;

gpio->GPFUP = 0x000000FF;

#if defined(CONFIG_edukit2410_LED)

gpio->GPGCON = 0xff4af7b9;

gpio->GPGUP = 0xffff;

#else

gpio->GPGCON = 0xFF95FF3A;

gpio->GPGUP = 0x0000FFFF;

#endif

//gpio->GPGDATA = 0xffcf;

gpio->GPHCON = 0x2aaaaa;

gpio->GPHUP = 0x000007FF;

 

gpio->EXTINT0=0x22222222;

gpio->EXTINT1=0x22222222;

gpio->EXTINT2=0x22222222;

 

#if defined(CONFIG_S3C2410)

    /* arch number of SMDK2410-Board */

     gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;

#endif

 

/* adress of boot parameters */

gd->bd->bi_boot_params = 0x30000100;

 

icache_enable();

dcache_enable();

 

# if defined(CONFIG_edukit2410_LED)

    //int board_init (void)设置完成后,LED1和LED2会亮起!

#endif

 

return 0;

}

2.3        为了实现NAND Flash的读写,再次修改/include/configs/edukit2410.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_SBC2410X           1     /* on a friendly-arm SBC-2410X Board  */

#define CONFIG_edukit2410            1

#define CONFIG_edukit2410_LED           1

......

/*

 * Command line configuration.

 */

#include

 

#define CONFIG_CMD_ASKENV

#define CONFIG_CMD_CACHE

#define CONFIG_CMD_DATE

#define CONFIG_CMD_DHCP

#define CONFIG_CMD_ELF

#define CONFIG_CMD_PING

#define CONFIG_CMD_NAND

#define CONFIG_CMD_REGINFO

 

#define CONFIG_CMD_JFFS2

/* JFFS2 Support    080218  */

 

#define CONFIG_CMD_USB

/* USB Support  080218  */

 

#define CONFIG_CMD_FAT

/* FAT support  080218  */

 

......

#define CFG_LONGHELP

/* undef to save memory */

#define CFG_PROMPT "[Edukit2410]#"

/*Monitor Command Prompt */

#define CFG_CBSIZE 256

/* Console I/O Buffer Size */

......

#define CFG_LOAD_ADDR 0x30800000

 /* default load address */

 

......

 

/* 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_NAND 1

#define CFG_ENV_OFFSET 0X30000

#define CFG_NAND_LEGACY

//#define    CFG_ENV_IS_IN_FLASH    1

 

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

 

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

 * NAND flash settings

 */

#if defined(CONFIG_CMD_NAND)

#define CFG_NAND_BASE 0x4E000000

/* NandFlash控制器在SFR区起始寄存器地址 */

#define CFG_MAX_NAND_DEVICE 1

 /* 支持的最在Nand Flash数据 */

#define SECTORSIZE 512

/* 1页的大小 */

#define NAND_SECTOR_SIZE SECTORSIZE

#define NAND_BLOCK_MASK 511

/* 页掩码 */

#define ADDR_COLUMN 1

/* 一个字节的Column地址 */

#define ADDR_PAGE 3

/* 3字节的页块地址!!!!!*/

#define ADDR_COLUMN_PAGE 4

/* 总共4字节的页块地址!!!!! */

#define NAND_ChipID_UNKNOWN 0x00

/* 未知芯片的ID号 */

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

 

/* Nand Flash命令层底层接口函数 */

#define WRITE_NAND_ADDRESS(d, adr) {rNFADDR = d;}

#define WRITE_NAND(d, adr) {rNFDATA = d;}

#define READ_NAND(adr) (rNFDATA)

#define NAND_WAIT_READY(nand) {while(!(rNFSTAT&(1<<0)));}

#define WRITE_NAND_COMMAND(d, adr) {rNFCMD = d;}

#define WRITE_NAND_COMMANDW(d, adr)    NF_CmdW(d)

#define NAND_DISABLE_CE(nand) {rNFCONF |= (1<<11);}

#define NAND_ENABLE_CE(nand) {rNFCONF &= ~(1<<11);}

 

/* the following s 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)

/* 允许Nand Flash写校验 */

#define CONFIG_MTD_NAND_VERIFY_WRITE 1

......

#endif /* __CONFIG_H */

2.1        修改文件/cpu/arm920t/s3c24x0/interrupts.c文件

在个文件中添加“defined(CONFIG_edukit2410)”,使得原来SBC2410X的代码可以编译进来。第181:

#elif defined(CONFIG_SBC2410X) || \

      defined(CONFIG_SMDK2410) || \

      defined(CONFIG_VCMA9) ||defined(CONFIG_edukit2410)

2.2        修改include/linux/mtd/nand_ids.h

在结构体nand_flash_ids加入

static struct nand_flash_dev nand_flash_ids[] = {

......

    {"Samsung K9F1208U0B", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000, 0},

    {NULL,}

};

2.3        修改include/linux/mtd/nand.h

/*

 * Constants for hardware specific CLE/ALE/NCE

*/

#if 0

/* Select the chip by setting nCE to low */

#define NAND_CTL_SETNCE        1

/* Deselect the chip by setting nCE to high */

#define NAND_CTL_CLRNCE        2

/* Select the command latch by setting CLE to high */

#define NAND_CTL_SETCLE        3

/* Deselect the command latch by setting CLE to low */

#define NAND_CTL_CLRCLE        4

/* Select the address latch by setting ALE to high */

#define NAND_CTL_SETALE        5

/* Deselect the address latch by setting ALE to low */

#define NAND_CTL_CLRALE        6

/* Set write protection by setting WP to high. Not used! */

#define NAND_CTL_SETWP        7

/* Clear write protection by setting WP to low. Not used! */

#define NAND_CTL_CLRWP        8

#endif

2.4        修改/lib_arm中的board.c

......

#include

#include

#include

#include

#include

#include

#include

 

......

 

static int display_banner (void)

{

# if defined(CONFIG_edukit2410_LED)    

 

//在串口初始化和console初始化完成,串口输出信息之前,LED1、LED2、LED3会亮起!

 

#endif

    printf ("\n\n%s\n\n", version_string);

    debug ("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n",

           _armboot_start, _bss_start, _bss_end);

#ifdef CONFIG_MODEM_SUPPORT

    debug ("Modem Support enabled\n");

#endif

#ifdef CONFIG_USE_IRQ

    debug ("IRQ Stack: %08lx\n", IRQ_STACK_START);

    debug ("FIQ Stack: %08lx\n", FIQ_STACK_START);

#endif

 

    return (0);

}

 

......

void start_armboot (void)

{

         init_fnc_t **init_fnc_ptr;

         char *s;

#ifndef CFG_NO_FLASH

         ulong size;

#endif

#if defined(CONFIG_VFD) || defined(CONFIG_LCD)

         unsigned long addr;

#endif

# if defined(CONFIG_edukit2410_LED)    

         S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

#endif

......

# if defined(CONFIG_edukit2410_LED)    

 

 

//在进入命令提示符之前,四个LED会同时亮起!

 

#endif

         /* main_loop() can return to retry autoboot, if so just run it again. */

         for (;;) {

                   main_loop ();

         }

 

         /* NOTREACHED - no way out of command loop except booting */

}

 

2.5        修改common/env_nand.c

......

#ifdef CONFIG_INFERNO

#error CONFIG_INFERNO not supported yet

#endif

 

int nand_legacy_rw (struct nand_chip* nand, int cmd,

        size_t start, size_t len,

        size_t * retlen, u_char * buf);

extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];

extern int nand_legacy_erase(struct nand_chip *nand, size_t ofs, size_t len, int clean);

 

/* info for NAND chips, defined in drivers/nand/nand.c */

extern nand_info_t nand_info[CFG_MAX_NAND_DEVICE];

 

......

 

#else /* ! CFG_ENV_OFFSET_REDUND */

int saveenv(void)

{

    ulong total;

    int ret = 0;

 

    puts ("Erasing Nand...");

    //if (nand_erase(&nand_info[0], CFG_ENV_OFFSET, CFG_ENV_SIZE))

if (nand_legacy_erase(nand_dev_desc + 0, CFG_ENV_OFFSET, CFG_ENV_SIZE, 0))

        return 1;

 

 

    puts ("Writing to Nand... ");

    total = CFG_ENV_SIZE;

    //ret = nand_write(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);

 

ret = nand_legacy_rw(nand_dev_desc + 0,

0x00 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE,

&total, (u_char*)env_ptr);

 

    if (ret || total != CFG_ENV_SIZE)

        return 1;

 

    puts ("done\n");

    return ret;

......

#else /* ! CFG_ENV_OFFSET_REDUND */

/*

 * The legacy NAND code saved the environment in the first NAND device i.e.,

 * nand_dev_desc + 0. This is also the behaviour using the new NAND code.

 */

void env_relocate_spec (void)

{

#if !defined(ENV_IS_EMBEDDED)

    ulong total;

    int ret;

 

    total = CFG_ENV_SIZE;

    //ret = nand_read(&nand_info[0], CFG_ENV_OFFSET, &total, (u_char*)env_ptr);

 

    ret = nand_legacy_rw(nand_dev_desc + 0, 0x01 | 0x02, CFG_ENV_OFFSET, CFG_ENV_SIZE, &total, (u_char*)env_ptr);

 

......

2.1        在/board/Embest/edukit2410/edukit2410.c文件的末尾添加对Nand Flash 的初始化函数(在后面Nand Flash的操作都要用到)

u-boot运行至第二阶段进入start_armboot()函数。其中nand_init()函数是对nand flash的最初初始化函数。Nand_init()函数在两个文件中实现。其调用与CFG_NAND_LEGACY宏有关,如果没有定义这个宏,系统调用 drivers/nand/nand.c中的nand_init();否则调用自己在board/Embest/edukit2410/edukit2410.c中的nand_init()函数。这里我选择第二种方式。

#if defined(CONFIG_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_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 u32 NF_Read_ECC(void)

{

    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    return(nand->NFECC);

}

 

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_Init_ECC(void)

{

    S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

    nand->NFCONF |= (1<<12);

}

 

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

#define TACLS 0

#define TWRPH0 3

#define TWRPH1 0

#else

#define TACLS 0

#define TWRPH0 4

#define TWRPH1 2

#endif

 

#if defined(CONFIG_S3C2440)

    NF_Conf((TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4));

    NF_Cont((1<<6)|(1<<4)|(1<<1)|(1<<0));

#else

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

#endif

    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

1        修改U-boot文件,以支持DM9000AEP

由于sbc2410x开发板支持的是cs8900,而EdukitIV使用的是DM9000AEP网卡芯片,所以要如果要实现对与DM9000AEP的支持需要对U-boot的代码做一些适当的修改。

3.1        修改include/configs/edukit2410.h文件

/*

 * Hardware drivers

 */

//#define CONFIG_DRIVER_CS8900 0     /* we have a CS8900 on-board */

//#define CS8900_BASE            0x20100000

//#define CS8900_BUS16          1 /* the Linux driver does accesses as shorts */

#define CONFIG_DRIVER_DM9000 1

#define CONFIG_DM9000_BASE 0x20000000

#define DM9000_IO CONFIG_DM9000_BASE

#define DM9000_DATA 0x20100000

#define CONFIG_DM9000_USE_16BIT

 

#define CONFIG_DM9000_DEBUG

 

......

 

/*修改启动参数,使能通过tftp引导内核,使用yaffs文件系统*/

#define CONFIG_BOOTDELAY    3

#define CONFIG_BOOTARGS           "console=ttySAC1 root=/dev/mtdblock/3 rootfstype=yaffs"

/*使用yaffs文件系统*/

#define CONFIG_ETHADDR         08:00:3e:26:0a:5b

#define CONFIG_NETMASK          255.255.255.0

#define CONFIG_IPADDR           192.168.2.201

/*设置开发板ip地址*/

#define CONFIG_SERVERIP              192.168.2.34

/*设置tftp服务器ip地址*/

/*#define CONFIG_BOOTFILE    "uImage" */

#define CONFIG_BOOTCOMMAND     "tftp 30800000 uImage\; bootm"

EdukitIV中,有两个网卡,分别位于核心板和主板上。

其中:

        主板网卡的I/O地址为:0x20000000data地址为:0x20000000

        核心板网卡的I/O地址为:0x10000000data地址为:0x10000002

3.2        修改lib_arm/board.c文件

......

#ifdef CONFIG_DRIVER_CS8900

extern void cs8900_get_enetaddr (uchar * addr);

#endif

#ifdef CONFIG_DRIVER_DM9000

 extern int eth_init(bd_t *bd);

#endif

 

......

 

#ifdef CONFIG_DRIVER_CS8900

cs8900_get_enetaddr (gd->bd->bi_enetaddr);

#endif

#ifdef CONFIG_DRIVER_DM9000

eth_init(gd->bd);

#endif

 

......

 

3.3        修改drivers\net\dm9000x.c文件

......

/* For module input parameter */

//static int media_mode = DM9000_AUTO;

static int media_mode = DM9000_100MFD; /*use full duplex mode */

static u8 nfloor = 0;

 

......

 

void eth_halt(void);

void eth_halt_true(void);

static int dm9000_probe(void);

 

......

 

#ifdef CONFIG_DM9000_DEBUG

static void

dump_regs(void)

{

        DM9000_DBG("\n");

        DM9000_DBG("NCR   (0x00): %02x\n", DM9000_ior(0));

        DM9000_DBG("NSR   (0x01): %02x\n", DM9000_ior(1));

        DM9000_DBG("TCR   (0x02): %02x\n", DM9000_ior(2));

        DM9000_DBG("TSRI  (0x03): %02x\n", DM9000_ior(3));

        DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4));

        DM9000_DBG("RCR   (0x05): %02x\n", DM9000_ior(5));

        DM9000_DBG("RSR   (0x06): %02x\n", DM9000_ior(6));

//      DM9000_DBG("ISR   (0xFE): %02x\n", DM9000_ior(ISR));

        DM9000_DBG("\n");

}

#endif                          /*  */

 

......

 

int

eth_init(bd_t * bd)

{

        int i, oft, lnk;

 

        DM9000_DBG("eth_init()\n");

 

//      eth_halt_true();

        /* RESET device */

        dm9000_reset();

        dm9000_probe();

 

        /* NIC Type: FASTETHER, HOMERUN, LONGRUN */

//      identify_nic();

 

        /* GPIO0 on pre-activate PHY */

        DM9000_iow(DM9000_GPR, 0x00);   /*REG_1F bit0 activate phyxcer */

 

        /* copy from set_PHY_mode, do not set phy mode */

        DM9000_iow(DM9000_GPCR, 0x01);  /* Let GPIO0 output */

        DM9000_iow(DM9000_GPR, 0x00);   /* Enable PHY */

        /* Set PHY */

//      set_PHY_mode();

 

        /* Program operating register */

//      DM9000_iow(DM9000_NCR, 0x0);    /* only intern phy supported by now */

 

 

        DM9000_iow(DM9000_TCR, 0);      /* TX Polling clear */

        DM9000_iow(DM9000_BPTR, 0x3f);  /* Less 3Kb, 200us */

        DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8));   /* Flow Control : High/Low Water */

        DM9000_iow(DM9000_FCR, 0x0);    /* SH FIXME: This looks strange! Flow Control */

        DM9000_iow(DM9000_SMCR, 0);     /* Special Mode */

        DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);   /* clear TX status */

        DM9000_iow(DM9000_ISR, 0x0f);   /* Clear interrupt status */

 

        /* Set Node address */

//      for (i = 0; i < 6; i++)

//              ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);

 

        if (is_zero_ether_addr(bd->bi_enetaddr) ||

            is_multicast_ether_addr(bd->bi_enetaddr)) {

 

......

 

#if 0  

        i = 0;

        while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */

                udelay(1000);

                i++;

                if (i == 10000) {

                        printf("could not establish link\n");

                        return 0;

                }

        }

#endif

#if 0

        /* see what we've got */

        lnk = phy_read(17) >> 12;

        printf("operating at ");

        switch (lnk) {

        case 1:

                printf("10M half duplex ");

                break;

        case 2:

                printf("10M full duplex ");

                break;

        case 4:

                printf("100M half duplex ");

                break;

        case 8:

                printf("100M full duplex ");

                break;

        default:

                printf("unknown: %d ", lnk);

                break;

        }

        printf("mode\n");

#endif

       printf("operating at 100M full duplex mode\n");

        return 0;

}

 

......

 

/*

  Stop the interface.

  The interface is stopped when it is brought.

*/

void eth_halt(void){}

 

void

eth_halt_true(void)

{

        DM9000_DBG("eth_halt\n");

 

        /* RESET devie */

        phy_write(0, 0x8000);   /* PHY RESET */

        DM9000_iow(DM9000_GPR, 0x01);   /* Power-Down PHY */

        DM9000_iow(DM9000_IMR, 0x80);   /* Disable all interrupt */

        DM9000_iow(DM9000_RCR, 0x00);   /* Disable RX */

}

 

......

 

        /* Check packet ready or not */

        DM9000_ior(DM9000_MRRH);

        DM9000_ior(DM9000_MRRL);        //must add this two read

        DM9000_ior(DM9000_MRCMDX);      /* Dummy read */

        rxbyte = DM9000_inb(DM9000_DATA);       /* Got most updated data */

 

        /* Status check: this byte must be 0 or 1 */

        if (rxbyte > 1) {

                DM9000_iow(DM9000_RCR, 0x00);   /* Stop Device */

                DM9000_iow(DM9000_ISR, 0x80);   /* Stop INT request */

                DM9000_DBG("rx status check: %d\n", rxbyte);

                return;

        }

 

......

 

/*

   Read a word from phyxcer

*/

static u16

phy_read(int reg)

{

        u16 val;

 

        /* Fill the phyxcer register into REG_0C */

        DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);

        DM9000_iow(DM9000_EPCR, 0xc);   /* Issue phyxcer read command */

//      udelay(100);            /* Wait read complete */        //weiyan

        udelay(1000);           /* Wait read complete */

        DM9000_iow(DM9000_EPCR, 0x0);   /* Clear phyxcer read command */

        val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);

 

        /* The read data keeps on REG_0D & REG_0E */

        DM9000_DBG("phy_read(%d): %d\n", reg, val);

        return val;

}

 

/*

   Write a word to phyxcer

*/

static void

phy_write(int reg, u16 value)

{

        /* Fill the phyxcer register into REG_0C */

        DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);

 

        /* Fill the written data into REG_0D & REG_0E */

        DM9000_iow(DM9000_EPDRL, (value & 0xff));

        DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));

        DM9000_iow(DM9000_EPCR, 0xa);   /* Issue phyxcer write command */

//      udelay(500);            /* Wait write complete */ /

        udelay(1000);           /* Wait write complete */

        DM9000_iow(DM9000_EPCR, 0x0);   /* Clear phyxcer write command */

        DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value);

}

#endif                          /* CONFIG_DRIVER_DM9000 */

4     修改U-boot文件,添加LCD驱动

4.1        驱动lcd,并刷屏

1)修改include/configs/edukit2410.h文件

#define CONFIG_DRIVER_LCD

/*suport LCD*/

#endif     /* __CONFIG_H */

2)添加LCD驱动及初始化函数

/board/Embest/edukit2410/目录下建立文件,命名为lcd.c,并将以下代码拷贝到该文件中。

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

* File?? lcdapp.c

* Author:       Embest 

* Desc??      LCD_Test

* History:      

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

 

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

/*                                                            include files                                                                     */

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

 

//#include "2410lib.h"

//#include "lcdlib.h"

#define UINT32T unsigned int

#define INT16T     short int

#define UINT8T  unsigned char

 

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

/*                                                            constant define                                                                      */

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

#define LCD_BUF_SIZE             (SCR_XSIZE_TFT_640480*SCR_YSIZE_TFT_640480/2)

#define LCD_ACTIVE_BUFFER    (0x33800000)

#define LCD_VIRTUAL_BUFFER  (0x33800000 + LCD_BUF_SIZE)

#define LCD_D_OFF                  rGPCDAT &= ~(1 << 4);

#define LCD_D_ON                   rGPCDAT |= (1 << 4);

#define MODE_TFT_16BIT_640480    (0x4204)

 

//Timing parameter for V16C6448AB(PRIME VIEW)

#define VBPD_640480        ((33-1)&0xff)

#define VFPD_640480        ((10-1)&0xff)

#define VSPW_640480              ((2-1) &0x3f)

#define HBPD_640480              ((48-1)&0x7f)

#define HFPD_640480        ((16-1)&0xff)

#define HSPW_640480             ((96-1)&0xff)

 

#define MVAL        (13)

#define MVAL_USED    (0)

#define M5D(n) ((n) & 0x1fffff)                                 // To get lower 21bits

 

#define CLKVAL_TFT_640480   (1)

    //53.5hz @90Mhz

    //VSYNC,HSYNC should be inverted

#ifndef CONFIG_LCD_BMP 

extern const UINT8T g_ucBitmap[][76800];

#endif    //HBPD=47VCLK,HFPD=15VCLK,HSPW=95VCLK

    //VBPD=32HSYNC,VFPD=9HSYNC,VSPW=1HSYNC

 

#define LCDFRAMEBUFFER 0x31000000 //_NONCACHE_STARTADDRESS

    // 1. The LCD frame buffer should be write-through or non-cachable.

    // 2. The total frame memory should be inside 4MB.

    // 3. To meet above 2 conditions, the frame buffer should be

    // inside the following regions.

    // 0x31000000~0x313ffffff,

    // 0x31400000~0x317ffffff,

    // 0x31800000~0x31bffffff,

    //        .....   

    // 0x33800000~0x33bffffff       

 

// LCD CONTROLLER

#define rLCDCON1    (*(volatile unsigned *)0x4d000000) //LCD control 1

#define rLCDCON2    (*(volatile unsigned *)0x4d000004) //LCD control 2

#define rLCDCON3    (*(volatile unsigned *)0x4d000008) //LCD control 3

#define rLCDCON4    (*(volatile unsigned *)0x4d00000c) //LCD control 4

#define rLCDCON5    (*(volatile unsigned *)0x4d000010) //LCD control 5

#define rLCDSADDR1  (*(volatile unsigned *)0x4d000014) //STN/TFT Frame buffer start address 1

#define rLCDSADDR2  (*(volatile unsigned *)0x4d000018) //STN/TFT Frame buffer start address 2

#define rLCDSADDR3  (*(volatile unsigned *)0x4d00001c) //STN/TFT Virtual screen address set

#define rREDLUT     (*(volatile unsigned *)0x4d000020) //STN Red lookup table

#define rGREENLUT   (*(volatile unsigned *)0x4d000024) //STN Green lookup table

#define rBLUELUT    (*(volatile unsigned *)0x4d000028) //STN Blue lookup table

#define rDITHMODE   (*(volatile unsigned *)0x4d00004c) //STN Dithering mode

#define rTPAL       (*(volatile unsigned *)0x4d000050) //TFT Temporary palette

#define rLCDINTPND  (*(volatile unsigned *)0x4d000054) //LCD Interrupt pending

#define rLCDSRCPND  (*(volatile unsigned *)0x4d000058) //LCD Interrupt source

#define rLCDINTMSK  (*(volatile unsigned *)0x4d00005c) //LCD Interrupt mask

#define rLPCSEL     (*(volatile unsigned *)0x4d000060) //LPC3600 Control

#define PALETTE     0x4d000400                         //Palette start address

 

 

#define rGPCCON    (*(volatile unsigned *)0x56000020) //Port C control

#define rGPCDAT    (*(volatile unsigned *)0x56000024) //Port C data

#define rGPCUP     (*(volatile unsigned *)0x56000028) //Pull-up control C

                       

#define rGPDCON    (*(volatile unsigned *)0x56000030) //Port D control

#define rGPDDAT    (*(volatile unsigned *)0x56000034) //Port D data

#define rGPDUP     (*(volatile unsigned *)0x56000038) //Pull-up control D

 

#define rGPGCON    (*(volatile unsigned *)0x56000060) //Port G control

#define rGPGDAT    (*(volatile unsigned *)0x56000064) //Port G data

#define rGPGUP     (*(volatile unsigned *)0x56000068) //Pull-up control G

 

#define LCD_XSIZE_TFT_640480     (640)     

#define LCD_YSIZE_TFT_640480     (480)

#define HOZVAL_TFT_640480   (LCD_XSIZE_TFT_640480-1)

#define LINEVAL_TFT_640480   (LCD_YSIZE_TFT_640480-1)

#define SCR_XSIZE_TFT_640480     (LCD_XSIZE_TFT_640480*2)

#define SCR_YSIZE_TFT_640480     (LCD_YSIZE_TFT_640480*2)

 

UINT32T (*frameBuffer16BitTft640480)[SCR_XSIZE_TFT_640480/2];

void (*PutPixel)(UINT32T,UINT32T,UINT32T);

void (*BitmapView)(UINT8T *pBuffer);

void BitmapViewTft16Bit_640480(UINT8T *pBuffer);

extern void Lcd_port_init(void);

extern void Lcd_Port_Return(void);

unsigned save_rGPCUP,save_rGPCDAT,save_rGPCCON;

unsigned save_rGPDUP,save_rGPDDAT,save_rGPDCON;

 

void Lcd_port_init(void)

{

    save_rGPCCON=rGPCCON;

    save_rGPCDAT=rGPCDAT;

    save_rGPCUP=rGPCUP;

    save_rGPDCON=rGPDCON;

    save_rGPDDAT=rGPDDAT;

    save_rGPDUP=rGPDUP;

    rGPCUP=0xffffffff;                                          // Disable Pull-up register

   // rGPCCON=0xaaaaa9aa;                                         // Initialize VD[7:0],LCDVF[2:0],VM,VFRAME,VLINE,VCLK,LEND

    rGPCCON=0xaaaaaaaa; 

rGPDUP=0xffffffff;                                          // Disable Pull-up register

    rGPDCON=0xaaaaaaaa;                                         // Initialize VD[23:8]

  //  uart_printf(" Initializing GPIO ports..........\n");

}

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

* name:         Lcd_Port_Return()

* func:           Return lcd port configuration

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

void Lcd_Port_Return(void)

{

    rGPCCON=save_rGPCCON;

    rGPCDAT=save_rGPCDAT;

    rGPCUP=save_rGPCUP;

    rGPDCON=save_rGPDCON;

    rGPDDAT=save_rGPDDAT;

    rGPDUP=save_rGPDUP;

}

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

* name:         _PutTft16Bit_640480()

* func:           put pixel to 16bpp 640*480 TFT

* para:           UINT32T x   --  x coordinate

*           UINT32T y   --  y coordinate

*           UINT32T c   --  color value         

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

void _PutTft16Bit_640480(UINT32T x,UINT32T y,UINT32T c)

{

    if(x

      frameBuffer16BitTft640480[(y)][(x)/2]=( frameBuffer16BitTft640480[(y)][x/2]

        & ~(0xffff0000>>((x)%2)*16) ) | ( (c&0x0000ffff)<<((2-1-((x)%2))*16) );                     

}

 

 

void Lcd_Init(int type)

{

   

frameBuffer16BitTft640480=(UINT32T (*)[SCR_XSIZE_TFT_640480/2])LCDFRAMEBUFFER;

        rLCDCON1=(CLKVAL_TFT_640480<<8)|(MVAL_USED<<7)|(3<<5)|(12<<1)|0;

           

        // TFT LCD panel,16bpp TFT,ENVID=off

        rLCDCON2=(VBPD_640480<<24)|(LINEVAL_TFT_640480<<14)|(VFPD_640480<<6)|(VSPW_640480);

        rLCDCON3=(HBPD_640480<<19)|(HOZVAL_TFT_640480<<8)|(HFPD_640480);

        rLCDCON4=(MVAL<<8)|(HSPW_640480);

        rLCDCON5=(1<<11)|(1<<9)|(1<<8);                     //FRM5:6:5,HSYNC and VSYNC are inverted

        rLCDSADDR1=(((UINT32T)frameBuffer16BitTft640480>>22)<<21)|M5D((UINT32T)frameBuffer16BitTft640480>>1);

        rLCDSADDR2=M5D( ((UINT32T)frameBuffer16BitTft640480+(SCR_XSIZE_TFT_640480*LCD_YSIZE_TFT_640480*2))>>1 );

        rLCDSADDR3=(((SCR_XSIZE_TFT_640480-LCD_XSIZE_TFT_640480)/1)<<11)|(LCD_XSIZE_TFT_640480/1);

        rLCDINTMSK|=(3);                                    // MASK LCD Sub Interrupt

        rLPCSEL&=(~7);                                      // Disable LPC3600

        rTPAL=0;                                            // Disable Temp Palette

      

}

 

void Glib_Init(int type)

PutPixel=_PutTft16Bit_640480;

BitmapView=BitmapViewTft16Bit_640480;       

}

 

void Glib_ClearScr(UINT32T c, int type)

{     

    int i,j;

 

 // type:MODE_TFT_1BIT_640480|MODE_TFT_8BIT_640480|MODE_TFT_16BIT_640480

        for(j=0;j<20;j++)

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

                PutPixel(i,j,c);

 

 

}

 

void Lcd_PowerEnable(int invpwren,int pwren)

{

    //GPG4 is setted as LCD_PWREN

    rGPGUP=rGPGUP&(~(1<<4))|(1<<4);                             // Pull-up disable

    rGPGCON=rGPGCON&(~(3<<8))|(3<<8);                           // GPG4=LCD_PWREN

   

    //Enable LCD POWER ENABLE Function

    rLCDCON5=rLCDCON5&(~(1<<3))|(pwren<<3);                     // PWREN

    rLCDCON5=rLCDCON5&(~(1<<5))|(invpwren<<5);                  // INVPWREN

 

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

* name:         Lcd_EnvidOnOff

* func:           lcd Envid onoff configuration

* para:           int onoff   --  Envid configuration

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

void Lcd_EnvidOnOff(int onoff)

{

    if(onoff==1)

      rLCDCON1|=0x00000001;                                            // ENVID=ON            

else

      rLCDCON1 =rLCDCON1 & 0x3fffe;                           // ENVID Off

 

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

* name:         lcd_init_app

* func:           lcd application initialization code

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

void lcd_init_app()

{

    Lcd_port_init();

    Lcd_Init(MODE_TFT_16BIT_640480);

    Glib_Init(MODE_TFT_16BIT_640480);

    Glib_ClearScr(0, MODE_TFT_16BIT_640480);

    Lcd_PowerEnable(0, 1);

    Lcd_EnvidOnOff(1);        

}

 

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

* name:         lcd_init_app_end

* func:           end lcd application initialization    

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

void lcd_init_app_end()

{

    Lcd_EnvidOnOff(0);

    Lcd_Port_Return();

}

 

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

* name:         lcd_clr_rect

* func:           fill appointed area with appointed color

* para:           usLeft,usTop,usRight,usBottom -- area's rectangle acme coordinate

*                    ucColor -- appointed color value

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

void lcd_clr_rect(INT16T usLeft, INT16T usTop, INT16T usRight, INT16T usBottom, UINT8T ucColor)

{

UINT32T i, j;

//      UINT8T *pDisp = (UINT8T*)LCD_ACTIVE_BUFFER;

for (i = usLeft; i < usRight; i++)

for (j = usTop; j < usBottom; j++)

{

        PutPixel(i,j,ucColor);

        //*(pDisp+i+j) = ucColor;

}

}

 

 

void lcd_clean(UINT32T c)

{

      UINT32T i, j;

UINT32T *pView = (UINT32T*)frameBuffer16BitTft640480;

 

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

{

  

  

   for (j = 0; j < LCD_XSIZE_TFT_640480/2 ; j++)

    {

     

      //pView[j] = ((*(pBuffer+3)) << 24) + ((*(pBuffer+2)) << 16) + ((*(pBuffer+1)) << 8) + (*(pBuffer));

        pView[j] = c;

          //pBuffer += 4;

   

              }

    pView+=LCD_XSIZE_TFT_640480;

}

 

   

}

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

* name:         color_lcd_test()

* func:           LCD test function      

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

void color_lcd_init(void)

{

      printf("lcd initial start\n");

lcd_init_app();   

lcd_clean(0x66665555);

printf("lcd initial end\n");  

}

移植uboot1.3.1到s3c2410(8)--lcd支持 (2009-07-30 17:36)分类: Bootloader相关

3)修改/board/Embest/edukit2410/Makefile文件

将lcd.c加入编译。

LIB   = $(obj)lib$(BOARD).a

 

COBJS     := edukit2410.o nand_read.o lcd.o flash.o

SOBJS     := lowlevel_init.o

4)修改/lib_arm/board.c文件

......

#ifdef CONFIG_HAS_DATAFLASH

extern int  AT91F_DataflashInit(void);

extern void dataflash_print_info(void);

#endif

 

#ifdef CONFIG_DRIVER_LCD

    extern void color_lcd_init(void);

#endif

 

#ifndef CONFIG_IDENT_STRING

#define CONFIG_IDENT_STRING ""

#endif

 

......

 

#if defined(CONFIG_DRIVER_LCD)

color_lcd_init();

#endif

/* main_loop() can return to retry autoboot, if so just run it again. */

for (;;) {

        main_loop ();

}

 

/* NOTREACHED - no way out of command loop except booting */

}

4.1        驱动lcd,并显示图片

如果要进一步显示图片需要在第一步的基础上进行修改。

1)修改include/configs/edukit2410.h文件

#define CONFIG_DRIVER_LCD

/*suport LCD*/

#define CONFIG_LCD_BMP

#endif    /* __CONFIG_H */

2)添加图片信息文件bmp.c

图片以数组的方式存储,数组名为g_ucBitmap[],大小自己定义,但要少于800K

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

* File?? bmp_data.c

* Author:       Embest 

* Desc??      bmp data

* History:      

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

 

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

/*                                                            global variables                                                              */

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

const unsigned char g_ucBitmap[614408] = { 0X00,0X10,0X80,0X02,0XE0,0X01,0X01,0X1B,

0X04,0X08,0X04,0X08,0X04,0X08,0X04,0X08,0X04,0X08,0X04,0X08,0X04,0X08,0X05,0X08,

0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X04,0X08,0X04,0X08,0X04,0X08,

0X04,0X08,0X04,0X08,0X04,0X08,0X04,0X08,0X04,0X08,0X04,0X08,0X04,0X08,0X04,0X08,

0X04,0X08,0X04,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,

0X04,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X04,0X08,0X05,0X08,0X05,0X08,

0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,

0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X05,0X08,0X25,0X08,0X25,0X08,0X25,0X08,

......

}

3)修改/board/Embest/edukit2410/Makefile文件

bmp.c加入编译。

 

LIB   = $(obj)lib$(BOARD).a

 

COBJS     := edukit2410.o nand_read.o lcd.o bmp.o flash.o

SOBJS     := lowlevel_init.o

4)修改/board/Embest/edukit2410/lcd.c,添加图片显示函数。

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

/*                                                            extern variables                                                              */

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

 

 

extern const UINT8T g_ucBitmap[][76800];

 

 

......

 

void lcd_clr_rect(INT16T usLeft, INT16T usTop, INT16T usRight, INT16T usBottom, UINT8T ucColor)

{

UINT32T i, j;

//      UINT8T *pDisp = (UINT8T*)LCD_ACTIVE_BUFFER;

for (i = usLeft; i < usRight; i++)

for (j = usTop; j < usBottom; j++)

{

        PutPixel(i,j,ucColor);

        //*(pDisp+i+j) = ucColor;

}

}

 

 

void BitmapViewTft16Bit_640480(UINT8T *pBuffer)

{

      UINT32T i, j,t=0;

UINT32T *pView = (UINT32T*)frameBuffer16BitTft640480;

 

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

{

  

  

   for (j = 0; j < LCD_XSIZE_TFT_640480/2 ; j++)

    {

     

           pView[j] = ((*(pBuffer+3)) << 24) + ((*(pBuffer+2)) << 16) + ((*(pBuffer+1)) << 8) + (*(pBuffer));

        //pView[j] = 0x88888888;

        pBuffer += 4;

   

              }

    pView+=LCD_XSIZE_TFT_640480;

       }

}

 

......

 

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

* name:         color_lcd_init()

* func:           LCD test function

* para:           none

* ret:             none

* modify:

* comment:          

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

void color_lcd_init(void)

{

      printf("lcd initial start\n");

lcd_init_app();   

lcd_clean(0x66665555);

 

BitmapViewTft16Bit_640480((UINT8T *)(g_ucBitmap));     

 

printf("lcd initial end\n");

}

5)修改/cpu/arm920t/start.S,以支持更大的u-boot自我拷贝

......

 

@ copy U-Boot to RAM

   ldr r0, =TEXT_BASE

  mov r1, #0x0

 

#ifdef CONFIG_LCD_BMP

  mov r2, #0x100000

#else

  mov r2, #0x30000

#endif

......

移植uboot1.3.1到s3c2410(9)--编译并下载u-boot (2009-08-07 15:28)分类: Bootloader相关

5     编译并下载uboot

5.1        编译u-boot

$make distclean

$make edukit2410_config

$make

编译成功之后,在当前目录下会生成uboot.bin文件。

5.2        下载u-boot

这里我们采用powericeuboot.bin下载到nandflash0偏移处。

烧写完成后,运行minicom,显示串口输出信息:

U-Boot 1.3.1 (Nov 29 2008 - 15:21:16)                                          

DRAM:  64 MB                                                                    

Flash:  1 MB                                                                   

NAND:  NAND flash probing at 0x4E000000                                        

 64 MB                                                                        

In:    serial                                                                  

Out:   serial                                                                  

Err:   serial                                                                  

dm9000 i/o: 0x20000000, id: 0x90000a46                                         

MAC: 08:00:3e:26:0a:5b                                                         

operating at 100M full duplex mode                                             

lcd initial start                                                               

lcd initial end                                                                

Hit any key to stop autoboot:  0 

[ edukit2410]#

按任意键终止自动运行模式。

5.3        使用u-boot自更新

1)更新不带图片显示的u-boot.bin

(1)           将编译生成的u-boot.bin拷贝到处tftp目录下面。

(2)           将u-boot.bin下载到sdram中间

[ edukit2410]# tftp 30000000 u-boot.bin                                         

(3)           擦除nandflash,起始地址为0,大小为0x30000

[ edukit2410]# nand erase 0 30000                                                                                                                             

(4)           将u-boot.bin固化到nandflash中

[ edukit2410]# nand write 30000000 0 30000

2)更新不带图片显示的u-boot.bin

(1)        将编译生成的u-boot.bin拷贝到处tftp目录下面。

(2)        将u-boot.bin下载到sdram中间

[ edukit2410]# tftp 30000000 u-boot.bin                                         

(3)        擦除nandflash,起始地址为0,大小为0x100000

[ edukit2410]# nand erase 0 100000                                                                                                                             

(4)        将u-boot.bin固化到nandflash中

[ edukit2410]# nand write 30000000 0 100000

移植uboot1.3.1到s3c2410(10)--使用uboot引导内核 (2009-08-07 15:32)分类: Bootloader相关

6        使用uboot下载引导内核

6.1        制作uImage(在tftp目录下存在zImage文件)

~/u-boot-1.3.1$ sudo cp tools/mkimage /usr/bin/

~/u-boot-1.3.1$ cd /home/example/tftp/

$ ./mkimage -A arm -O linux -T kernel -C none -a 30080000 -e 30080000 -n linux-2.6.14.1_ds9000 -d zImage uImage

Image Name:   linux-2.6.14.1_ds9000

Created:      Sat Nov 29 16:21:35 2008

Image Type:   ARM Linux Kernel Image (uncompressed)

Data Size:    1785268 Bytes = 1743.43 kB = 1.70 MB

Load Address: 0x30080000

Entry Point:  0x30080000

6.2        查看u-boot支持命令

[ edukit2410]# help

6.3        查看启动参数是否配置正确

[ edukit2410]# printenv

bootdelay=3                                                                     

baudrate=115200                                                                 

ethaddr=08:00:3e:26:0a:5b                                                       

netmask=255.255.255.0                                                           

ipaddr=192.168.2.199                                                            

serverip=192.168.2.34                                                           

bootargs=console=ttySAC1 root=/dev/mtdblock/3 rootfstype=yaffs                 

bootcmd=tftp 30800000 uImage                                                

stdin=serial                                                                    

stdout=serial                                                                   

stderr=serial                                                                                                                                        

Environment size: 256/65532 bytes 

如果要修改参数请使用setenv命令。比如要设置新的ipaddr

[ edukit2410]# setenv ipaddr 192.168.2.199                                      

[ edukit2410]# saveenv                                                          

Saving Environment to NAND...                                                   

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

[ edukit2410]#

6.4        下载uImage到指定位置,并启动内核

[ edukit2410]# tftp 30800000 uImage                                             

dm9000 i/o: 0x20000000, id: 0x90000a46                                         

MAC: 08:00:3e:26:0a:5b                                                         

operating at 100M full duplex mode                                             

TFTP from server 192.168.2.34; our IP address is 192.168.2.199                 

Filename 'uImage'.                                                             

Load address: 0x30800000                                                       

Loading: ##########################################################################################################  ###############################################################################################################################################################

done                                                                            

Bytes transferred = 1785332 (1b3df4 hex) 

[ edukit2410]# bootm

这样就完成了利用uboot下载并引导内核。

http://blogimg.chinaunix.net/blog/upfile2/090807160102.rar