This time, u-boot-2010.09 is ported based on the FL440 board of S3C2440. The board comes with NANDFLASH but no NORFLASH, so redirection from NANDFLASH to SDRAM must be implemented during the U-BOOT startup process.
The most important one is the start.S assembly code at the beginning of U-BOOT. This code must complete the work:
1. Abnormal interrupt vector table, abnormal vector processing after reset
2. Jump to the actual execution of the code start_code
3. Turn off the watchdog WATCHDOG
3. Turn off all interrupts INTERRUPT
4. Set the clock frequency division, mainly set the registers CLKDVN, MPLLCON, UPLLCON
5. Turn off MMU and CACHE, and call lowlevel_init.S to complete the initialization of SDRAM and NANDFLASH to prepare for code redirection
6. Set up the stack and jump into the second stage C code
7. Exception vector handling code
The following is the analysis of start.S:
1. Abnormal interrupt vector table, abnormal vector processing after reset
//Declare a global scalar, which is defined in cpu/arm920t/u-boot.lds, that is, the entry address of the code, and also the compilation address
_start: b start_code
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction //.word defines a 32-bit address identifier
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef //Offset the address to an integer multiple of 16, and fill the remaining content with 0xdeadbeef, which is the "Magic Number" and can be used to determine the current u-boot execution position
_TEXT_BASE:
.word TEXT_BASE //Defined in config.mk, that is, the address from which flash is directed to sdram when u-boot starts
.globl _armboot_start //Declare a global variable and then call it
_armboot_start:
.word _start
/*
* These are defined in the board-specific linker script.
*/
.globl _bss_start //Defined in the link script u-boot.lds
_bss_start:
.word __bss_start
.globl _bss_end //Defined in the linker script u-boot.lds
_bss_end:
.word _end
#ifdef CONFIG_USE_IRQ //Stack settings
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
.word 0x0badc0de
/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
.word 0x0badc0de
#endif
2. Jump to the actual execution of the code (set management mode => turn off watchdog => turn off all interrupts => set clock division)
/*
* the actual start code
*/
start_code:
/*
* set the cpu to SVC32 mode
*/
//Set management mode 31 30 29 28 7 6 4 3 2 1 0
mrs r0, cpsr // CPSR N Z C V I F M4 M3 M2 M1 M0
bic r0, r0, #0x1f // 1 0 0 1 1
orr r0, r0, #0xd3
msr cpsr, r0 // CPSR is a status register used to set the system operation status. Only MSR MRS instructions can be used
#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK) //System interrupts are redirected to RAM for quick response to interrupts. The code to be transferred is 4*16 bytes
/* relocate exception table */
ldr r0, =_start
ldr r1, =0x0
mov r2, #16
copyex:
subs r2, r2, #1
ldr r3, [r0], #4
str r3, [r1], #4
bne copyex
#endif
// Turn off the watchdog
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
/* turn off the watchdog */
#if defined(CONFIG_S3C2400)
#define pWTCON 0x15300000
#define INTMSK 0x14400008 /* Interupt-Controller base addresses */
#define CLKDIVN 0x14800014 /* clock divisor register */
#else //Check the datesheet of s3c2440 to find the register address
#define pWTCON 0x53000000
#define INTMSK 0x4A000008 /* Interupt-Controller base addresses */
#define INTSUBMSK 0x4A00001C
#define CLKDIVN 0x4C000014 /* clock divisor register */
#endif
#define CLK_CTL_BASE 0x4C000000 //Add the clock frequency division register address for clock frequency division setting
#define MDIV_405 0x7f<<12
#define PSDIV_405 0x21
#define MDIV_200 0xa1<<12
#define PSDIV_200 0x31
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0] /* mask all IRQs by setting all bits in the INTMR - default */
mov r1, #0xffffffff //ARM920T has 32 interrupt sources, disable all interrupts, set the 32-bit interrupt mask register
ldr r0, =INTMSK
str r1, [r0]
#if defined(CONFIG_S3C2440)||defined(CONFIG_S3C2410) /* add by zhou */
ldr r1, =0x7ff //Shield all interrupt sources. In S3C2440, only the first 15 bits of the register are valid, so 0x7ff sets INTSUNMSK
ldr r0, =INTSUBMSK
str r1, [r0]
#endif
//Set the clock frequency
#if defined(CONFIG_S3C2440)
mov r1, #5
str r1, [r0]
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
mov r1, #CLK_CTL_BASE //S3C2440 system main frequency is 405MHZ, USB is 48MHZ, requiring MPLLCON = (0x7f<<12) | (0x02<<4) | (0x01) = 0x7f021
mov r2, #MDIV_405
add r2, r2, #PSDIV_405
str r2, [r1, #0x04]
#else
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #0xc0000000
mcr p15, 0, r1, c1, c0, 0
mov r1, #CLK_CTL_BASE
mov r2, #MDIV_200
add r2, r2,#PSDIV_200
str r2, [r1,#0x04]
#endif
#endif /* (CONFIG_S3C2400) || (CONFIG_S3C2410) || (CONFIG_S3C2440) */
3. Turn off MMU and CACHE, and call lowlevel_init.S to complete the initialization of SDRAM and NANDFLASH to prepare for code redirection
/**********************************************
* we do sys-critical inits only at reboot,
* not when booting from ram!
******************************************/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit //Turn off MMU and CACHE, and call lowlevel_init.S to complete the initialization of SDRAM and NANDFLASH
#endif
...........
...........
...........
/*
*************************************************** ***********************
*
* CPU_init_critical registers
*
* setup important registers
* setup memory timing
*
*************************************************** ***********************
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
cpu_init_crit:
/*
* flush v4 I/D caches
*/
mov r0, #0 //For specific settings, see the figure below. For details, refer to CP15 instructions: http://blog.csdn.net/gooogleman/article/details/3635238
mcr p15, 0, r0, c7, c7, 0 //Writing 0 to c7 will invalidate ICache and DCache flush v3/v4 cache
mcr p15, 0, r0, c8, c7, 0 //Writing 0 to c8 will invalidate the TLB flush v4 TLB
/*
* disable MMU stuff and caches //The C1 processor of the coprocessor CP15 can set MMU and caches. Please refer to the figure below for details.
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependent, you will
* find a lowlevel_init.S in your board directory.
*/
mov ip, lr //Since there are two layers of calls, lr needs to be saved to ip to prevent damage
bl lowlevel_init //Call C function to initialize FLASH and SDRAM to prepare for code redirection
mov lr, ip
mov pc, lr //return
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
The basic idea of code redirection:
1. Whether the memory is running or not, if yes, set up the stack and jump into the C function stage
2. If it is not running in memory, determine whether it is running in norflash or nandflash
//Code redirection part
/******************CHECK_CODE_POSITION******************************/
adr r0, _start /* r0 <- current position of code */ //Check if the code is already running in SDRAM, if so, set up the stack and jump into the C code section
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ //_start is the real running address of u-boot, _TEXT_BASE is the address of FLASH loaded into SDRAM, defined as 0x33f80000 in config.mk
cmp r0, r1 /* don't reloc during debug */ //If they are equal, it means it is already running in SDRAM, set up the stack, and transfer to the second stage C function
beq stack_setup //If they are not equal, determine whether to boot from NORFLASF or NANDFLASH
/******************CHECK_CODE_POSITION******************************/
/******************CHECK_BOOT_FLASH************************************/
ldr r1, =((4<<28)|(3<<4)|(3<<2)) /*address in 4000003c*/
mov r0, #0 //NANDFLASH startup principle, when starting, 4K SRAM, namely Stepping Stone, will be mapped to nGCS0, 0x0000 0000 address, and it will also be mapped to 0x4000 0000 address
str r0,[r1] //NORFLASH supports on-chip operation and will be mounted to nGCS0,0x0000 0000. For details, please refer to the NANDFLASH startup principle
mov r1, #0x3c /*address in 0x3c*/ //When NANDFLASH starts, because the address is aligned to a multiple of 16, 0x0000 003c and 0x4000 003c are both uniquely identified as 0xdeadbeef, i.e. "Magic Mumber"
ldr r0, [r1] //When 0x4000 003c is cleared, if 0x0000 003c is also read as zero, the u-boot code starts from NANDFLASH, otherwise it starts from NORFLASH
cmp r0, #0
bne relocate
Previous article:Analysis of nandflash initialization process in u-boot
Next article:S3C2440 storage controller learning record
Recommended ReadingLatest update time:2024-11-23 08:29
- Popular Resources
- Popular amplifiers
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- Analysis of embedded C language pointers
- STM8 PID heating stage
- MSP430 emulator instructions and msp430f5438 minimum system circuit
- Which domestic fast-charging chip is the best?
- What does 0402_SHORT mean in the schematic diagram and how to draw the PCB
- Analysis of the reasons why MLCC (chip) capacitors make squeaking sounds
- [Raspberry Pi Pico Review] How to use the buttons
- CB140 core board voltage value difference solution
- BrainPad Pulse and BrainPad Tick development boards with micropython support
- Embedded Qt - Write and run your first ARM-Qt program