1. Introduction to MMU
1.1 Virtual address and physical address
Build two applications, hello1.c and hello2.c, and then run:
hello1.c
hello2.c
The running results are as follows:
You can see that the addresses printed by the two results are the same, both are 0x601040, which means that both programs are running at the same address. Our infinite loop program ensures that the two programs are running at the same time.
For 2440, as shown below:
The CPU only issues addresses and reads and writes data. It doesn't matter whether the address is a physical address or a virtual address.
When writing a program, the link address does not have a physical address or a virtual address. The link address is what the CPU sees, from the CPU's perspective.
1.2 Convert virtual address to physical address
For ARM, the virtual address (VA) is converted into a physical address (PA) through a table. This table is the page table.
The simple steps to set up the mapping are:
Create a table: virtual address to physical address mapping
Tell the MMU the table address: the table is in memory, tell the MMU the first address of the table
Start MMU
2. Code
2.1 start.S (archarmcpuarm920t)
The cpu_init_crit in start.S enables the MMU. When u-boot starts, the MMU is not enabled. The enabling of MMU involves the CP15 coprocessor.
The code snippet is as follows:
1 /*
2 * disable MMU stuff and caches
3*/
4 mrc p15, 0, r0, c1, c0, 0 /* Read the value of register C1 of CP15 into r0*/
5 /* Bits 8, 9, and 13 of the C1 register are cleared
6 * S (bit[8]) In MMU-based storage systems, this bit is used for system protection
7 * R (bit[9]) In MMU-based storage systems, this bit is used for ROM protection
8*V(bit[13])
9 * For systems that support high-end exception vector tables, this control bit controls the location of the vector table
10 * 0: Select the low-end exception interrupt vector 0x0~0x1c
11 * 1: Select the high-end exception interrupt vector 0xffff0000~ 0xffff001c
12 * For systems that do not support high-end exception vector tables, this bit returns 0 when reading and ignores when writing.
13 */
14 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
15 /* Bits 0, 1, 2, and 7 of the C1 register are cleared
16*M(bit[0])
17 * 0: Disable MMU or PU
18 * 1: Enable MMU or PU
19 * If there is no MMU and PU in the system, this bit returns 0 when reading and ignores this bit when writing.
20*A(bit[1])
21 * 0: Disable address alignment check
22 * 1: Enable address alignment check
23*C(bit[2])
24 * When the data cache and instruction cache are separated, this control bit disables/enables the data cache.
25 * When the data cache and instruction cache are unified, this control bit disables/enables the entire cache.
26 * 0: prohibit data/entire cache
27 * 1: enable data/entire cache
28 * If there is no cache in the system, this bit returns 0 when reading. Ignore when writing.
29 * When the cache cannot be disabled in the system, 1 is returned when reading and ignored when writing.
30*B(bit[7])
31 * For ARM systems whose storage system supports both big-endian and little-endian, this control bit configures the storage mode of the system.
32 * 0: little endian
33 * 1: big endian
34 * For systems that only support little-endian, this bit returns 0 when reading and ignores when writing.
35 * For systems that only support big-endian, this bit returns 1 when reading and ignores when writing.
36 */
37 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
38 /* Bit1 of the C1 register is set to 1, which enables address alignment*/
39 orr r0, r0, #0x00000002 @ set bit 1 (A) Align
40 /* Set bit12 of the C1 register to 1 to enable the instruction cache */
41 /* I (bit[12])
42 * When the data cache and instruction cache are separated, this control bit disables/enables the instruction cache.
43 * 0: Disable instruction cache
44 * 1: Enable instruction cache
45 * If a unified instruction cache and data cache are used in the system or there is no cache in the system, 0 will be returned when reading this bit and ignored when writing.
46 * When the instruction cache in the system cannot be disabled, this bit returns 1 when reading and ignores when writing.
47 */
48 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
49 mcr p15, 0, r0, c1, c0, 0 /* Write the value of r0 to register C1 of CP15*/
50
51/*
52 * before relocating, we have to setup RAM timing
53 * because memory timing is board-dependent, you will
54 * find a lowlevel_init.S in your board directory.
55 */
56 mov ip, lr /* Save the function address for return */
Afterwards, the code in start.S will enter _main (crt0.S (archarmlib)) to run.
2.2 crt0.S (archarmlib)
Run the _main function in ctr0.S. In this function, run to board_init_f (initialization before board startup), and then execute to the linked list init_sequence_f, where the MMU is initialized reserve_mmu.
2.2.1 reserve_mmu
1 static int reserve_mmu(void)
2 {
3 /* reserve TLB table */
4 gd->arch.tlb_size = PGTABLE_SIZE; //PGTABLE_SIZE = 4096 *4 Reserve 16kb MMU page table
5 gd->relocaddr -= gd->arch.tlb_size;//gd->relocaddr = gd->relocaddr - 16K = 0x33ffc000
6
7 /* round down to next 64 kB limit */
8 gd->relocaddr &= ~(0x10000 - 1);//64kb alignment gd->relocaddr = 0x33ff0000
9
10 gd->arch.tlb_addr = gd->relocaddr;//gd->arch.tlb_addr = 0x33ff0000
11 debug("TLB table from %08lx to %08lxn", gd->arch.tlb_addr,
12 gd->arch.tlb_addr + gd->arch.tlb_size);
13 return 0;
14}
We can get the size of PGTABLE_SIZE by looking at u-boot.dis:
The first line is the size of PGTABLE_SIZE.
After executing the linked list, jump back to _main to continue execution, and then execute to board_init_r (Board_r.c (common) initialization code after board startup).
A linked list, init_sequence_r, will also be executed in board_init_r. Execute various initialization functions in the linked list, and then execute them in board_init. In board_init, perform icache_enable and dcache_enable.
Both functions call the cache_enable function. There are MMU settings in it.
2.2.2 cache_enable
cache_enable
1 static void cache_enable(uint32_t cache_bit)
2 {
3 uint32_t reg;
4
5 /* The data cache is not active unless the mmu is enabled too */
6 if ((cache_bit == CR_C) && !mmu_enabled())
7 mmu_setup();
8 reg = get_cr(); /* get control reg. */
9 cp_delay();
10 set_cr(reg | cache_bit);
11 }
Now let’s look at the mmu_setup function
1 /* to activate the MMU we need to set up virtual memory: use 1M areas */
2 static inline void mmu_setup(void)
3 {
4 int i;
5 u32 reg;
6
7 arm_init_before_mmu(); //Empty function
8 /* Set up an identity-mapping for all 4GB, rw for everyone */
9 for (i = 0; i < 4096; i++)
10 set_section_dcache(i, DCACHE_OFF); //Pass in the DCACHE_OFF parameter and establish the page table address
11
12 for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
13 dram_bank_mmu_setup(i); //Set the page table size and address of DRAM
14}
15
16 /* Set the access control to all-supervisor */
17 asm volatile("mcr p15, 0, %0, c3, c0, 0"
18 : : "r" (~0)); //MMU initializes
19
20 arm_init_domains(); //Empty function
twenty one
22 /* and enable the mmu */
23 reg = get_cr(); /* get control reg. */
24 cp_delay();
25 set_cr(reg | CR_M);
26}
27
28 arch/arm/include/asm/system.h
29 /* Size of an MMU section */
30 enum {
31 MMU_SECTION_SHIFT = 20,
32 MMU_SECTION_SIZE = 1 << MMU_SECTION_SHIFT,
33};
34
35 /* Page table creation function, each page is 1M, the starting address of the page is section */
36 void set_section_dcache(int section, enum dcache_option option)
37 {
38 u32 *page_table = (u32 *)gd->arch.tlb_addr; //Take out page_table, 16K
39 u32 value;
40
41 value = (section << MMU_SECTION_SHIFT) | (3 << 10); //The 20th power of 2 is 1M
42 value |= option;
43 page_table[section] = value;
44}
45
46 __weak void dram_bank_mmu_setup(int bank)
47 {
48 bd_t *bd = gd->bd;
49 int i;
50
51 debug("%s: bank: %dn", __func__, bank);
52 for (i = bd->bi_dram[bank].start >> 20;
53 i < (bd->bi_dram[bank].start >> 20) + (bd->bi_dram[bank].size >> 20);
54 i++) {
55
56 set_section_dcache(i, DCACHE_WRITETHROUGH);
57 }
58 }
Previous article:u-boot transplantation (9)---Code modification---NAND
Next article:u-boot transplantation (7)---code modification---storage controller
Recommended ReadingLatest update time:2024-11-15 14:51
- Popular Resources
- Popular amplifiers
- Software and Hardware Fusion (by Huang Chaobo)
- In-depth exploration of embedded operating system design, architecture and development from scratch (written by Peng Dong)
- Writing embedded operating systems step by step--ARM programming methods and practices
- Pattern-Oriented Software Architecture Volume 4 A Pattern Language for Distributed Computing
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- Electromagnetism and quantum mechanics
- ST NUCLEO-L452RE Development Board Introduction
- ARM register analysis and exception handling methods
- Qorvo has recently launched Wi-Fi 6 and IoT solutions. Will you choose them?
- TI DSP Simulation
- Radar System Engineering: Antenna System (summarizes many sub-projects) You can take a look at it to absorb scattered memories
- DM642 hard interrupt delay problem
- [Xingkong Board Python Programming Learning Main Control Board] Basic Use of Display Graphical Interface
- Is the semiconductor industry still worth investing in?
- Regarding the question of safety capacitors, let's see who is right