S3C6410 uboot re-engineering (2) Address independence

Publisher:幸福如愿Latest update time:2024-09-19 Source: cnblogsKeywords:S3C6410  uboot Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

This article was written a bit slowly because I had to figure out some details, but I will write it in more detail.


1 /*

2************************************************ ************************

3 *

4 * CPU_init_critical registers

5 *

6 * setup important registers

7 * setup memory timing

8 *

9************************************************ ************************

10 */

11 /*

12 * we do sys-critical inits only at reboot,

13 * not when booting from ram!

14 */

15 cpu_init_crit:

16 /*

17 * When booting from NAND - it has definitely been a reset, so, no need

18 * to flush caches and disable the MMU

19 */

20 #ifndef CONFIG_NAND_SPL

twenty one /*

22 * flush v4 I/D caches

twenty three */

24 mov r0, #0 // Clear r0 register. The following three coprocessor operations will be explained in detail later.

25 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */

26 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */

27

28 /*

29 * disable MMU stuff and caches

30 */

31 mrc p15, 0, r0, c1, c0, 0

32 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)

33 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)

34 orr r0, r0, #0x00000002 @ set bit 2 (A) Align

35 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache

/*------------------------------------------------ -------------------------- */

36 /* Prepare to disable the MMU */

37 adr r1, mmu_disable_phys //Get the address of mmu_..., that is, the address of line 55

38 /* We presume we're within the first 1024 bytes */

39 and r1, r1, #0x3fc //Only keep bits [9:2]

40 ldr r2, _TEXT_PHY_BASE //_TEXT_PHY_BASE --> CONFIG_SYS_UBOOT_BASE

//The previous article has analyzed its two possible addressing methods.

//A problem arises here: SDRAM is initialized in lowlevel_init, so where is the program running at this time?

//Answer later~,~

41 ldr r3, =0xfff00000

42 and r2, r2, r3 //Only keep [32:20] bits, that is, save the first address of different fetches

43 orr r2, r2, r1 //After taking or, the register already contains two parts:

44 b mmu_disable //r2 is the first address + offset address (mmu_diable_phys)

//From the final implementation point of view, this code is a meaningless operation

/*------------------------------------------------ ---------------------------- */

45

46 .align 5 //.align here is aligned according to 2^5 = 32, which is 4 bytes here

//Different from ALIGN(4) in .lds file, 4 in lds file means 4 bytes

47 /* Run in a single cache-line */

48 mmu_disable:

49 mcr p15, 0, r0, c1, c0, 0 //coprocessor, we will talk about it later

50 nop

51 nop

52 mov pc, r2

53 #endif

54

55 mmu_disable_phys:

56 /* Peri port setup */

57 ldr r0, =0x70000000

58 orr r0, r0, #0x13 //The following is still the coprocessor. Let's finish their functions one by one.

59 mcr p15,0,r0,c15,c2,4 @ 256M (0x70000000 - 0x7fffffff)

60

61 /*

62 * Go setup Memory and board specific bits prior to relocation.

63 */

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


1. First, for an introduction to the coprocessor, please refer to the following website


http://blog.csdn.net/genglei1022/article/details/5712843

Let's go back to our code segment. To understand the coprocessor, we first need to understand two instructions.


MCR{cond} coproc, opcode1, Rd, CRn, CRm{, opcode2}

MRC{cond} coproc, opcode1, Rd, CRn, CRm{, opcode2}

//in

//coproc(essor) is the coprocessor, the standard name is pn, n = 1 ~ 15 corresponds to CPn

//opcode1 is the coprocessor behavior opcode, which is always 0, otherwise the coprocessor status is uncertain

//Rd ARM register, CRn target register, CRm additional register, set to c0 if not used

//Provide additional information such as the register version number or access type to distinguish different physical registers with the same number

// You can omit or set it to 0, otherwise the result is unknown


Next comes the coprocessor.


CP15 is a system control coprocessor register used to connect to the page table descriptor in memory and is also used to determine the operation of the MMU.


The first two MCRs encountered here are:


24 mov r0, #0 // clear r0 register

//Move to Coprocessor frem Register, the meaning of MCR is similar to the following sentence

25 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */

26 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */

Two registers c7 and c8 appear here.


Register number Basic function Function in MMU

c7 controls cache and write cache, same as left

c8 Storage Protection and Control TLB Control

Here is a powerful website that introduces the various parts of the chip in detail.


http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0301h/ch03s02s01.html

Then let me tell you how to check the relevant storage information:


1. Find the chip. Here I use ARM1176-JZF-S


