QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13741|回复: 26

成功在skyeye 上实现U-Boot 的Nand命令并从Nand中启动Linux

[复制链接]
发表于 2008-2-25 21:45:32 | 显示全部楼层 |阅读模式
同主题~~
一天的时间 就跟踪代码了~~

步骤见2楼


[root@fc4 test]# vim u-boot.conf

  1. # skyeye config file for S3C2410X

  2. cpu: arm920t
  3. mach: s3c2410x

  4. # physical memory
  5. mem_bank: map=M, type=RW, addr=0x00000000, size=0x00800000, file=./u-boot.bin ,boot=yes

  6. mem_bank: map=M, type=RW, addr=0x30000000, size=0x00800000
  7. mem_bank: map=M, type=RW, addr=0x30800000, size=0x00800000
  8. mem_bank: map=M, type=RW, addr=0x31000000, size=0x03000000


  9. # all peripherals I/O mapping area
  10. mem_bank: map=I, type=RW, addr=0x48000000, size=0x20000000
  11. mem_bank: map=I, type=RW, addr=0x19000300, size=0x00000020

  12. net: type=cs8900a, base=0x19000300, size=0x20,int=9, mac=0:4:3:2:1:f, ethmod=tuntap, hostip=10.0.0.1
  13. nandflash: type=s3c2410x,name=K9F1208U0B,dump=./nand.dump
  14. #lcd:type=s3c2410x, mod=gtk
  15. dbct:state=on
复制代码


用skyeye 提供的mknandflashdump程序将 我们的u-boot.bin文件镜像到nand.dump 文件中

mknandflashdump u-boot.bin nand.dump 0


