Practice of uboot transplantation of Mini440

1, u-boot process

1.1 u-boot flow chart drawing

In previous blogs, we have analyzed the source code of u-boot. So let's try to connect what we introduced in the previous sections. Draw a u-boot startup flowchart:

2, Steps of u-boot migration

Since we want to transplant u-boot, we first need to understand the startup process of u-boot. U-boot migration can be divided into the following steps:

  • Kernel level configuration and initialization;
  • SOC level configuration and initialization;
  • board_init_f;
  • u-boot relocation;
  • board_init_r;
  • Start the kernel or process user commands;

two point one   Kernel level configuration and initialization

This is mainly the assembly code in the start.S file, mainly including:

  • Turn on SVC mode, turn off FIQ and IRQ interrupt;
  • Close the watchdog
  • Mask all interrupts;
  • Set the system clock;
  • Execution cpu_init_crit function;
    • Close MMU and cache;
    • lowlevel_init function;

This part is the code closely related to the kernel. The configuration of this part is slightly different according to different kernels.

two point two   SOC level configuration and initialization

There are a lot of contents in this part, and it can be said that it runs through the whole u-boot, but it is basically necessary to focus on the low level_ Init, the rest depends on whether you want to use some hardware resources in the u-boot phase.

For example, the network card is on the board_init_r is already in the back position. Some boards may not even use the network in the u-boot stage. Naturally, initialization is not required.

This part is modified a lot during the migration process, and assembly coding is basically used. As long as this part is completed, the u-boot can be started successfully.

2.3 board_init_f

This stage is mainly for memory planning after u-boot relocation. Although there are many sub functions, they are not complex. Less transplant content.

two point four   u-boot relocation

This part of the code basically does not need to be changed.

2.5 board_init_r

The main task in this stage is to prepare the terminal and initialize the hardware resources needed. If a new driver model is used, the hardware should be abstracted like the kernel. According to their own needs, we should change what we use.

two point six   Start the kernel or process user commands

The biggest mission of u-boot is to start the kernel, so this part is also the core content. board_init_r finally calls run_main_loop enters a loop, either directly starts the kernel or enters the terminal to process user commands and user interaction. It can also be said that there is no need to change. It is almost done by pure software.

3, Add board

Since u-boot-2016.05 supports S3C2410 development board, we can directly copy the relevant files of S3C2410 board to S3C2440.

three point one   Create a board directory in board (board / sampling / smdk2440)

cd board/samsung/
cp smdk2410 -r smdk2440

Enter smdk2440 path:

Modify the file Kconfig:


config SYS_BOARD
        default "smdk2440"

        default "samsung"

config SYS_SOC
        default "s3c24x0"

        default "smdk2440"


Modify MAINTAINERS file:

M:      David Müller <>
S:      Maintained
F:      board/samsung/smdk2440/
F:      include/configs/smdk2440.h
F:      configs/smdk2440_defconfig

As you can see from here, we also need to create include / configurations / smdk2440. H and configs/smdk2440_defconfig.

Modify Makefile file:

# (C) Copyright 2000-2006
# Wolfgang Denk, DENX Software Engineering,
# SPDX-License-Identifier:      GPL-2.0+

obj-y   := smdk2440.o
obj-y   += lowlevel_init.o

smdk2410.c renamed smdk2440.c

mv smdk2410.c smdk2440.c

three point two   Create a board related header file (include / configure / smdk2440. H)

Similarly, we copy the smdk2410.h file in the include / configurations / directory as smdk2440.h:

cd include/configs
cp smdk2410.h smdk2440.h

This file is very important. It is mainly used to configure whether to enable some functions when compiling u-boot, such as network card, LCD, etc. if defined, the code of relevant modules will be compiled.

Modify string 2410 - > 2440 in smdk2440.h:

#define CONFIG_S3C2440          /* specifically a SAMSUNG S3C2440 SoC */
#define CONFIG_SMDK2440         /* on a SAMSUNG SMDK2440 Board */
 * NAND configuration
#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_NAND_BASE            0x4E000000

three point three   Create defconfig file

Executing make smdk2440_defconfig, which depends on configs/smdk2440_defconfig file, so we will also smdk2410_ Copy defconfig:

cd configs
cp smdk2410_defconfig smdk2440_defconfig

Modify smdk2440_defconfig:


3.4 modify arch/arm/Kconfig file

vim arch/arm/Kconfig

Add the following:

config TARGET_SMDK2440
    bool "Support smdk2440"
    select CPU_ARM920T

source "board/samsung/smdk2440/Kconfig"

three point five   Try configuring and compiling

After completing the above steps, we have completed the addition of S3C2440 board. Although S3C2410 is copied, we only need to modify it based on the S3C2410 configuration file.