2. Now we are looking for the coprocessor unit System Control Coprocessor


3. What we are looking for now is the coprocessor register System control processor registers


4. Finally, you can check the register list in Register allocation


5. If you want to know the actual function of a register, such as our register operation bit here


25 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */

So what we are looking for should be


CRn Op1 CRm Op2 Register or operation

c7 0 c7 0 Invalidate Both Caches

This line actually contains the information we want to know about the coprocessor operation. If you want to learn more, click the link at the end of the line.


Here is an excerpt of c7's function


The purpose of c7 is to:

control these operations:

clean and invalidate instruction and data caches, including range operations

prefetch instruction cache line

Flush Prefetch Buffer

flush branch target address cache

virtual to physical address translation.

implement the Data Synchronization Barrier (DSB) operation

implement the Data Memory Barrier (DMB) operation

implement the Wait For Interrupt clock control function.


Those who can read English should understand


Line 25 means clearing and disabling the instruction and data caches, which has the same meaning as the comments below.


Line 26 means disabling TLB.


31 mrc p15, 0, r0, c1, c0, 0

//Read Control Register configuration data


49 mcr p15, 0, r0, c1, c0, 0

//Write Control Register configuration data


59 mcr p15,0,r0,c15,c2,4

//Peripheral Port Memory Remap


From now on, in the code segment, the implementation of each assembly instruction will not be explained in detail, but will be explained by module.


However, some difficult points will still be analyzed in detail.


2. Code running before SDRAM initialization


To understand how the code runs, you first need to understand ARM's on-chip memory system.


Here we use the XIP (eXecute In Place) standard to distinguish:


Support XIP: NOR flash, mDDR (mobile DDR);


XIP is not supported: NAND flash.


In terms of speed, NOR flash > mDDR > NAND flash.


Knowing this, let's contact the development board to break it down:


NOR flash is used as internal execution memory and is responsible for the initialization code execution of the system (such as start.o);


mDDR is the conventional memory, namely SDRAM, which is the main operating environment of the code;


As a storage device, NAND flash can be regarded as the hard disk on our PC.



It is easy to understand here, SDRAM is initialized in lowlevel_init, before SDRAM is initialized, the code is executed in NOR flash.



Next, let's solve the problem of initialization order left just now:


40 ldr r2, _TEXT_PHY_BASE

In this sentence, what exactly does _TEXT_PHY_BASE store?


Let's disassemble it first.


arm-linux-objdump -D -S -t start.o

//Add -t to see the location of the code segment


00000044 <_TEXT_PHY_BASE>:

44: 57e00000 .word 0x57e00000

...

ldr r2, _TEXT_PHY_BASE

8c: e51f2050 ldr r2, [pc, #-80] ; 44 <_TEXT_PHY_BASE>


Obviously, the _TEXT_PHY_BASE here is 0x57e00000!


But let's think about it, lowlevel_init is still behind, SDRAM has not been initialized!


So we cannot call this address, but we can clearly see it here.


What you see with your eyes is not necessarily true.


Here we introduce a new concept to explain this problem: running address independence.


First, the place of reference:


http://blog.sina.com.cn/s/blog_4a9fb5cf01008d8u.html~type=v5_one&label=rela_nextarticle

Just read the last part.



As running code, whether it is the bootloader or kernel initialization code, there will always be a period of weakness: the code is too long and the space is too short.


In uboot, it is before SDRAM initialization, and in kernel, it is before MMU enabling.


During this weak period, the addressing space of the code is very limited, and the predetermined location during the compilation process may cause addressing errors.


Therefore, the need for address independence arises, which is mainly manifested in the need to limit the addressing range of this code to our NOR flash and not disrupt code execution.


At this point, let's understand the essence of 0x57e00000 here


00000044 <_TEXT_PHY_BASE>:

44: 57e00000 .word 0x57e00000

...

ldr r2, _TEXT_PHY_BASE

8c: e51f2050 ldr r2, [pc, #-80] ; 44 <_TEXT_PHY_BASE>

If our SDRAM is enabled, then this address is actually the starting address where uboot.bin is placed.


However, at this time, uboot.bin is placed in NOR flash, so the starting point should be 0x00000000.


Following this logic, the result is correct. The execution of that section of code is "optional", which is why many people choose to delete it when modifying the code.

[1] [2]
Keywords:S3C6410  uboot Reference address:S3C6410 uboot re-engineering (2) Address independence

Previous article:s3c6410 SD card boot Secure mode
Next article:S3C6410 bare metal - external interrupt program

Latest Microcontroller Articles
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号