分类: LINUX
2009-05-09 12:50:38
环境变量设置:
环境变量: export PATH=$PATH:/opt/crosstool/gcc-
编译命令
Make linux2410_config
Make CROSS_COMPILE=arm-linux-
修改顶层Makefile
(1) 在顶层Makefile 中为开发板添加新的配置选项,使用已有的配置项目为例:
smdk2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s
linux2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t linux2410x NULL s
创建开发板目录
在board 目录创建linux2410 用于存放开发板相关的代码
# cd ./board
# mkdir linux2410
# cp -r smdk2410 linux2410
修改board/linux2410/Makefile
将OBJS :=smdk2410.o flash.o 修改为OBJS := linux2410.o flash.o
为开发板添加新的配置文件
cp include/configs/smdk2410.h include/configs/linux2410.h
修改lowlevel_init.S文件
修改board/linux2410x/lowlevel_init.S文件
将#define B1_BWSCON (DW16) /* DW32改为DW16 */
在board/linux2410/中添加nand_read.c文件:
#include
#include "linux/mtd/mtd.h"
#include "linux/mtd/nand.h"
//#define LARGEPAGE_FLASH
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE 0x4e000000
#define NFCONF __REGi(NF_BASE + 0x0)
#define NFCMD __REGb(NF_BASE + 0x4)
#define NFADDR __REGb(NF_BASE + 0x8)
#define NFDATA __REGb(NF_BASE + 0xc)
#define NFSTAT __REGb(NF_BASE + 0x10)
#define BUSY 1
inline void wait_idle(void) {
int i;
while(!(NFSTAT & BUSY))
for(i=0; i<10; i++);
}
#ifndef LARGEPAGE_FLASH
#define NAND_SECTOR_SIZE 512
#else
#define NAND_SECTOR_SIZE 2048
#endif
#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
/* low level nand read function */
int
nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
{
int i, j;
if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)){
//if ((start_addr & NAND_BLOCK_MASK) /*|| (size > SZ_
return -1; /* invalid alignment */
}
/* chip Enable */
NFCONF &= ~0x800;
for(i=0; i<10; i++);
for(i=start_addr; i < (start_addr + size);) {
/* READ0 */
NFCMD = NAND_CMD_READ0;
/* Write Address */
#ifndef LARGEPAGE_FLASH
NFADDR = i & 0xff;
NFADDR = (i >> 9) & 0xff;
NFADDR = (i >> 17) & 0xff;
NFADDR = (i >> 25) & 0xff;
#else
NFADDR = i & 0xff;
NFADDR = (i >> 8) & 0x07;
NFADDR = (i >> 11) & 0xff;
NFADDR = (i >> 19) & 0xff;
NFADDR = (i >> 27) & 0x3;
NFCMD = NAND_CMD_READSTART;
#endif
wait_idle();
for(j=0; j < NAND_SECTOR_SIZE; j++) {
*buf = (NFDATA & 0xff);
buf++;
}
i += NAND_SECTOR_SIZE;
}
/* chip Disable */
NFCONF |= 0x800; /* chip disable */
return 0;
修改board/linux2410/Makefile
修改为:OBJS := linux2410.o flash.o nand_read.o
在cpu/arm920t/start.s中修改如下
在 ldr pc, _start_armboot之前加入
#ifdef CONFIG_S
bl copy_myself
@ jump to ram
ldr r1, =on_the_ram
add pc, r1, #0
nop
nop
1: b 1b @ infinite loop
on_the_ram:
#endif
在 _start_armboot: .word start_armboot之后加入
#ifdef CONFIG_S
copy_myself:
mov r10, lr
@ reset NAND
mov r1, #NAND_CTL_BASE
ldr r2, =0xf830 @ initial value
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
bic r2, r2, #0x800 @ enable chip
str r2, [r1, #oNFCONF]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait
1:add r3, r3, #0x1
cmp r3, #0xa
blt 1b
2:ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x1
beq 2b
ldr r2, [r1, #oNFCONF]
orr r2, r2, #0x800 @ disable chip
str r2, [r1, #oNFCONF]
@ get read to call C functions (for nand_read())
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0
@ copy vivi to RAM
ldr r0, =UBOOT_RAM_BASE
mov r1, #0x0
mov r2, #0x20000
bl nand_read_ll
tst r0, #0x0.align 2
DW_STACK_START:
.word STACK_BASE+STACK_SIZE-4
beq ok_nand_read
#ifdef CONFIG_DEBUG_LL
bad_nand_read:
ldr r0, STR_FAIL
ldr r1, SerBase
bl PrintWord
1:b 1b @ infinite loop
#endif
ok_nand_read:
#ifdef CONFIG_DEBUG_LL
ldr r0, STR_OK
ldr r1, SerBase
bl PrintWord
#endif
@ verify
mov r0, #0
ldr r1, =UBOOT_RAM_BASE
mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq done_nand_read
bne go_next
notmatch:
#ifdef CONFIG_DEBUG_LL
sub r0, r0, #4
ldr r1, SerBase
bl PrintHexWord
ldr r0, STR_FAIL
ldr r1, SerBase
mov r2, #0
mov r3, r2
mov r4, r2
mov r5, r2
mov r6, r2
mov r7, r2
mov r8, r2
mov r9, r2
clear_loop:
stmia r0!, {r2-r9}
subs r1, r1, #(8 * 4)
bne clear_loop
mov pc, lr
#endif @ CONFIG_S
#endif
1:b 1b
done_nand_read:
#ifdef CONFIG_DEBUG_LL
ldr r0, STR_OK
ldr r1, SerBase
bl PrintWord
#endif
mov pc, r10
@ clear memory
@ r0: start address
@ r1: length
mem_clear:
mov r2, #0
mov r3, r2
mov r4, r2
mov r5, r2
mov r6, r2
mov r7, r2
mov r8, r2
mov r9, r2
clear_loop:
stmia r0!, {r2-r9}
subs r1, r1, #(8 * 4)
bne clear_loop
mov pc, lr
#endif @ CONFIG_S
在最后面添加
.align 2
DW_STACK_START:
.word STACK_BASE+STACK_SIZE-4
修改include/configs/linux2410.h文件
添加如下内容:
#ifndef __CONFIG_H
#define __CONFIG_H
/*
* High Level Configuration Options
* (easy to change)
*/
#define CONFIG_ARM920T 1 /* This is an ARM920T Core */
#define CONFIG_S
#define CONFIG_SMDK2410 1 /* on a SAMSUNG SMDK2410 Board */
……
……
……
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
#define CONFIG_AMD_LV400 1 /* uncomment this if you have a LV400 flash */
#if 0
#define CONFIG_AMD_LV800 1 /* uncomment this if you have a LV800 flash */
#endif
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#ifdef CONFIG_AMD_LV800
#define PHYS_FLASH_SIZE 0x00100000 /* 1MB */
#define CFG_MAX_FLASH_SECT (19) /* max number of sectors on one chip */
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x
#endif
#ifdef CONFIG_AMD_LV400
#define PHYS_FLASH_SIZE 0x00080000 /* 512KB */
#define CFG_MAX_FLASH_SECT (11) /* max number of sectors on one chip */
#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x070000) /* addr of environment */
#endif
/* timeout values are in ticks */
#define CFG_FLASH_ERASE_TOUT (5*CFG_HZ) /* Timeout for Flash Erase */
#define CFG_FLASH_WRITE_TOUT (5*CFG_HZ) /* Timeout for Flash Write */
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_SIZE 0x10000 /* Total Size of Environment Sector */
/*-----------------------------------------------------------------------
* NAND FLASH BOOT
*/
#define CONFIG_S
#define STACK_BASE 0x
#define STACK_SIZE 0x8000
#define NAND_CTL_BASE 0x4e000000
#define bINT_CTL(Nb) _REG(INT_CTL_BASE+(Nb))
#define oNFCONF 0x00
#define oNFCMD 0x04
#define oNFADDR 0x08
#define oNFDATA 0x
#define oNFSTAT 0x10
#define oNFECC 0x14
/*-----------------------------------------------------------------------
* NAND flash settings
*/
#define CFG_NAND_LEGACY 1
#define NFCE_LOW 0
#define NFCE_HIGH 1
#define NAND_MAX_CHIPS 1
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
#define CFG_NAND_BASE 0x4E000000
#define SECTORSIZE 512
#define ADDR_COLUMN 1
#define ADDR_PAGE 2
#define ADDR_COLUMN_PAGE 3
#define NAND_ChipID_UNKNOWN 0x00
#define NAND_MAX_FLOORS 1
#define NAND_WAIT_READY(nand) NF_WaitRB()
#define NAND_DISABLE_CE(nand) NF_SetCE(NFCE_HIGH)
#define NAND_ENABLE_CE(nand) NF_SetCE(NFCE_LOW)
#define WRITE_NAND_COMMAND(d, adr) NF_Cmd(d)
#define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d)
#define WRITE_NAND_ADDRESS(d, adr) NF_Addr(d)
#define WRITE_NAND(d, adr) NF_Write(d)
#define READ_NAND(adr) NF_Read()
/* the following functions are NOP's because S
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)
/* #undef CONFIG_MTD_NAND_VERIFY_WRITE */
#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */
加入自己的Nand Flash芯片型号
在include/linux/mtd/nand_ids.h 中,对如下结构体赋值进行修改:
static struct nand_flash_dev nand_flash_ids[] = {
....
{"Samsung K
....
};
为U-BOOT添加NAND FLASH驱动
1、在drivers/nand_legacy/nand_legacy.c 中添加如下:
/**********************************************************************/
/* My ADD */
#if (CONFIG_SMDK2410)
#include 3c2410.h>
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
/*typedef enum {
NFCE_LOW,
NFCE_HIGH
} NFCE_STATE;*/
static inline void NF_Conf(u16 conf)
{
S
nand->NFCONF = conf;
}
static inline void NF_Cmd(u8 cmd)
{
S
nand->NFCMD = cmd;
}
static inline void NF_CmdW(u8 cmd)
{
NF_Cmd(cmd);
udelay(1);
}
static inline void NF_Addr(u8 addr)
{
S
nand->NFADDR = addr;
}
//static inline void NF_SetCE(NFCE_STATE s)
static inline void NF_SetCE(int s)
{
S
switch (s) {
case NFCE_LOW:
nand->NFCONF &= ~(1<<11);
break;
case NFCE_HIGH:
nand->NFCONF |= (1<<11);
break;
}
}
static inline void NF_WaitRB(void)
{
S
while (!(nand->NFSTAT & (1<<0)));
}
static inline void NF_Write(u8 data)
{
S
nand->NFDATA = data;
}
static inline u8 NF_Read(void)
{
S
return(nand->NFDATA);
}
static inline void NF_Init_ECC(void)
{
S
nand->NFCONF |= (1<<12);
}
static inline u32 NF_Read_ECC(void)
{
S
return(nand->NFECC);
}
extern ulong nand_probe(ulong physadr);
static inline void NF_Reset(void)
{
int i;
NF_SetCE(NFCE_LOW);
NF_Cmd(0xFF); /* reset command */
for(i = 0; i < 10; i++); /* tWB = 100ns. */
NF_WaitRB(); /* wait 200~500us; */
NF_SetCE(NFCE_HIGH);
}
static inline void NF_Init(void)
{
#if 1
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#else
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
#endif
NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
/*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
/* 1 1 1 1, 1 xxx, r xxx, r xxx */
/* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */
NF_Reset();
}
void nand_init(void)
{
S
NF_Init();
#ifdef DEBUG
printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif
printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}
#endif /*CONFIG_COMMANDS & CFG_CMD_NAND*/
#endif /*CONFIG_SMDK23410*/
修改include/configs/linux2410.h如下:
……
……
/***********************************************************
* Command definition
***********************************************************/
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL | \
CFG_CMD_CACHE | \
CFG_CMD_NAND | \
/*CFG_CMD_EEPROM |*/ \
/*CFG_CMD_I
/*CFG_CMD_USB |*/ \
CFG_CMD_REGINFO | \
CFG_CMD_DATE | \
CFG_CMD_ELF)
……
……
修改drivers/nand_legacy/nand_legacy.c如下:
/* for (i=0; i
if (nand_dev_desc[i].ChipID == NAND_ChipID_UNKNOWN)
{
nand = &nand_dev_desc[i];
break;
}
}
*/
用nand = &nand_dev_desc[0]; 代替 nand = &nand_dev_desc[i];
修改在include/configs/linux2410.h中定义的一些宏
文件定义了CPU频率,网卡地址,SDRAM的某些设置也都在这里。主要修改如下:
/*cs8900网卡的设置*/
#define CONFIG_DRIVER_CS8900 1 //使用cs8900的驱动
#define CS8900_BASE 0x19000300 //网卡的地址,如要变动,则需查阅板子的手册
#define CS8900BUS16 1
/*设置波特率*/
#define CONFIG_BAUDRATE 115200
网络的一些环境变量的设置
#define CONFIG_BOOTDELAY 5
#define CONFIG_BOOTARGS "root=/dev/mtdblock2 loadramfs=0 devfs=mount mem=
#define CONFIG_ETHADDR 00:00:C0:FF:EE:08
#define CONFIG_NETMASK 255.255.255.0
#define CONFIG_IPADDR
#define CONFIG_SERVERIP
有关于网卡mac地址,ip地址,以及tftp服务器的ip的设置,还有linux内核启动的参数等
SDRAM的设置:
#define CONFIG_NR_DRAM_BANKS 1
#define PHYS_SDRAM_1 0x30000000 //SDRAM的开始地址
#define PHYS_SDRAM_1_SIZE 0x04000000 //SDRAM的大小,这里是64MB
下面代码放到common/cmd_nand.c中
#if (CONFIG_COMMANDS & CFG_CMD_JFFS2) && defined(CONFIG_JFFS2_CMDLINE)后边放
#if (CONFIG_SMDK2410)
#include 3c2410.h>
typedef enum {
NFCE_LOW,
NFCE_HIGH
} NFCE_STATE;
static inline void NF_Conf(u16 conf)
{
S
nand->NFCONF = conf;
}
static inline void NF_Cmd(u8 cmd)
{
S
nand->NFCMD = cmd;
}
static inline void NF_CmdW(u8 cmd)
{
NF_Cmd(cmd);
udelay(1);
}
static inline void NF_Addr(u8 addr)
{
S
nand->NFADDR = addr;
}
static inline void NF_SetCE(NFCE_STATE s)
{
S
switch (s) {
case NFCE_LOW:
nand->NFCONF &= ~(1<<11);
break;
case NFCE_HIGH:
nand->NFCONF |= (1<<11);
break;
}
}
static inline void NF_WaitRB(void)
{
S
while (!(nand->NFSTAT & (1<<0)));
}
static inline void NF_Write(u8 data)
{
S
nand->NFDATA = data;
}
static inline u8 NF_Read(void)
{
S
return(nand->NFDATA);
}
static inline void NF_Init_ECC(void)
{
S
nand->NFCONF |= (1<<12);
}
static inline u32 NF_Read_ECC(void)
{
S
return(nand->NFECC);
}
extern ulong nand_probe(ulong physadr);
static inline void NF_Reset(void)
{
int i;
NF_SetCE(NFCE_LOW);
NF_Cmd(0xFF); /* reset command */
for(i = 0; i < 10; i++); /* tWB = 100ns. */
NF_WaitRB(); /* wait 200~500us; */
NF_SetCE(NFCE_HIGH);
}
static inline void NF_Init(void)
{
#if 0 /* a little bit too optimistic */
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#else
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
#endif
NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
/*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
/* 1 1 1 1, 1 xxx, r xxx, r xxx */
/* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */
NF_Reset();
}
void nand_init(void)
{
S
NF_Init();
#ifdef DEBUG
printf("NAND flash probing at 0x%.8lX ", (ulong)nand);
#endif
printf ("%4lu MB ", nand_probe((ulong)nand) >> 20);
}
#endif /* (CONFIG_SMDK2410) */
再把以下代码放到include/configs/linux2410.h中
#define CFG_ENV_SIZE 0x10000 /* TOtal Size of Environment Sector */之后
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
#define SECTORSIZE 512
#define ADDR_COLUMN 1
#define ADDR_PAGE 2
#define ADDR_COLUMN_PAGE 3
#define NAND_ChipID_UNKNOWN 0x00
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
#define NAND_WAIT_READY(nand) NF_WaitRB()
#define NAND_DISABLE_CE(nand) NF_SetCE(NFCE_HIGH)
#define NAND_ENABLE_CE(nand) NF_SetCE(NFCE_LOW)
#define WRITE_NAND_COMMAND(d, adr) NF_Cmd(d)
#define WRITE_NAND_COMMANDW(d, adr) NF_CmdW(d)
#define WRITE_NAND_ADDRESS(d, adr) NF_Addr(d)
#define WRITE_NAND(d, adr) NF_Write(d)
#define READ_NAND(adr) NF_Read()
/* the following functions are NOP's because S
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)
/* #define CONFIG_MTD_NAND_VERIFY_WRITE 1 */
#define CONFIG_MTD_NAND_ECC_JFFS2 1
#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */
重新编译 make all ARCH=arm