make smdk2440_config
make ARCH=arm CROSS_COMPILE=arm-linux- V=1

The first step can be compiled successfully, and the second step will fail, mainly because we configured NAND in include / configurations / smdk2440. H, but we did not migrate the relevant code.

IV   Kernel level configuration and initialization (arch/arm/cpu/arm920t/start.S)

Let's first analyze the arch/arm/cpu/arm920t/start.S file to see if there are any changes that need to be made.

The first thing we need to change is the clock system setting. Initialize the system clock FCLK = 400MHz,HCLK = 100MHz, PCLK = 50MHz, UPLL=48MHz.

#ifdef CONFIG_S3C24X0
        /* turn off the watchdog */

# if defined(CONFIG_S3C2400)
#  define pWTCON        0x15300000
#  define INTMSK        0x14400008      /* Interrupt-Controller base addresses */
#  define CLKDIVN       0x14800014      /* clock divisor register */
#  define pWTCON        0x53000000
#  define INTMSK        0x4A000008      /* Interrupt-Controller base addresses */
#  define INTSUBMSK     0x4A00001C
/*  Initialize the system clock FCLK = 400MHz,HCLK = 100MHz, PCLK = 50MHz, UPLL=48MHz  */
#  define LOCKTIME      0x4c000000
#  define MPLLCON       0x4c000004
#  define EQU  UPLLCON  0x4c000008
#  define CLKDIVN       0x4c000014
#  define  M_MDIV       92       /* Fin=12M  UPLL=400M  */
#  define  M_PDIV       1
#  define  M_SDIV       1
#  define  U_MDIV       56        /* Fin=12M  UPLL=48M  */
#  define  U_PDIV       2
#  define  U_SDIV       2
#  define  DIVN_UPLL    0         /* FCLK:HCLK:PCLK=1:4:8 */
#  define  HDIVN        2
#  define  PDIVN        1
# endif

        ldr     r0, =pWTCON
        mov     r1, #0x0
        str     r1, [r0]

         * mask all IRQs by setting all bits in the INTMR - default
        mov     r1, #0xffffffff
        ldr     r0, =INTMSK
        str     r1, [r0]
# if defined(CONFIG_S3C2410)
        ldr     r1, =0x3ff
        ldr     r0, =INTSUBMSK
        str     r1, [r0]
# endif

        /* Set Lock Time  */
        ldr     r0, =LOCKTIME
        ldr     r1, =0xffffffff
        str     r1, [r0]

        /* Set frequency division coefficient */
        ldr     r0, =CLKDIVN
        ldr     r1, =((DIVN_UPLL<<3) | HDIVN <<1 | PDIVN)
        str     r1, [r0]

        /* CPU Change to asynchronous bus mode */
        mrc      p15,0,r1,c1,c0,0
        orr      r1, r1,#0xC0000000
        mcr      p15,0,r1,c1,c0,0

        /* Set UPLL */
        ldr      r0, =UPLLCON
        ldr      r1, =((U_MDIV<<12) | (U_PDIV<<4) | U_SDIV)
        str      r1, [r0]


        /* Set MPLL */
        ldr     r0, =MPLLCON
        ldr     r1, =((M_MDIV << 12) | (M_PDIV << 4) | M_SDIV)
        str     r1, [r0]

#endif  /* CONFIG_S3C24X0 */

5, SOC level configuration and initialization (board / sampling / smdk2440 / low level_init. S)

In lowlevel_ The init. S file mainly contains the code for initializing SDRAM. The initialization of SDRAM depends on our external SDRAM chip.

Take the Mini2440 development board as an example: two pieces of 32MB, 16 bit wide SDRAM memory (model HY57V561620FTP) are welded to Bank6 to form 64M, 32-bit memory in parallel. Therefore, here we mainly focus on the configuration related to Bandk6.

We will the configuration and Memory controller for Mini2440 bare metal development To compare the codes in, we need to modify the following:

#define REFCNT            1269     /* period=7.8125us, HCLK=60Mhz, (2048+1-7.8125*100) */

Change BANKSIZE to 0xB1:

    .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
    .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
    .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
    .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
    .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
    .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
    .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
    .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
    .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
    .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
    .word 0xB1
    .word 0x30
    .word 0x30

  Vi   board_init_f

We will not modify this piece of code.

7, u-boot relocation

  We don't modify this piece of code.


Reference articles

[1]1. Transplant uboot - analyze uboot startup process (detailed explanation)

[2]u-boot2020.04 migration (summary)

[3]U-BOOT-2016.07 porting (Part II) adding boards

Posted by assafbe on Tue, 30 Nov 2021 13:53:45 -0800