Code relocation (nand->sdram) in s3c6410_uboot

Publisher:breakthrough2Latest update time:2024-09-04 Source: cnblogsKeywords:s3c6410  uboot  nand  sdram Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

This article only discusses the code relocation process when s3c6410 starts u-boot from nand flash


reference:


1) "USER'S MANUAL-S3C6410X" Chapter 2 MEMORY MAP Chapter 8 NAND FLASH CONTROLLER


2) u-boot source code:


u-boot-x.x.x/board/samsumg/smdk6410/lowlevel_init.S


u-boot-x.x.x/cpu/s3c64xx/start.S


u-boot-x.x.x/cpu/s3c64xx/nand_cp.c


A brief description of the code relocation process


Since the code cannot be run in nand flash, when the development board boots from nand flash, we need to move the u-boot code stored in the peripheral nand flash to sdram for execution. How to complete this task? This requires the help of a stepping stone, which is a built-in sram of s3c6410. When the development board is powered on, the nand flash controller automatically copies the first 8K of nand flash to sram and executes it. In addition to initializing the hardware, the most important task of this small startup code is to copy (i.e. relocate) all the u-boot codes in nand flash to the specified address of sdram, and then jump to sdram for execution.


Relocation code analysis:


1) NAND interface initialization


When u-boot starts, it first executes start.S of the corresponding hardware platform. In start.S, lowlevel_init is called to initialize the underlying hardware such as clock, uart, nand, mmu, etc.


start.S:


...

bl    lowlevel_init    /* go setup pll,mux,memory */

...

lowlevel_init.S:


...

/*

* Nand Interface Init for SMDK6400 */

nand_asm_init:

ldr    r0, =ELFIN_NAND_BASE