[ 本帖最后由 zbluecn 于 2008-2-26 15:48 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 发表于 2008-2-26 12:29:56 | 显示全部楼层
1. 下载u-boot-1.1.4.tar.bz2,并解压
2. 将arm-linux-2.95.3复制到/usr/local/arm/2.95.3/

3. 编辑u-boot跟目录的Makefile文件
  1. include $(TOPDIR)/config.mk
  2. CROSS_COMPILE=/usr/local/arm/2.95.3/bin/arm-linux-
  3. ifndef CROSS_COMPILE
复制代码

  1. smdk2410_config : unconfig
  2.         @./mkconfig $(@:_config=) arm arm920t smdk2410 NULL s3c24x0

  3. sky2410_config : unconfig
  4.         @./mkconfig $(@:_config=) arm arm920t sky2410 NULL s3c24x0

  5. SX1_config :    unconfig
  6.         @./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
  1. LIB = lib$(BOARD).a

  2. OBJS  := sky2410.o flash.o
  3. SOBJS := lowlevel_init.o
复制代码


6. make 测试一下
make sky2410_config
make
出现错误
cc1: Invalid option `abi=apcs-gnu'
修改文件cpu/arm920t/config.mk
  1. PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
复制代码

改成:
  1. 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的重定向语句段:


  1. #ifndef CONFIG_SKIP_RELOCATE_UBOOT
  2. relocate:                /* relocate U-Boot to RAM        */
  3.     adr    r0, _start        /* r0 <- current position of code   */
  4.     ldr    r1, _TEXT_BASE        /* test if we run from flash or RAM */
  5.     cmp     r0, r1                 /* don't reloc during debug         */
  6.     beq     stack_setup

  7.     ldr    r2, _armboot_start
  8.     ldr    r3, _bss_start
  9.     sub    r2, r3, r2        /* r2 <- size of armboot            */
  10.     add    r2, r0, r2        /* r2 <- source end address         */

  11. copy_loop:
  12.     ldmia    r0!, {r3-r10}        /* copy from source address [r0]    */
  13.     stmia    r1!, {r3-r10}        /* copy to   target address [r1]    */
  14.     cmp    r0, r2            /* until source end addreee [r2]    */
  15.     ble    copy_loop
  16. #endif    /* CONFIG_SKIP_RELOCATE_UBOOT */
复制代码




替换成:

  1. #ifdef CONFIG_S3C2410_NAND_BOOT
  2. @ reset NAND
  3.   mov r1, #NAND_CTL_BASE
  4.   ldr   r2, =0xf830           @ initial value
  5.   str   r2, [r1, #oNFCONF]
  6.   ldr   r2, [r1, #oNFCONF]
  7.   bic  r2, r2, #0x800              @ enable chip
  8.   str   r2, [r1, #oNFCONF]
  9.   mov r2, #0xff         @ RESET command
  10.   strb r2, [r1, #oNFCMD]


  11.   mov r3, #0                   @ wait
  12. nand1:
  13.   add  r3, r3, #0x1
  14.   cmp r3, #0xa
  15.   blt   nand1

  16. nand2:
  17.   ldr   r2, [r1, #oNFSTAT]      @ wait ready
  18.   tst    r2, #0x1
  19.   beq  nand2

  20.   ldr   r2, [r1, #oNFCONF]
  21.   orr  r2, r2, #0x800              @ disable chip
  22.   str   r2, [r1, #oNFCONF]

  23. @ get read to call C functions (for nand_read())
  24.   ldr   sp, DW_STACK_START       @ setup stack pointer
  25.   mov fp, #0                    @ no previous frame, so fp=0

  26. @ copy U-Boot to RAM
  27.   ldr   r0, =TEXT_BASE
  28.   mov     r1, #0x0
  29.   mov r2, #0x20000
  30.   bl    nand_read_ll
  31.   tst    r0, #0x0
  32.   beq  ok_nand_read

  33. bad_nand_read:
  34. loop2:    b     loop2          @ infinite loop


  35. ok_nand_read:
  36. @ verify
  37.   mov r0, #0
  38.   ldr   r1, =TEXT_BASE
  39.   mov r2, #0x400     @ 4 bytes * 1024 = 4K-bytes
  40. go_next:
  41.   ldr   r3, [r0], #4
  42.   ldr   r4, [r1], #4
  43.   teq   r3, r4
  44.   bne  notmatch
  45.   subs r2, r2, #4
  46.   beq  stack_setup
  47.   bne  go_next

  48. notmatch:
  49. loop3:     b     loop3         @ infinite loop

  50. #endif /* CONFIG_S3C2410_NAND_BOOT */
复制代码


在 “  _start_armboot:    .word start_armboot  ” 后加入:

  1.         .align     2
  2. DW_STACK_START:  .word  STACK_BASE+STACK_SIZE-4
复制代码


8.
(I)修改board/sky2410/Makefile
OBJS  := sky2410.o flash.o nand_read.o


(II)创建board/sky2410/nand_read.c文件

  1. #include <config.h>
  2. #define __REGb(x) (*(volatile unsigned char *)(x))
  3. #define __REGi(x) (*(volatile unsigned int *)(x))
  4. #define NF_BASE  0x4e000000
  5. #define NFCONF  __REGi(NF_BASE + 0x0)
  6. #define NFCMD  __REGb(NF_BASE + 0x4)
  7. #define NFADDR  __REGb(NF_BASE + 0x8)
  8. #define NFDATA  __REGb(NF_BASE + 0xc)
  9. #define NFSTAT  __REGb(NF_BASE + 0x10)
  10. #define BUSY 1
  11. #ifndef NAND_SECTOR_SIZE
  12. #define NAND_SECTOR_SIZE 512
  13. #endif
  14. #ifndef
  15. #define NAND_BLOCK_MASK 511
  16. #endif
  17. inline void wait_idle(void) {
  18. int i;
  19. while(!(NFSTAT & BUSY))
  20. for(i=0; i<10; i++);
  21. }
  22. /* low level nand read function */
  23. int
  24. nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
  25. {
  26. int i, j;
  27. if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
  28. return -1; /* invalid alignment */
  29. }
  30. /* chip Enable */
  31. NFCONF &= ~0x800;
  32. for(i=0; i<10; i++);
  33. for(i=start_addr; i < (start_addr + size);) {
  34. /* READ0 */
  35. NFCMD = 0;
  36. /* Write Address */
  37. NFADDR = i & 0xff;
  38. NFADDR = (i >> 9) & 0xff;
  39. NFADDR = (i >> 17) & 0xff;
  40. NFADDR = (i >> 25) & 0xff;
  41. wait_idle();
  42. for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
  43. *buf = (NFDATA & 0xff);
  44. buf++;
  45. }
  46. }
  47. /* chip Disable */
  48. NFCONF |= 0x800; /* chip disable */
  49. return 0;
  50. }
复制代码


9.修改include/configs/sky2410.h
在文件的后部添加

  1. /*
  2. * Nandflash Boot
  3. */
  4. #define CONFIG_S3C2410_NAND_BOOT 1
  5. #define STACK_BASE    0x33f00000
  6. #define STACK_SIZE    0x8000
  7. //#define UBOOT_RAM_BASE    0x33f80000
  8. /* NAND Flash Controller */
  9. #define NAND_CTL_BASE            0x4E000000
  10. #define bINT_CTL(Nb)        __REG(INT_CTL_BASE + (Nb))
  11. /* Offset */
  12. #define oNFCONF               0x00
  13. #define oNFCMD                0x04
  14. #define oNFADDR               0x08
  15. #define oNFDATA               0x0c
  16. #define oNFSTAT               0x10
  17. #define oNFECC                0x14
复制代码


10.
make 测试一下啊
到这里 u-boot 已经可以从nand启动了

[ 本帖最后由 zbluecn 于 2008-3-3 17:18 编辑 ]
回复

使用道具 举报

 楼主| 发表于 2008-2-26 12:30:48 | 显示全部楼层
下面我们对u-boot添加nand指令的支持

11. 修改include/configs/sky2410.h
(I)去掉CFG_CMD_NAND的注释

  1. #define CONFIG_COMMANDS \
  2.       (CONFIG_CMD_DFL  | \
  3.       CFG_CMD_CACHE  | \
  4.       CFG_CMD_NAND   | \
  5.       /*CFG_CMD_EEPROM |*/ \
  6.       /*CFG_CMD_I2C  |*/ \
  7.       /*CFG_CMD_USB  |*/ \
  8.       CFG_CMD_REGINFO  | \
  9.       CFG_CMD_DATE   | \
  10.       CFG_CMD_ELF)
  11. [code]

  12. (II) 修改我们在第9步修改的内容
  13. [code]
  14. #define CFG_NAND_LEGACY
  15. #define CFG_ENV_OFFSET  0X20000
  16. #if (CONFIG_COMMANDS & CFG_CMD_NAND)
  17. #define CFG_NAND_BASE 0x4E000000
  18. /* NandFlash控制器在SFR区起始寄存器地址 */
  19. #define CFG_MAX_NAND_DEVICE 1
  20. /* 支持的最在Nand Flash数据 */
  21. #define SECTORSIZE 512
  22. /* 1页的大小 */
  23. #define NAND_SECTOR_SIZE SECTORSIZE
  24. #define NAND_BLOCK_MASK 511
  25. /* 页掩码 */
  26. #define ADDR_COLUMN 1
  27. /* 一个字节的Column地址 */
  28. #define ADDR_PAGE 3
  29. /* 3字节的页块地址!!!!!*/
  30. #define ADDR_COLUMN_PAGE 4
  31. /* 总共4字节的页块地址!!!!! */
  32. #define NAND_ChipID_UNKNOWN 0x00
  33. /* 未知芯片的ID号 */
  34. #define NAND_MAX_FLOORS 1
  35. #define NAND_MAX_CHIPS 1
  36. /* Nand Flash命令层底层接口函数 */
  37. #define WRITE_NAND_COMMAND(d, adr) {rNFCMD = d;}
  38. #define WRITE_NAND_ADDRESS(d, adr) {rNFADDR = d;}
  39. #define WRITE_NAND(d, adr) {rNFDATA = d;}
  40. #define READ_NAND(adr) (rNFDATA)
  41. #define NAND_WAIT_READY(nand) {while(!(rNFSTAT&(1<<0)));}
  42. #define NAND_DISABLE_CE(nand) {rNFCONF |= (1<<11);}
  43. #define NAND_ENABLE_CE(nand) {rNFCONF &= ~(1<<11);}
  44. /* the following functions are NOP's because S3C24X0 handles this in hardware  一定要加上 */
  45. #define NAND_CTL_CLRALE(nandptr)
  46. #define NAND_CTL_SETALE(nandptr)
  47. #define NAND_CTL_CLRCLE(nandptr)
  48. #define NAND_CTL_SETCLE(nandptr)
  49. /* 允许Nand Flash写校验 */
  50. #define CONFIG_MTD_NAND_VERIFY_WRITE 1
  51. /*
  52. * Nandflash Boot
  53. */
  54. #define CONFIG_S3C2410_NAND_BOOT 1
  55. #define STACK_BASE    0x33f00000
  56. #define STACK_SIZE    0x8000
  57. //#define UBOOT_RAM_BASE    0x33f80000
  58. /* NAND Flash Controller */
  59. #define NAND_CTL_BASE            0x4E000000
  60. #define bINT_CTL(Nb)        __REG(INT_CTL_BASE + (Nb))
  61. /* Offset */
  62. #define oNFCONF               0x00
  63. #define oNFCMD                0x04
  64. #define oNFADDR               0x08
  65. #define oNFDATA               0x0c
  66. #define oNFSTAT               0x10
  67. #define oNFECC                0x14
  68. #define rNFCONF (*(volatile unsigned int *)0x4e000000)
  69. #define rNFCMD (*(volatile unsigned char *)0x4e000004)
  70. #define rNFADDR (*(volatile unsigned char *)0x4e000008)
  71. #define rNFDATA (*(volatile unsigned char *)0x4e00000c)
  72. #define rNFSTAT (*(volatile unsigned int *)0x4e000010)
  73. #define rNFECC (*(volatile unsigned int *)0x4e000014)
  74. #define rNFECC0 (*(volatile unsigned char *)0x4e000014)
  75. #define rNFECC1 (*(volatile unsigned char *)0x4e000015)
  76. #define rNFECC2 (*(volatile unsigned char *)0x4e000016)
  77. #endif /* CONFIG_COMMANDS & CFG_CMD_NAND*/
复制代码


12. 修改 board/sky2410/sky2410.c
在文件尾部添加

  1. #if (CONFIG_COMMANDS & CFG_CMD_NAND)
  2. typedef enum {
  3. NFCE_LOW,
  4. NFCE_HIGH
  5. } NFCE_STATE;

  6. static inline void NF_Conf(u16 conf)
  7. {
  8. S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

  9. nand->NFCONF = conf;
  10. }

  11. static inline void NF_Cmd(u8 cmd)
  12. {
  13. S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

  14. nand->NFCMD = cmd;
  15. }

  16. static inline void NF_CmdW(u8 cmd)
  17. {
  18. NF_Cmd(cmd);
  19. udelay(1);
  20. }

  21. static inline void NF_Addr(u8 addr)
  22. {
  23. S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

  24. nand->NFADDR = addr;
  25. }

  26. static inline void NF_SetCE(NFCE_STATE s)
  27. {
  28. S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

  29. switch (s) {
  30. case NFCE_LOW:
  31. nand->NFCONF &= ~(1<<11);
  32. break;

  33. case NFCE_HIGH:
  34. nand->NFCONF |= (1<<11);
  35. break;
  36. }
  37. }

  38. static inline void NF_WaitRB(void)
  39. {
  40. S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

  41. while (!(nand->NFSTAT & (1<<0)));
  42. }

  43. static inline void NF_Write(u8 data)
  44. {
  45. S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

  46. nand->NFDATA = data;
  47. }

  48. static inline u8 NF_Read(void)
  49. {
  50. S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

  51. return(nand->NFDATA);
  52. }

  53. static inline void NF_Init_ECC(void)
  54. {
  55. S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

  56. nand->NFCONF |= (1<<12);
  57. }

  58. static inline u32 NF_Read_ECC(void)
  59. {
  60. S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

  61. return(nand->NFECC);
  62. }

  63. #endif
  64. /*

  65. * NAND flash initialization.
  66. */
  67. #if (CONFIG_COMMANDS & CFG_CMD_NAND)
  68. extern ulong nand_probe(ulong physadr);


  69. static inline void NF_Reset(void)
  70. {
  71. int i;

  72. NF_SetCE(NFCE_LOW);
  73. NF_Cmd(0xFF); /* reset command */
  74. for(i = 0; i < 10; i++); /* tWB = 100ns. */
  75. NF_WaitRB(); /* wait 200~500us; */
  76. NF_SetCE(NFCE_HIGH);
  77. }


  78. static inline void NF_Init(void)
  79. {
  80. #if 0 /* a little bit too optimistic */
  81. #define TACLS 0
  82. #define TWRPH0 3
  83. #define TWRPH1 0
  84. #else
  85. #define TACLS 0
  86. #define TWRPH0 4
  87. #define TWRPH1 2
  88. #endif

  89. NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
  90. /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
  91. /* 1 1 1 1, 1 xxx, r xxx, r xxx */
  92. /* En 512B 4step ECCR nFCE=H tACLS tWRPH0 tWRPH1 */

  93. NF_Reset();
  94. }

  95. void
  96. nand_init(void)
  97. {
  98. S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

  99. NF_Init();
  100. #ifdef DEBUG
  101. printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
  102. #endif
  103. printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
  104. }
  105. #endif
复制代码


现在我问对uboot的nand指令的修改也完成了

上面的步骤基本的在网上也能找到
但是,如果就真么直接使用的话 skyeye1.2.4就会报错

SMDK2410 # nand read 33000000 0 20000
NAND read: device 0 offset 0, size 131072 ... warning when RE  falling,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 编辑 ]
回复

使用道具 举报

发表于 2008-2-27 11:31:54 | 显示全部楼层

回复 #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.
回复

使用道具 举报

发表于 2008-2-27 11:32:59 | 显示全部楼层

回复 #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.
回复

使用道具 举报

 楼主| 发表于 2008-2-27 12:20:10 | 显示全部楼层
在Linux上挂机模拟的s3c2410 nand flash 是可以的啊~~ 已经启动起来了~~
按照普通开发板的去修改内核就可以了啊

[ 本帖最后由 zbluecn 于 2008-2-27 12:54 编辑 ]
回复

使用道具 举报

 楼主| 发表于 2008-2-29 21:51:59 | 显示全部楼层
8.
错误的
(I)修改board/smdk2410/Makefile
OBJS  := sky2410.o flash.o

正确的
(I)修改board/sky2410/Makefile
OBJS  := sky2410.o flash.o nand.o
回复

使用道具 举报

 楼主| 发表于 2008-3-3 15:02:47 | 显示全部楼层
board/smdk2410/nand_read.c

文件添加错误 嘻嘻

board/sky2410/nand_read.c
回复

使用道具 举报

发表于 2008-3-4 12:23:24 | 显示全部楼层
in http://skyeye.svn.sourceforge.ne ... ce/nandflash/tools/
, and use your native gcc to build it and use it.
回复

使用道具 举报

 楼主| 发表于 2008-3-9 10:50:29 | 显示全部楼层
tftp 是从TFTP服务器上下载内核镜像
flash 是另外Nor 的虚拟 没有关系的
我们用的nand 虚拟
回复

使用道具 举报

 楼主| 发表于 2008-3-9 10:52:40 | 显示全部楼层
分清楚 nor 和 nand的区别~~
在自己的机子上做一个tftp server

建议看看 linux 的启动顺序
还有关于s3c2410的启动过程
回复

使用道具 举报

发表于 2008-3-24 13:03:16 | 显示全部楼层

出现段错误。。。 晕

执行skyeye -c u-boot.conf之后的显示如下:






不小心执行了两遍bootm。。。 不过执行一遍的时候也是这个错误

u-boot.conf内容如下:



是访问内存出错了吗?请高手指点!!

[ 本帖最后由 albert198511 于 2008-3-24 16:40 编辑 ]

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
回复

使用道具 举报

发表于 2008-3-25 13:51:26 | 显示全部楼层
我把u-boot.conf中的“dbct:state=on”注释之后,程序执行到:
Uncompressing Linux................................................................. done, booting the kernel.
死机。

还请高手指教啊!!!
回复

使用道具 举报

发表于 2008-3-25 14:19:18 | 显示全部楼层

内核配置

内核是2.6.14.1的,按照LZ:
http://blog.csdn.net/zblue78/archive/2008/02/20/2109827.aspx
的帖子中进行的配置,最后执行make uImage,将uImage上传至tftp中,然后载入,是内核配置的问题吗?
回复

使用道具 举报

发表于 2008-4-9 23:42:29 | 显示全部楼层

问题

看楼主的贴图,发现在启动过程中 有 Loaded RAM   ./initrd.img

但是在skyeye.conf 中并没有initrd.img,是什么原因?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-4-28 04:50 , Processed in 0.050854 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表