Http://www.linuxfans.org/bbs/thread-182694-1-1.html
1. Download u-boot-1.1.4.tar.bz2 and decompress it.
2. Copy the arm-linux-2.95.3 to/usr/local/ARM/2.95.3/
3. Edit the MAKEFILE file of the U-boot directory.
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
Sxw.config: unconfig
@./Mkconfig $ (@: _ Config =) arm arm925t SX1
4. Copy necessary files
CP-Arn board/smdk2410/board/sky2410
MV board/sky2410/smdk2410.c board/sky2410/sky2410.c
CP include/configs/smdk2410.h include/configs/sky2410.h
5. Modify the Board/smdk2410/makefile
Lib = Lib $ (board).
Objs: = sky2410.o flash. o
Sobjs: = lowlevel_init.o
6. Test make.
Make sky2410_config
Make
Error
C0: Invalid option 'Abi = APCs-GNU'
Modify the file CPU/ARM920T/config. mk
Platform_cppflags + = $ (call CC-option,-mapcs-32,-mabi = APCs-GNU)
Changed:
Platform_cppflags + = $ (call CC-option,-mapcs-32, $ (call CC-option,-mabi = APCs-GNU ),)
Make again
7. Start transplantation of NAND
Modify CPU/ARM920T/start. s
Change from flash to NAND Flash.
Rewrite the following U-boot statement segment:
# 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 [R0] */
Stmia R1 !, {R3-r10}/* Copy to target address [R1] */
CMP r0, R2/* Until source end addreee [R2] */
Ble copy_loop
# Endif/* config_skip_relocate_uboot */
Replace:
# 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 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
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 */
After "_ start_armboot:. Word start_armboot", add:
. Align 2
Dw_stack_start:. Word stack_base + STACK_SIZE-4
8.
(I) modify the Board/smdk2410/makefile
Objs: = sky2410.o flash. o
(Ii) modify the Board/sky2410/lowlevel_init.s
# Define ublb (0x1 <3)
# Define bw.bwscon (dw16)
# Define b2_bwscon (dw16)
# Define b3_bwscon (dw16 + wait + ublb)
# Define b4_bwscon (dw16)
(Iii) Create the Board/smdk2410/nand_read.c File
# Include <config. h>
# 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 ++ );
}
/* 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. Modify include/configs/sky2410.h.
Add
/*
* 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.
Test it with make.
Here, U-boot can be started from NAND.
The following describes how to add NAND commands for U-boot.
11. Modify include/configs/sky2410.h.
(I) Remove the comment of ipv_0000_nand.
# Define config_commands/
(Config_cmd_dfl |/
Pai_pai_cache |/
Performance_0000_nand |/
/* Cmd_cmd_eeprom | *//
/* Cfg_cmd_i2c | *//
/* Cfg_cmd_usb | *//
Pai_pai_reginfo |/
1__1__date |/
Pai_pai_elf)
(Ii) modify the content we modified in step 1
# Define pai_nand_legacy
# Define 1__env_offset 0x20000
# If (config_commands & cmd_cmd_nand)
# Define pai_nand_base 0x4e000000
/* Nandflash controller start Register address in SFr zone */
# Define pai_max_nand_device 1
/* The most supported NAND Flash data */
# Define sectorsize 512
/* 1 page size */
# Define nand_sector_size sectorsize
# Define nand_block_mask 511
/* Page mask */
# Define addr_column 1
/* One-byte column address */
# Define addr_page 3
/* 3-byte page block address !!!!! */
# Define addr_column_page 4
/* Page block address of 4 bytes in total !!!!! */
# Define nand_chipid_unknown 0x00
/* Unknown chip ID */
# Define nand_max_floors 1
# Define nand_max_chips 1
/* Underlying interface functions of the NAND Flash command Layer */
# 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 must be added */
# Define nand_ctl_clrale (nandptr)
# Define nand_ctl_setale (nandptr)
# Define nand_ctl_clrcle (nandptr)
# Define nand_ctl_setcle (nandptr)
/* Allow NAND Flash write verification */
# 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_assist_nand */
12. Modify the Board/sky2410/sky2410.c
Add at the end of the file
# If (config_commands & cmd_cmd_nand)
Typedef Enum {
Nfce_low,
Nfce_high
} Nfce_state;
Static inline void nf_conf (2010conf)
{
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_0000w (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 & cmd_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 XXX, r XXX, r xxx */
/* En 512b 4 step 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
Now I have completed the modification of the uboot NAND command.
The above steps can be basically found online
However, if you use it directly, skyeye1.2.4 will report an error.
Smdk2410 # NAND read 33000000 0 20000
Nand read: The device 0 offset 0, size 131072... warning when re falling, do nothing
0 bytes read: Error
It took the last day to track Skyeye and U-boot and finally found the cause of the error.
When u-boot reads OOB data
Nand_command (nand, nand_assist_readoob)
Then
Nand_address (nand, addr_column_page
At this time, the NAND simulated by Skyeye is ready for data.
Actually, read_nand (nandptr) can be used directly.
However, in the nand_readbuf function of U-boot, another nand_command (nand, nand_assist_read0) is sent );
As a result, Skyeye considers that the command has changed and then waits for nand_address (nand, addr_column_page.
However, U-boot directly starts reading data after sending nand_command (nand, nand_assist_read0 ).
Skyeye considers that there is no sending Address and an error is reported.
The simplest way is to comment out the nand_command (nand, nand_cmd_read0) in nand_readbuf.
No problem ~~
In addition, I have also tested that the modified U-boot downloaded to my Development Board has been detected without any problems.