ldr    r1, [r0, #NFCONF_OFFSET]

orr    r1, r1, #0x70

orr    r1, r1, #0x7700

str     r1, [r0, #NFCONF_OFFSET]


ldr    r1, [r0, #NFCONT_OFFSET]

orr    r1, r1, #0x03

str     r1, [r0, #NFCONT_OFFSET]


mov    pc, lr

...


2) Code relocation


When booting from nand flash, the relocation code is as follows:


start.S:


/* when we already run in ram, we don't need to relocate U-Boot.

* and actually, memory controller must be configured before U-Boot

* is running in ram.

*/

ldr    r0, =0xff000fff

bic    r1, pc, r0        /* r0 <- current base addr of code */

ldr    r2, _TEXT_BASE        /* r1 <- original base addr in ram */

bic    r2, r2, r0        /* r0 <- current base addr of code */

cmp     r1, r2                  /* compare r0, r1                  */

beq     after_copy        /* r0 == r1 then skip flash copy   */


#ifdef CONFIG_BOOT_NAND

mov    r0, #0x1000

bl    copy_from_nand

#endif


r1 stores the starting address of the current code, and r2 stores the address where u-boot will run in sdram. If the two addresses are equal, it means that u-boot is already running in sdram and there is no need to copy data from nand to sdram. Otherwise, u-boot is still executing in its temporary residence sram, where it cannot stay for long. It is necessary to execute copy_from_nand to copy the u-boot code completely to sdram, and then jump to sdram to execute the rest of the code.


/*

* copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND)

* r0: size to be compared

* Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size

*/

.globl copy_from_nand

copy_from_nand:

mov    r10, lr        /* save return address */


move r9, r0

/* get ready to call C functions */

ldr    sp, _TEXT_PHY_BASE    /* setup temp stack pointer */

sub    sp, sp, #12

mov    fp, #0            /* no previous frame, so fp=0 */

move r9, #0x1000

bl    copy_uboot_to_ram


3:    tst     r0, #0x0

bne    copy_failed


ldr    r0, =0x0c000000

ldr    r1, _TEXT_PHY_BASE

1:    ldr    r3, [r0], #4

ldr    r4, [r1], #4

teq r3, r4

bne    compare_failed    /* not matched */

subs    r9, r9, #4

bne 1b


4:    mov    lr, r10        /* all is OK */

mov    pc, lr


copy_failed:

nop            /* copy from nand failed */

b    copy_failed


compare_failed:

nop            /* compare failed */

b    compare_failed


The function that actually performs the copy operation is copy_uboot_to_ram, which is defined in u-boot-xxx/cpu/s3c64xx/nand_cp.c.


int copy_uboot_to_ram (void)

{

int large_block = 0;

int i;

vu_char id;

NAND_ENABLE_CE();

NFCMD_REG = NAND_CMD_READID;

NFADDR_REG = 0x00;


/* wait for a while */

for (i=0; i<200; i++);

id = NFDATA8_REG;

id = NFDATA8_REG;


if (id > 0x80)

large_block = 1;


/* read NAND Block.

* 128KB ->240KB because of U-Boot size increase. by scsuh

* So, read 0x3c000 bytes not 0x20000(128KB).

*/

return nandll_read_blocks(CFG_PHY_UBOOT_BASE, 0x3c000, large_block);

}


NAND flash supports two page sizes, 512B and 2KB. When large_block = 0, the page size is 512 bytes, and when large_block = 1, the page size is 2KB. nandll_read_blocks copies the data of size 0x3c00 (240KB) of NAND flash starting from page 0 to the CFG_PHY_UBOOT_BASE address of SDRAM.


/*

* Read data from NAND.

*/

static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)

{

fly *buf = (fly *)dst_addr;

int i;

uint page_shift = 9;


if (large_block)

page_shift = 11;


/* Read pages */

for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<

nandll_read_page(buf, i, large_block);

}


return 0;

}


First, the size of a nand flash page is determined based on large_block, and the number of pages that need to be copied is calculated, that is, (0x3c000>>page_shift) pages need to be copied, and nandll_read_page only copies one page of data each time.


/*

* address format

*              17 16         9 8            0

* --------------------------------------------

* | block(12bit) | page(5bit) | offset(9bit) |

* --------------------------------------------

*/


static int nandll_read_page (uchar *buf, ulong addr, int large_block)

{

int i;

int page_size = 512;


if (large_block)

page_size = 2048;


NAND_ENABLE_CE();


NFCMD_REG = NAND_CMD_READ0;


/* Write Address */

NFADDR_REG = 0;


if (large_block)

NFADDR_REG = 0;


NFADDR_REG = (addr) & 0xff;

NFADDR_REG = (addr >> 8) & 0xff;

NFADDR_REG = (addr >> 16) & 0xff;


if (large_block)

NFCMD_REG = NAND_CMD_READSTART;


NF_TRANSRnB();


/* for compatibility(2460). u32 cannot be used. by scsuh */

for(i=0; i < page_size; i++) {

*buf++ = NFDATA8_REG;

}


NAND_DISABLE_CE();

return 0;

}


The process of reading data from nand flash is chip select (NAND_ENABLE_CE) -> send read command (NFCMD_REG) -> send address (NFADDR_REG) -> send read command (NFCMD_REG) -> wait for data to be readable (NF_TRANSRnB) -> read data (NFDATA8_REG). Since only 1 byte of data can be read from NFDATA8_REG each time, it takes 512 or 2048 times to copy one page.


When copy_uboot_to_ram is executed and returns to start.S, the code relocation in nand flash is completed. After that, the program jumps to sdram for execution, and the stepping stone's responsibility ends.


Keywords:s3c6410  uboot  nand  sdram Reference address:Code relocation (nand->sdram) in s3c6410_uboot

Previous article:s3c6410_MMU address mapping process details
Next article:s3c6410_uart initialization and reading and writing

Recommended ReadingLatest update time:2024-11-15 17:19

uboot porting process on ARM s3c2410
Overview u-boot is a bootloader program developed by the German DENX team for various embedded CPUs. The u-boot software currently under development can be obtained through CVS under LINUX. The current version number is: u-boot 1.0.2, see the definition in include/version.h. #cvs –dserver:anonymous@cvs.sourceforge.ne
[Microcontroller]
Implementation of s3c6410 timer interrupt
Related content in the 6410 manual five 32-bit timers Timers 0 and 1 include a PWM function Each timer has its own 32-bit down-counter which is driven by the timer clock. The down-counter is initially loaded from the Timer Count Buffer register (TCNTBn). When the down-counter reaches zero, the timer interrupt req
[Microcontroller]
Implementation of s3c6410 timer interrupt
LED: Control light emitting diode
1. The LED drive implementation principle is as shown in the figure: 2. Write LED driver (1) Create the device file for the LED driver Step 1: Initialize cdev using the cdev_init function Step 2: Specify the device number Step 3: Use the cdev_add function to add the character device to
[Microcontroller]
LED: Control light emitting diode
S5PV210 (TQ210) study notes - Nand configuration
  The Nand flash configuration of S5PV210 is similar to that of 2440 and 6410, but the difference is that S5PV210 has more powerful functions, especially the hardware ECC of S5PV210 (this article does not cover the Nand ECC configuration of S5PV210). Overall, the Nand flash configuration of S5PV210 is still very simpl
[Microcontroller]
S5PV210 (TQ210) study notes - Nand configuration
s3c2440 Learning Road-011 Code Relocation
1 Basic principles Following the last blog s3c2440 learning path-010 sdram, sdram has been initialized, and now the value of SDRAM can be officially brought into play. (SDRAM can be read and written at will, and the subsequent codes will be placed on it to run) 1.1 Division of program segments After a program is com
[Microcontroller]
s3c2440 Learning Road-011 Code Relocation
UART device driver for s3c6410(5)
This function was mentioned in the previous article. The source code is as follows: static int s3c6400_serial_probe(struct platform_device *dev) {  dbg("s3c6400_serial_probe: dev=%pn", dev);  return s3c24xx_serial_probe(dev, &s3c6400_uart_inf); } Now let’s continue: int s3c24xx_serial_probe(struct platform_devic
[Microcontroller]
s3c2440 bare metal-memory controller (5. SDRAM programming implementation)
Configuring Memory Controller-SDRAM Programming Configuration The 2440 memory controller has a total of 13 registers. BANK0--BANK5 only need to set two registers, BWSCON and BANKCONx (x is 0~5); When BANK6 and BANK7 are externally connected to SDRAM, in addition to BWSCON and BANKCONx (x is 6 and 7), four registers
[Microcontroller]
s3c2440 bare metal-memory controller (5. SDRAM programming implementation)
Research on Low Power Design of Embedded DSP Accessing Off-Chip SDRAM
The limited on-chip memory capacity of DSP often makes designers feel stretched, especially in applications such as digital image processing and voice processing, which require strong support from high-speed and large-capacity storage space. Therefore, external memory is needed to expand the storage space of DSP. In D
[Embedded]
Research on Low Power Design of Embedded DSP Accessing Off-Chip SDRAM
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号