The start stage of U-boot is divided into two, the first part is start. s file, post as much as possible to analyze the meaning of each line of code, see a lot of manuals, the purpose of the analysis is to learn it, blog is also want to give their own learning to leave something, these things online is actually a lot, but feel to read others write and the words of their own analysis to write again, the difference is great. Reprint please indicate the source, the following into the topic.
Line 11th:
The #include <asm-offsets.h>//is automatically generated by kbuild, and no matter
header files with other generic header files under #include <common.h>//include
#include <config.h>//Many architectures have a configuration header file for the respective system
A Start_code and CPSR Analysis
Line 24th:
. globl _start
_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
Here starting from _start, the first sentence, B start_code meaning is to jump to start_code this part. Let's cut over to see.
On line 79th:
Start_code:
/*
* Set the CPU to SVC32 mode
*/
Mrs R0, CPSR
Bic R0, R0, #0x1f
Orr R0, R0, #0xd3
MSR CPSR, R0
This part is to set the CPU to SVC32 mode, we know arm has 7 modes of operation, here is set to the highest level, generally we are working in USR mode.
Mrs R0,CPSR
Send the contents of the status register CPSR to the general register R0
Bic R0, R0, #0x1f
The beginning of this sentence is the low 5-bit zeroing of the r0. The BIC directive means a logical "and" operation of the inverse of the value and the Operand2 value in Rn.
Orr R0, R0, #0xd3
Here is the setting r0 inside of the low 5 bit for 10011, which is the SVC mode, while the IRQ and Fiq are turned off.
MSR Cpsr,r0
Writes the value of the R0 back to CPSR.
Here we look at s3c2440 's datasheet:
Here is the definition of the CPSR register bits, we are here to focus on low eight-bit, 0 to 5 bit set operation mode, the figure below gives the corresponding bits of each mode should set the value. 5,6,7 three bits corresponding to the status bit, Fiq and IRQ, the above to R0 assignment 0xd3 is 11010011, corresponding to go into a glance.
Two Off interrupt, clock setup analysis
Line 102th below:
#ifdef config_s3c24x0
/* Turn offthe watchdog */
# if defined (config_s3c2400)
# define Pwtcon 0x15300000
# define INTMSK 0x14400008/*interrupt-controller base Addresses * *
# DEFINECLKDIVN 0x14800014/* Clock divisor Register */
#else
# define Pwtcon 0x53000000
# define INTMSK 0x4a000008/*interrupt-controller base Addresses * *
# Defineintsubmsk 0x4a00001c
# DEFINECLKDIVN 0x4c000014/* Clock divisor Register */
# endif
This section of the function is to define the watchdog, interrupts and sub-interrupts and the register address of the divider, here we are s3c2440, you can look at the data sheet, take Intmsk as an example.
The base site of Intmsk is indeed 0x4a000008.
Below, line 116th:
Ldr R0, =pwtcon
mov r1, #0x0
STR R1, [R0]
LDR uses a pseudo-directive here, which writes the address of the Pwtcon to the r0. MOV speaks 0 to R1, and the last Str is to put the value of R1 into the memory of the address r0 represents. This passage is actually to Pwtcon clear zero close the watchdog.
Line 123th:
mov r1, #0xffffffff
Ldr R0, =intmsk
STR R1, [R0]
Refer to the previous paragraph, because the interrupt control register is set to zero, and this is where all interrupts are closed.
Line 133th:
#if defined (config_s3c2440)
LDR R1, =0X7FFF
Ldr R0, =intsubmsk
STR R1, [R0]
#endif
This part is a shield interrupt, 2440 of the sub-interrupt control register only low 15 bits valid, the other bits are reserved, so here is 0x7fff.
Line 139th:
#if defined (config_s3c2440)
#define MPLLCON 0x4c000004
#define UPLLCON 0x4c000008
#define CAMDIVN 0x4c000018
Ldrr0,=camdivn
mov r1, #0
STR R1,[R0]
Ldrr0,=clkdivn
MOVR1, #0x05
STR R1,[R0]
mrcp15,0,r0,c1,c0,0
ORRR1,R1, #0xc0000000
mcrp15,0,r0,c1,c0,0
Ldrr0,=upllcon
ldrr1,=0x38022
STR R1,[R0]
Nop
Nop
Nop
Nop
Nop
Nop
Nop
Ldrr0,=mpllcon
ldrr1,=0x5c011
STR R1,[R0]
#else
The above section mainly made three clock settings, the first switch off the divider for the camera, the second setting of the USB clock frequency of 48M, the third set the system clock frequency of 400MHZ. Specific why, let's see.
CLKDIVN registers refer to the data sheet as follows:
mov r1, #0x05也就是0101, as we set the Camdiv are all 0, so corresponding to the Pclk:hclk:fclk=1:2:8, the crossover factor has been set up well.
MRC p15,0,r0,c1,c0,0
Orr R1,r1, #0xc0000000
MCR p15,0,r0,c1,c0,0
Here, the data in the register of the coprocessor P15 is transferred to the register R0 of the ARM processor, where 1 is the coprocessor opcode 1,0 is the coprocessor operation code that holds the first operand, and c0 the coprocessor register that holds the second operand. The ultimate goal is to convert arm from Fast bus mode to asynchronous bus mode.
LDR R0,=upllcon
LDR r1,=0x38022
STR R1,[R0]
Here the USB clock frequency is set to 48M, the specific reference manual.
LDR R0,=mpllcon
LDR r1,=0x5c011
STR R1,[R0]
The final setting of the system clock frequency to 400m,mpllcon is to control the relationship between FCLK and Fin, and view the data sheet as follows:
Here's how the m,p,s three parameters come in, and we'll see
This is set to 0x5c011 0101 1100 0000 0001 0001, according to the data bit, can calculate the s=1,p=1+2=3,m=172+8=100, and because our crystal oscillator is 12MHZ, so mpll=fclk= (2*100*12)/ (3*2) =400mhz.
Three Cpu_init_crit and MMU CP15 coprocessor configuration Analysis
Below, line 186th:
#ifndef Config_skip_lowlevel_init
BL Cpu_init_crit
#endif
If the config_skip_lowlevel_init is not defined, then jump to the Cpu_init_crit function, where BL is used, that is, the execution address of the next instruction, stored in the LR link register, indicating that the child function after the end of the operation, using MOV pc LR, the program is still going back here to continue execution, cut past, line NO. 212:
/*
*flush V4 I/D Caches
*/
mov r0, #0
MCR p15,0, R0, C7, C7, 0/* Flush V3/V4 cache*/
MCR p15,0, R0, C8, C7, 0/* Flush v4 TLB */
/*
*disable MMU Stuff and caches
*/
MRC p15,0, R0, C1, C0, 0
Bic r0,r0, #0x00002300 @ clear bits, 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 (I) I-cache
MCR p15,0, R0, C1, C0, 0
Let's take a look at the two instructions for MCR and MRC, and look at the following:
MRC {condition} coprocessor encoding, coprocessor opcode 1, Destination register, source register 1, source register 2,{coprocessor operation code 2}
MCR {condition} coprocessor encoding, coprocessor opcode 1, source register, purpose register 1, destination register 2,{coprocessor operation code 2}
ARM's CP15 coprocessor can only be operated by MCR and MRC Two instructions, here we view datasheet:
Here because is CP15, so 8 to 11 bit is 1111, each bit corresponding meaning also can go to Datesheet to find. We don't have to repeat it here.
MCR p15,0, R0, C7, C7, 0/* Flush V3/V4 cache*/
MCR p15,0, R0, C8, C7, 0/* Flush v4 TLB */
Here first to R0 Qing 0, and then C7 and C8 to clear, and C7 and C8 respectively corresponding to what, you can continue to look at the register in the manual number:
Register number |
Basic role |
The role in the MMU |
The role of PU in |
0 |
ID encoding (read-only) |
ID code and cache type |
|
1 |
Control bit (readable and writable) |
Various control bits |
|
2 |
Storage protection and control |
Address Translation Table Base site |
Control bits of the cachability |
3 |
Storage protection and control |
Domain access Control bit |
Bufferablity control bit |
4 |
Storage protection and control |
Keep |
Keep |
5 |
Storage protection and control |
Memory Failure Status |
Access rights control bits |
6 |
Storage protection and control |
Memory Failure Address |
Protected Area Control |
7 |
Cache and Write Cache |
Cache and Write Cache control |
|
8 |
Storage protection and control |
TLB Control |
Keep |
9 |
Cache and Write Cache |
Cache lock |
|
10 |
Storage protection and control |
TLB Lock |
Keep |
11 |
Keep |
|
|
12 |
Keep |
|
|
13 |
Process identifiers |
Process identifiers |
|
14 |
Keep |
|
|
15 |
Varies by design |
Varies by design |
Varies by design |
You can see that the role of C7,C8 in the MMU is to tell the cache and write cache control as well as the TLB control, in fact C7 and C8 are two write-only registers, this is to clear cache and write cache, and clear TLB is to do so.
MRC p15,0, R0, C1, C0, 0
Bic r0,r0, #0x00002300 @ clear bits, 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 (I) I-cache
MCR p15,0, R0, C1, C0, 0
This paragraph, actually is very clear, first will c0 and C1 value read to R0, and then respectively clear corresponding bit, respectively is 0 to 2 bits, 7 bit, 8,9,13 bit, these bits is what do. Why should we know these bits? Find datasheet See C1, there are two tables below, cleared bits and the following bits set with the ORR instructions I have marked out.
31 16 |
15 |
14 |
13 |
12 |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Additional |
L4 |
Rr |
V |
I |
Z |
F |
R |
S |
B |
L |
D |
P |
W |
C |
A |
M |
Bit |
Say |
M |
0: Disable MMU or pu;1: Enable MMU or PU |
A |
0: Prohibit address alignment check; 1: Enable address alignment check |
C |
0: Prohibit data/entire CACHE;1: Enable data/entire cache |
W |
0: Write buffer disabled, 1: Enable write buffer |
P |
P>0: Exception Interrupt Handler enters 32-bit address mode, 1: Exception interrupt Handler enters 26-bit address mode |
D |
0:26-bit address exception check; 1: Make Can 26-bit address exception check |
L |
0: Select early abort model; 1: Select late Abort model |
B |
0:little endian;1:big endian |