introduction
The boot loader is usually the first code executed on the hardware. Although there are a large number of boot loaders in the Linux open source community, these boot loaders are too complex and lengthy for applications on many embedded devices. To this end, this article specifically designs a small boot loader program for the PowerPC E300 series processor chip and names it Genesis. The program has a simple structure and complete functions, and can well boot the Linux kernel and file system.
Environmental requirements and system images
Hardware Environment
The hardware environment developed in this article is as follows: the processor uses the MPC83xx series; the memory uses 512M DDR2 memory; the flash memory uses 8MB flash memory; the serial port uses uart16550; the baud rate uses 115200.
Compilation environment
The program is compiled under mvl-linux, linux-kernal-2.6.10 and gcc compiler environment.
System file storage image
The Genesis program is stored in a flash memory. For a small Linux system, the kernel and file system are compiled together with the bootloader to generate binary files, which are finally stored in the flash memory and moved to the memory for execution after power-on. Figure 1 is a schematic diagram of the compiled system file code in the flash memory and after it is moved to the memory.
Figure 1 System file image
Implementation of Genesis
The main structure of Genesis
A fully functional boot loader BootLoader must go through the following steps, namely: initialize the CPU; initialize the memory, including enabling memory banks, initializing memory configuration registers, etc.; initialize the serial port (if available on the target board); enable instruction/data cache; set the stack pointer; set the parameter area and construct the parameter structure and tags (this is an important step because the kernel uses boot parameters when identifying the root device, page size, memory size, and more); turn on/off the watchdog; call the main entry function; jump to the beginning of the kernel.
Establishment of program model
According to the main structure of Genesis, this paper establishes several most important code programs in the program body: entry.S; board.c; cpu.c; console.c; main.c. The execution order of these programs is shown in Figure 2.
Figure 2 Schematic diagram of program execution sequence [page]
Programming
Here, entry.S is the entry point of the program. The codes in entry.S are all assembly instructions. The whole program revolves around these assembly codes.
The function of cpu.c is to initialize the CPU core, CPU main controller and system clock controller; board.c is mainly used to initialize peripheral devices closely related to the target board, including flash memory, CPLD and system memory; console.c is the serial port initialization program of the target board, which initializes the serial port of the CPU and configures the serial port rate; the function of main.c is to boot the Linux kernel and file system.
When the CPU is powered on or a reset signal is applied, the CPU determines its state by reading the value on the data bus D[0:31] or according to the internal default constant D[0:31]=0x00000000. If the signal pin RSTCONF# is low when the CPU reads the bus value, the hardware reset configuration word (HRCW) is read from the bus; if RSTCONF# is high, HRCW uses the internal default value. After power-on, the startup storage controller CSO# (corresponding to the chip select signal of the flash memory) is valid, the flash memory is selected, and the CPU address line outputs the address 0x00000100 corresponding to the hardware reset interrupt vector, and starts reading the first instruction. In Genesis, this instruction corresponds to the _start: label in entry.S. The code segment is as follows.
_start:
b boot_cold
boot_cold:
lis r4, DEFAULT_IMMR_ BASE@h
nop
boot_warm:
mfmsr r5
lis r3, IMMR_BASE@h
times r3, r3, IMMR_BASE@l
stw r3, IMMR(r4)
Next, initialize and configure the CPU CORE. First, turn off the CPU watchdog. The code is as follows:
xor r4, r4, r4
stw r4, SWCRR(r3)
Mask all interrupt registers and initialize caches D-CACHE and I-CACHE:
.globl icache_enable
.globl icache_disable
.globl icache_status
.globl dcache_enable
.globl dcache_disable
.globl dcache_status
Then remap the absolute address of the flash memory using code like this:
map_flash_by_law1:
remap_flash_by_law0:[page]
Set up the stack in the high-speed cache area opened inside the CPU. Before the external DRAM of the device is initialized, only the cache inside the CPU can be used as memory. The next step is to enter the second stage of CPU initialization, that is, the C language environment:
setup_stack_in_data_cache_on_r1:
After the stack is built, it immediately enters step S1, which jumps to the cpu_init() function in cpu.c. In this code, all CPU control registers are configured. The statement to call a C function in assembly is bl cpu_init.
When the configuration is completed, enter step S2, and the pointer returns to entry.S. Then execute and call the board_init function, enter step S3, jump to board.c, and execute the board_init() function. This function includes several important parts.
1) get_clocks() function
Initialize the CPU's PLL and system clock registers.
2) init_timebase() initializes the counter
3) Initialize the serial port: serial_init (port, baudrate)
The earlier you open the serial port, the better it will be for the subsequent work. serial_init() calls console.c. For the MPC83xx series processors with E300 core, two sets of UART interfaces are generally provided to support RS232, UART16550, HDLC and other applications. This article uses UART1 as a serial output interface and uses the PC16550 protocol. Since many subsequent debugging will rely on the debug interface, it is more important to configure and initialize the serial port. Here, it is mainly noted that the offset addresses of UART1 and UART2 are 0x4500 and 0x4600 respectively, and their baud rates are obtained from the CSB_CLK clock division.
4) DDR RAM initialization: long int initdram (int board_type)
This is a very important step. If the DDR RAM is not configured correctly, the following work will not be able to proceed. DDR2 type memory sticks are used on the target board. This design can dynamically adjust the size of the memory used, and greatly reduce the configuration work of the DDR memory. Generally speaking, there is an eeprom on the DDR memory stick, which stores basic DDR information. It provides a standard I2C interface for the CPU to access. So in this system, the basic information on the DDR memory stick is read through I2C, and then the CPU's DDR controller is correctly configured based on this information. The I2C driver is easy to find in the open source code, and then it can be slightly modified according to the CPU used.
After the DDR memory is initialized, go to step S4 and return to entry.S. Then execute step S5 to call the function run_into_ram() in main.c to move the code. Call the relocate_code() function in entry.S and execute step S6 to copy the code from the flash memory to the DDR RAM: global relocate_code.
After the copy is completed, jump directly to the main() function: bl main. At this point, the initialization of the CPU and external basic devices is completed. Next, the Linux kernel can be correctly booted. Using code copying, copy the Linux kernel stored in the flash memory to the DDR RAM, then jump directly to the address and start executing step S7.
copy_code((void *)dest_addr,(void *)img_begin, img_end - img_begin);
jImage=(void (*)(void))dest_addr;
(*jImage)();
There are also steps S8 and S9 in the program flow chart. They represent the pointer jump direction when executing the reset command under Genesis and Linux respectively. When resetting, the program returns to entry.S and then re-executes.
Conclusion
Download the bin file designed and compiled according to the process to the target board. After testing, it can correctly boot the Linux kernel and file system, realizing the function of BootLoader. In order to enrich the functions of Genesis, some supplementary development can be carried out, such as adding Genesis command line editing; adding read and write commands of device address space, etc.
References
1.Programming Environments Manual for 32-Bit Implementations of the PowerPC Architecture, Rev. 3, Copyright 9/2005 by Freescale Semiconductor Corporation
2.e300 PowerPC Core Reference Manual, Rev. 1, Copyright 8/2005 by Freescale Semiconductor Corporation
3.MPC8360E PowerQUICC II Pro Integrated Host Processor Family Reference Manual, Rev. 1, Copyright 2006 by Freescale Semiconductor Corporation
Previous article:ARM Video Monitoring System Based on WinCE
Next article:Application of uC/OS-II in GPRS Terminal System
Recommended ReadingLatest update time:2024-11-16 17:42
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Looking for package SOT128-1
- 【Qinheng RISC-V core CH582】Timer PWM drive servo
- Selection and use of bypass capacitors
- CircuitPython Holiday Wreath
- Application and advantages of mica capacitors
- First Battlefield
- Infrared remote control LED dot matrix
- [Chuanglong TL570x-EVM] Install Prossessor SDK and create a development environment
- NRK3301 speech recognition chip schematic
- Microchip Live Today: How to Build a Car Charger