U-Boot-2009-03 Nandflash에서 부팅 1

33406 단어 Flash
에서중, 우리는 sdram을 초기화하고 첫 번째 불을 켰다.본고에서, 우리는 nandflash가 시작하는 구동 코드를 이식할 것이다.
S3C2440에 대해 steppingston이 하나 있는데 CPU에 전기를 넣을 때 하드웨어가 Nandflash의 전 4KB 코드를 필름 안의 SRAM으로 복사하고 내부 SRAM은 주소 0x0에 비추어야만 우리의 코드가 cpu에 실행될 수 있다.
문제는 우리의 코드가 4KB에 그치지 않는다는 것이다. 따라서 우리는 스스로 코드를 써서 nandflash의 나머지 코드를 메모리에 복사한 다음 CPU를 해당하는 메모리 주소로 이동시켜 실행해야 한다.
C 언어에 대한 실행 환경을 위한 스택 포인터 설정
1         /*    */

2     ldr sp, DW_STACK_START

3     mov fp,#0    

두 번째 행은 DW 을 참조합니다.STACK_START 기호, 우리는 기호에 정의한다start_armboot 뒷면
1 _start_armboot:    .word start_armboot

2 DW_STACK_START: .word STACK_BASE+STACK_SIZE-4

두 번째 줄의 STACKBASE 및 STACKSIZE는 모두include/configs/xinna2440에 정의되어 있습니다.h중
1 #define STACK_BASE  0x33f00000     //       

2 #define STACK_SIZE  0x8000         //       

창고 지침을 설정했습니다. 다음은 Nandflash를 초기화한 후에 데이터를 읽고 sdram에 저장할 수 있습니다.
NandFlash 초기화
우리는board/xinna2440/폴더 아래nand 증가op.c 파일, 그리고 board/xinna2440/Makefile 수정, nand 추가op.c의 컴파일
1 COBJS        := xinna2440.o flash.o nand_op.o

board/xinna2440/nand 편집op.c, 다음 파일을 추가합니다. 저희 보드에는 K9F2G08U0A, 2KB 한 페이지, 총 64MB 크기가 사용됩니다.  1/*
  2  * board/samsung/reille2440/nand_read.c

  3  *

  4  * (C) Copyright 2011

  5  * reille <http://blog.csdn.net/reille/> <[email protected]>

  6  *

  7  * This program is free software; you can redistribute it and/or

  8  * modify it under the terms of the GNU General Public License as

  9  * published by the Free Software Foundation; either version 2 of

 10  * the License, or (at your option) any later version.

 11  *

 12  */

 13 #include <config.h>

 14 #define NF_BASE   0x4E000000  //Nand Flash        

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

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

 17 #if 0

 18 #define NFCONF __REGi(NF_BASE + 0x0 )  //                 

 19 #define NFCONT __REGi(NF_BASE + 0x4 )  //               

 20 #define NFCMD  __REGb(NF_BASE + 0x8 )  //               

 21 #define NFADDR __REGb(NF_BASE + 0xC )  //               

 22 #define NFDATA __REGb(NF_BASE + 0x10)  //               

 23 #define NFSTAT __REGb(NF_BASE + 0x20)  //               

 24 #endif

 25 

 26 #define NFCONF (*(volatile unsigned int *)(NF_BASE + 0X0))

 27 #define NFCONT (*(volatile unsigned short *)(NF_BASE + 0x4))

 28 #define NFCMD  (*(volatile unsigned short *)(NF_BASE + 0X8))

 29 #define NFADDR (*(volatile unsigned short *)(NF_BASE + 0xc))

 30 #define NFDATA (*(volatile unsigned char *)(NF_BASE + 0x10))

 31 #define NFSTAT (*(volatile unsigned char *)(NF_BASE + 0x20))

 32 

 33 

 34 #define NAND_CHIP_ENABLE  (NFCONT &= ~(1<<1))  //Nand    

 35 #define NAND_CHIP_DISABLE (NFCONT |= (1<<1))   //  Nand  

 36 #define NAND_CLEAR_RB     (NFSTAT |= (1<<2));

 37 #define NAND_DETECT_RB    { while(! (NFSTAT&(1<<2)) );}

 38 #define NAND_SECTOR_SIZE 2048

 39 #define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)

 40 #if 0

 41 #define DEBUGN    printf

 42 #else

 43 #define DEBUGN(x, args ...) {}

 44 #endif

 45 

 46 /* low level nand read function */

 47 #define GPBCON  (*(volatile unsigned long *)0x56000010)

 48 #define GPBDAT  (*(volatile unsigned long *)0x56000014)

 49 

 50 #define GPACON    (*(volatile unsigned long *)0x56000000)

 51 

 52 void nand_wait_ll(void)

 53 {

 54     int k;

 55     while(!(NFSTAT & 1))

 56         for(k = 0; k < 20; k++);

 57     return;

 58 //    NAND_DETECT_RB

 59 }

 60 

 61 void nand_reset_ll(void)

 62 {

 63     NAND_CHIP_ENABLE; //  Nand  

 64 //    NAND_CLEAR_RB 

 65     NFCMD = 0xff;

 66     nand_wait_ll();

 67 //    NAND_CLEAR_RB 

 68     NAND_CHIP_DISABLE; //      

 69 }

 70 

 71 

 72 unsigned char nand_read_id(unsigned char*mc,unsigned char *dc,unsigned char *pc)

 73 {

 74     int i=0;

 75     unsigned char res;

 76     NAND_CHIP_ENABLE; //  Nand  

 77     NFCMD = 0x90;

 78     for(i = 0;i < 100;i++);

 79     NFADDR = 0 & 0xFF;

 80     NFADDR = (0 >> 9) & 0xFF;

 81     NFADDR = (0 >> 17) & 0xFF;

 82     NFADDR = (0 >> 25) & 0xFF;

 83     for(i = 0;i < 100;i++);

 84     nand_wait_ll();

 85     *mc = NFDATA;

 86     *dc = NFDATA;

 87     res = NFDATA;

 88     *pc = NFDATA;

 89     NAND_CHIP_DISABLE; //      

 90     return *mc;

 91 }

 92 

 93 void nand_init_ll(void)

 94 {

 95     int TACLS = 3;

 96     int TWRPH0 = 7;

 97     int TWRPH1 = 7;

 98     int i = 0;

 99     //  gpio

100 //    GPACON = (GPACON &~(0x3f << 17)) | ( 0x3f << 17);

101     GPACON = GPACON | (0x3f << 17);

102     NFCONF = (TACLS << 12) | (TWRPH0 << 8) | (TWRPH1 << 4) | (0 << 0);

103 

104     NFCONT = (0 << 13) | (0 << 12) | ( 0 << 10) | (0 << 9) | (0 << 8) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 1) | (1 << 0);

