鲁班锁八角球解法:移植uboot1.3.1到s3c2410
1 在U-Boot中建立自己的开发板类型,并测试编译
开发板取名叫: edukit2410。
开发板基本配置:
处理芯器片 : S
NANDFLASH:K
NorFLASH: AM29LV160DB
网卡芯片: DM9000AEP
SDRAM: HY57V561620
LCD: LQ080V3DG01 TFT
移植u-boot版本:
U-boot: u-boot
1) 在工作目录下解压U-Boot
$ tar -xjvf u-boot-
2)进入U-Boot目录,修改Makefile
$ cd u-boot-
$ kwrite Makefile
#为edukit2410建立编译项(建议从sbc2410_config复制后做相应的修改)。
sbc2410x_config: unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t sbc2410x NULL s
edukit2410_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm920t edukit2410 Embest s
各项的意思如下:
arm: CPU的架构(ARCH);
arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录;
edukit2410: 开发板的型号(BOARD),对应于board/Embest/edukit2410目录;
Embest: 开发者/或经销商(vender);
s
设置交叉编译工具。
$ source /usr/crosstool/gcc-
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: *** 遗漏分隔符 。 停止。
请在U-boot的根目录下的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
#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启动。
在以下U-Boot的重定向语句段:
#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
修改其对GPIO和PLL的配置(请参阅开发板的硬件说明和芯片手册):
......
#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);
}
#endif1 修改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地址为:0x20000000,data地址为:0x20000000。
核心板网卡的I/O地址为:0x10000000,data地址为: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"); 将lcd.c加入编译。 LIB = $(obj)lib$(BOARD).a COBJS := edukit2410.o nand_read.o lcd.o flash.o SOBJS := lowlevel_init.o ...... #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 */ } 如果要进一步显示图片需要在第一步的基础上进行修改。 #define CONFIG_DRIVER_LCD /*suport LCD*/ #define CONFIG_LCD_BMP #endif /* __CONFIG_H */ 图片以数组的方式存储,数组名为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, ...... } 将bmp.c加入编译。 LIB = $(obj)lib$(BOARD).a COBJS := edukit2410.o nand_read.o lcd.o bmp.o flash.o SOBJS := lowlevel_init.o /*------------------------------------------------------------------------------------------*/ /* 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"); } ...... @ copy U-Boot to RAM ldr r0, =TEXT_BASE mov r1, #0x0 #ifdef CONFIG_LCD_BMP mov r2, #0x100000 #else mov r2, #0x30000 #endif $make distclean $make edukit2410_config $make 编译成功之后,在当前目录下会生成u-boot.bin文件。 这里我们采用powerice将u-boot.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]# 按任意键终止自动运行模式。 [ edukit2410]# tftp 30000000 u-boot.bin [ edukit2410]# nand erase 0 30000 [ edukit2410]# nand write 30000000 0 30000 [ edukit2410]# tftp 30000000 u-boot.bin [ edukit2410]# nand erase 0 100000 [ edukit2410]# nand write 30000000 0 100000 ~/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 [ edukit2410]# help [ 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]# [ 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 这样就完成了利用u-boot下载并引导内核。 http://blogimg.chinaunix.net/blog/upfile2/090807160102.rar
移植uboot1.3.1到s3c2410(8)--lcd支持 (2009-07-30 17:36)分类: Bootloader相关3)修改/board/Embest/edukit2410/Makefile文件
4)修改/lib_arm/board.c文件
4.1 驱动lcd,并显示图片
1)修改include/configs/edukit2410.h文件
2)添加图片信息文件bmp.c
3)修改/board/Embest/edukit2410/Makefile文件
4)修改/board/Embest/edukit2410/lcd.c,添加图片显示函数。
5)修改/cpu/arm920t/start.S,以支持更大的u-boot自我拷贝
移植uboot1.3.1到s3c2410(9)--编译并下载u-boot (2009-08-07 15:28)分类: Bootloader相关5 编译并下载u-boot
5.1 编译u-boot
5.2 下载u-boot
5.3 使用u-boot自更新
1)更新不带图片显示的u-boot.bin
(1) 将编译生成的u-boot.bin拷贝到处tftp目录下面。
(2) 将u-boot.bin下载到sdram中间
(3) 擦除nandflash,起始地址为0,大小为0x30000
(4) 将u-boot.bin固化到nandflash中
2)更新不带图片显示的u-boot.bin
(1) 将编译生成的u-boot.bin拷贝到处tftp目录下面。
(2) 将u-boot.bin下载到sdram中间
(3) 擦除nandflash,起始地址为0,大小为0x100000
(4) 将u-boot.bin固化到nandflash中
6 使用u-boot下载引导内核
6.1 制作uImage(在tftp目录下存在zImage文件)
6.2 查看u-boot支持命令
6.3 查看启动参数是否配置正确
6.4 下载uImage到指定位置,并启动内核