成功在skyeye 上实现U-Boot 的Nand命令并从Nand中启动Linux
同主题~~一天的时间 就跟踪代码了~~
步骤见2楼
# vim u-boot.conf
# skyeye config file for S3C2410X
cpu: arm920t
mach: s3c2410x
# physical memory
mem_bank: map=M, type=RW, addr=0x00000000, size=0x00800000, file=./u-boot.bin ,boot=yes
mem_bank: map=M, type=RW, addr=0x30000000, size=0x00800000
mem_bank: map=M, type=RW, addr=0x30800000, size=0x00800000
mem_bank: map=M, type=RW, addr=0x31000000, size=0x03000000
# all peripherals I/O mapping area
mem_bank: map=I, type=RW, addr=0x48000000, size=0x20000000
mem_bank: map=I, type=RW, addr=0x19000300, size=0x00000020
net: type=cs8900a, base=0x19000300, size=0x20,int=9, mac=0:4:3:2:1:f, ethmod=tuntap, hostip=10.0.0.1
nandflash: type=s3c2410x,name=K9F1208U0B,dump=./nand.dump
#lcd:type=s3c2410x, mod=gtk
dbct:state=on
用skyeye 提供的mknandflashdump程序将 我们的u-boot.bin文件镜像到nand.dump 文件中
mknandflashdump u-boot.bin nand.dump 0
[ 本帖最后由 zbluecn 于 2008-2-26 15:48 编辑 ] 1. 下载u-boot-1.1.4.tar.bz2,并解压
2. 将arm-linux-2.95.3复制到/usr/local/arm/2.95.3/
3. 编辑u-boot跟目录的Makefile文件
include $(TOPDIR)/config.mk
CROSS_COMPILE=/usr/local/arm/2.95.3/bin/arm-linux-
ifndef CROSS_COMPILE
smdk2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0
sky2410_config : unconfig
@./mkconfig $(@:_config=) arm arm920t sky2410 NULL s3c24x0
SX1_config : unconfig
@./mkconfig $(@:_config=) arm arm925t sx1
4. 复制必要的文件
cp -arf board/smdk2410/ board/sky2410
mv board/sky2410/smdk2410.c board/sky2410/sky2410.c
cp include/configs/smdk2410.h include/configs/sky2410.h
5. 修改board/sky2410/Makefile
LIB = lib$(BOARD).a
OBJS:= sky2410.o flash.o
SOBJS := lowlevel_init.o
6. make 测试一下
make sky2410_config
make
出现错误
cc1: Invalid option `abi=apcs-gnu'
修改文件cpu/arm920t/config.mk
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
改成:
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,$(call cc-option,-mabi=apcs-gnu),)
再make成功
7. 开始移植nand
修改cpu/arm920t/start.S
将从Flash启动改成从NAND Flash启动。
将以下U-Boot的重定向语句段:
#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 r0!, {r3-r10} /* copy from source address */
stmia r1!, {r3-r10} /* copy to target address */
cmp r0, r2 /* until source end addreee */
ble copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
替换成:
#ifdef CONFIG_S3C2410_NAND_BOOT
@ reset NAND
mov r1, #NAND_CTL_BASE
ldr r2, =0xf830 @ initial value
str r2,
ldr r2,
bicr2, r2, #0x800 @ enable chip
str r2,
mov r2, #0xff @ RESET command
strb r2,
mov r3, #0 @ wait
nand1:
addr3, r3, #0x1
cmp r3, #0xa
blt nand1
nand2:
ldr r2, @ wait ready
tst r2, #0x1
beqnand2
ldr r2,
orrr2, r2, #0x800 @ disable chip
str r2,
@ 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 U-Boot to RAM
ldr r0, =TEXT_BASE
mov r1, #0x0
mov r2, #0x20000
bl nand_read_ll
tst r0, #0x0
beqok_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, , #4
ldr r4, , #4
teq r3, r4
bnenotmatch
subs r2, r2, #4
beqstack_setup
bnego_next
notmatch:
loop3: b loop3 @ infinite loop
#endif /* CONFIG_S3C2410_NAND_BOOT */
在 “_start_armboot: .word start_armboot” 后加入:
.align 2
DW_STACK_START:.wordSTACK_BASE+STACK_SIZE-4
8.
(I)修改board/sky2410/Makefile
OBJS:= sky2410.o flash.o nand_read.o
(II)创建board/sky2410/nand_read.c文件
#include <config.h>
#define __REGb(x) (*(volatile unsigned char *)(x))
#define __REGi(x) (*(volatile unsigned int *)(x))
#define NF_BASE0x4e000000
#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
#ifndef NAND_SECTOR_SIZE
#define NAND_SECTOR_SIZE 512
#endif
#ifndef
#define NAND_BLOCK_MASK 511
#endif
inline void wait_idle(void) {
int i;
while(!(NFSTAT & BUSY))
for(i=0; i<10; i++);
}
/* 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)) {
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;
}
9.修改include/configs/sky2410.h
在文件的后部添加
/*
* Nandflash Boot
*/
#define CONFIG_S3C2410_NAND_BOOT 1
#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
#define oNFCMD 0x04
#define oNFADDR 0x08
#define oNFDATA 0x0c
#define oNFSTAT 0x10
#define oNFECC 0x14
10.
make 测试一下啊
到这里 u-boot 已经可以从nand启动了
[ 本帖最后由 zbluecn 于 2008-3-3 17:18 编辑 ] 下面我们对u-boot添加nand指令的支持
11. 修改include/configs/sky2410.h
(I)去掉CFG_CMD_NAND的注释
#define CONFIG_COMMANDS \
(CONFIG_CMD_DFL| \
CFG_CMD_CACHE| \
CFG_CMD_NAND | \
/*CFG_CMD_EEPROM |*/ \
/*CFG_CMD_I2C|*/ \
/*CFG_CMD_USB|*/ \
CFG_CMD_REGINFO| \
CFG_CMD_DATE | \
CFG_CMD_ELF)
(II) 修改我们在第9步修改的内容
#define CFG_NAND_LEGACY
#define CFG_ENV_OFFSET0X20000
#if (CONFIG_COMMANDS & CFG_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
/* Nand Flash命令层底层接口函数 */
#define WRITE_NAND_COMMAND(d, adr) {rNFCMD = d;}
#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 NAND_DISABLE_CE(nand) {rNFCONF |= (1<<11);}
#define NAND_ENABLE_CE(nand) {rNFCONF &= ~(1<<11);}
/* the following functions are NOP's because S3C24X0 handles this in hardware一定要加上 */
#define NAND_CTL_CLRALE(nandptr)
#define NAND_CTL_SETALE(nandptr)
#define NAND_CTL_CLRCLE(nandptr)
#define NAND_CTL_SETCLE(nandptr)
/* 允许Nand Flash写校验 */
#define CONFIG_MTD_NAND_VERIFY_WRITE 1
/*
* Nandflash Boot
*/
#define CONFIG_S3C2410_NAND_BOOT 1
#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
#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 /* CONFIG_COMMANDS & CFG_CMD_NAND*/
12. 修改 board/sky2410/sky2410.c
在文件尾部添加
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
typedef enum {
NFCE_LOW,
NFCE_HIGH
} NFCE_STATE;
static inline void NF_Conf(u16 conf)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF = conf;
}
static inline void NF_Cmd(u8 cmd)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCMD = cmd;
}
static inline void NF_CmdW(u8 cmd)
{
NF_Cmd(cmd);
udelay(1);
}
static inline void NF_Addr(u8 addr)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFADDR = addr;
}
static inline void NF_SetCE(NFCE_STATE s)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
switch (s) {
case NFCE_LOW:
nand->NFCONF &= ~(1<<11);
break;
case NFCE_HIGH:
nand->NFCONF |= (1<<11);
break;
}
}
static inline void NF_WaitRB(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
while (!(nand->NFSTAT & (1<<0)));
}
static inline void NF_Write(u8 data)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFDATA = data;
}
static inline u8 NF_Read(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFDATA);
}
static inline void NF_Init_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
nand->NFCONF |= (1<<12);
}
static inline u32 NF_Read_ECC(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
return(nand->NFECC);
}
#endif
/*
* NAND flash initialization.
*/
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
extern ulong nand_probe(ulong physadr);
static inline void NF_Reset(void)
{
int i;
NF_SetCE(NFCE_LOW);
NF_Cmd(0xFF); /* reset command */
for(i = 0; i < 10; i++); /* tWB = 100ns. */
NF_WaitRB(); /* wait 200~500us; */
NF_SetCE(NFCE_HIGH);
}
static inline void NF_Init(void)
{
#if 0 /* a little bit too optimistic */
#define TACLS 0
#define TWRPH0 3
#define TWRPH1 0
#else
#define TACLS 0
#define TWRPH0 4
#define TWRPH1 2
#endif
NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
/*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
/* 1 1 1 1, 1 xxx, r xxx, r xxx */
/* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */
NF_Reset();
}
void
nand_init(void)
{
S3C2410_NAND * const nand = S3C2410_GetBase_NAND();
NF_Init();
#ifdef DEBUG
printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif
printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}
#endif
现在我问对uboot的nand指令的修改也完成了
上面的步骤基本的在网上也能找到
但是,如果就真么直接使用的话 skyeye1.2.4就会报错
SMDK2410 # nand read 33000000 0 20000
NAND read: device 0 offset 0, size 131072 ... warning when REfalling,do nothing
0 bytes read: ERROR
最后花费一天的时间跟踪 skyeye 和u-boot 终于找到错误的原因了
在u-boot读取oob数据
先发送了NanD_Command(nand, NAND_CMD_READOOB)
然后发送NanD_Address(nand, ADDR_COLUMN_PAGE
这个时候 skyeye模拟的nand就准备好数据了
直接就可以用 READ_NAND (nandptr)读取了
但是在u-boot的NanD_ReadBuf函数中又发送了一次NanD_Command (nand, NAND_CMD_READ0);
结果skyeye就认为命令发生了改变 然后就开始等待NanD_Address(nand, ADDR_COLUMN_PAGE了
可是u-boot在发送NanD_Command (nand, NAND_CMD_READ0);后就用READ_NAND (nandptr)读取数据
skyeye 就认为是没有发送地址然后就报错了.
猜测 skyeye不能同时处理2个指令 在发送NAND_CMD_READ0后前面的NAND_CMD_READOOB就被丢失了
开始想修改skyeye的nand代码 可以整体结构已经定了 感觉很难修改
现阶段找到的办法就是
修改 command/cmd_nand.c
中的NanD_ReadBuf函数
注释掉NanD_Command (nand, NAND_CMD_READ0);这一行
问题解决
重要的一点
用修改后的u-boot下载到开发板中, 经过检测没有任何问题的.
[ 本帖最后由 zbluecn 于 2008-2-26 12:39 编辑 ]
回复 #3 zbluecn 的帖子
That is really great job.If you can run flash file system based on s3c2410 nand flash with linux kernel, that is more perfect.回复 #4 albert198511 的帖子
nand flash simulation was added in skyeye-1.2.4. That means you have to use skyeye-1.2.4 to try LZ's instruction. 在Linux上挂机模拟的s3c2410 nand flash 是可以的啊~~ 已经启动起来了~~按照普通开发板的去修改内核就可以了啊
[ 本帖最后由 zbluecn 于 2008-2-27 12:54 编辑 ] 8.
错误的
(I)修改board/smdk2410/Makefile
OBJS:= sky2410.o flash.o
正确的
(I)修改board/sky2410/Makefile
OBJS:= sky2410.o flash.o nand.o board/smdk2410/nand_read.c
文件添加错误 嘻嘻
board/sky2410/nand_read.c in http://skyeye.svn.sourceforge.net/viewvc/skyeye/skyeye-v1/trunk/device/nandflash/tools/
, and use your native gcc to build it and use it. tftp 是从TFTP服务器上下载内核镜像
flash 是另外Nor 的虚拟 没有关系的
我们用的nand 虚拟 分清楚 nor 和 nand的区别~~
在自己的机子上做一个tftp server
建议看看 linux 的启动顺序
还有关于s3c2410的启动过程
出现段错误。。。 晕
执行skyeye -c u-boot.conf之后的显示如下:不小心执行了两遍bootm。。。 不过执行一遍的时候也是这个错误
u-boot.conf内容如下:
是访问内存出错了吗?请高手指点!!
[ 本帖最后由 albert198511 于 2008-3-24 16:40 编辑 ] 我把u-boot.conf中的“dbct:state=on”注释之后,程序执行到:
Uncompressing Linux................................................................. done, booting the kernel.
死机。
还请高手指教啊!!!
内核配置
内核是2.6.14.1的,按照LZ:http://blog.csdn.net/zblue78/archive/2008/02/20/2109827.aspx
的帖子中进行的配置,最后执行make uImage,将uImage上传至tftp中,然后载入,是内核配置的问题吗?
问题
看楼主的贴图,发现在启动过程中 有 Loaded RAM ./initrd.img但是在skyeye.conf 中并没有initrd.img,是什么原因?
页:
[1]
2