105 

106     nand_reset_ll();

107 }

108 

109 #if 0

110 int nand_write_ll(void)

111 {

112     int i = 0x90000;

113     unsigned char j = 0;

114     NAND_CHIP_ENABLE; //  Nand  

115     NFCMD = 0x80;

116 

117     NFADDR = 0x00;

118     NFADDR = 0x00;

119     NFADDR = i & 0xFF;

120     NFADDR = (i >> 8) & 0xFF;

121     NFADDR = (i >> 16) & 0xFF;

122     for(j = 0; j < 100;j++);

123 

124 

125     NFCMD = 0x10;

126     nand_wait_ll();

127 

128     for(j = 0 ; j < 100; j++)

129     {

130         NFDATA = j;

131     }

132     NFCMD = 0x10;

133     nand_wait_ll();

134 

135     NAND_CHIP_DISABLE; //      

136     return 0;

137 }

138 #endif

139 

140 static void write_addr(unsigned int addr)

141 {

142     int col,page,i;

143     col = addr & NAND_BLOCK_MASK;

144     page = addr & NAND_SECTOR_SIZE;

145 

146     NFADDR = col & 0xff;

147     for(i = 0; i < 10; i++);

148     NFADDR = (col >> 8) & 0x0f;

149     for(i = 0; i < 10; i++);

150 

151 

152     NFADDR = page & 0xFF;

153     for(i = 0; i < 10; i++);

154     NFADDR = (page >> 8) & 0xFF;

155     for(i = 0; i < 10; i++);

156 

157     NFADDR = (page >> 16) & 0x01;

158     for(i = 0; i < 10; i++);

159 }

160 

161 static nand_read_page_ll(unsigned char *buf,unsigned long pageaddr)

162 {

163     int i = 0;

164     NAND_CHIP_ENABLE; //  Nand  

165 

166     //  READ0  

167     NFCMD = 0;

168 

169     // Nand    

170     NFADDR = 0x00;

171     NFADDR = 0x00;

172     NFADDR = pageaddr & 0xff;

173     NFADDR = (pageaddr >> 8) & 0xff;

174     NFADDR = (pageaddr >> 16) & 0xff;

175 

176     NFCMD = 0x30;

177     nand_wait_ll();

178         

179     for(i=0; i < NAND_SECTOR_SIZE; i++)

180         buf[i] = NFDATA;

181 

182     NAND_CHIP_DISABLE; //      

183 }

184 

185 int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)

186 {

187     int pageaddr = 0;

188     for(pageaddr = 0; pageaddr < 100;pageaddr++)

189     {

190         nand_read_page_ll(buf,pageaddr);

191         buf += NAND_SECTOR_SIZE;

192     }

193     return 0;

194 }

195 

nand 적었습니다.플래시 드라이브 이후 start.S에서 u-boot 자체를 호출하여 nandflash에서 sdram으로 읽습니다.
 1     bl nand_init_ll     /*  nandflash     */

 2 

 3     ldr r0, =TEXT_BASE  /*  uboot       ,      board/xinna2440/config.mk ,   0x33f80000*/

 4     mov r1, #0x0  /* nandflash 0    */

 5     mov r2, #0x30000  /*    */

 6 

 7     bl nand_read_ll    /*      */

 8     tst r0, #0x0  /*       */

 9     beq ok_nand_read

10 

11 bad_nand_read:

12     loop2: b loop2  /**/

13 

14 ok_nand_read:

15     mov r0,#0

16     ldr r1,=TEXT_BASE

17     mov r2,#0x400

18         /*    ,             sram        */

19 

20 go_next:

21     ldr r3, [r0], #4

22     ldr r4, [r1], #4

23     teq r3, r4

24     bne notmatch

25     subs r2, r2, #4

26     beq stack_setup

27     bne go_next

28 

29 notmatch:    /**/

30     loop3: b loop3           /* infinite loop */

이로써, 우리는 nandflash에서 u-boot를 시작하는 코드를 추가했고, 뒤에는led1과led2를 켜는 점등 코드를 추가했다.
1 loo:

2     ldr r4,=0x56000010

3     ldr r5,=( 1 << 10) | (1 << 12)

4     str r5,[r4]

5  

6     ldr r4,=0x56000014

7     ldr r5,=~(( 1 << 5) | ( 1 << 6))

8     str r5,[r4]

9     b loo

 
널빤지를 태우고 뛰었는데led1과led2가 우리가 예상한 대로 밝아지지 않은 것을 발견한 이유는 무엇일까?다음 번에 분해!

좋은 웹페이지 즐겨찾기