.text
.global _start
_start:
ldr sp, =4096 @ Set the stack pointer. The following are all C functions. You need to set the stack before calling them
bl disable_watch_dog @ Turn off WATCHDOG, otherwise the CPU will restart continuously
bl memsetup @ Set up the memory controller to use SDRAM
bl copy_2th_to_sdram @ Copy the second part of the code to SDRAM
bl create_page_table @ Set up the page table
bl mmu_init @ Start MMU
ldr sp, =0xB4000000 @ Reset the stack pointer to point to the top of SDRAM (using virtual address)
ldr pc, =0xB0004000 @ Jump to SDRAM and continue executing the second part of the code
halt_loop:
b halt_loop
From this compilation, we can see that the whole setup process, among which setting the page table and starting the MMU are the key points
Setting up the page table
/*
* Set up the page table
*/
void create_page_table(void)
{
/*
* Some macro definitions for segment descriptors
*/
#define MMU_FULL_ACCESS (3 << 10) /* Access rights*/
#define MMU_DOMAIN (0 << 5) /* Which domain does it belong to*/
#define MMU_SPECIAL (1 << 4) /* Must be 1 */
#define MMU_CACHEABLE (1 << 3) /* cacheable */
#define MMU_BUFFERABLE (1 << 2) /* bufferable */
#define MMU_SECTION (2) /* Indicates that this is a segment descriptor*/
#define MMU_SECDESC (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | \
MMU_SECTION)
#define MMU_SECDESC_WB (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | \
MMU_CACHEABLE | MMU_BUFFERABLE | MMU_SECTION)
#define MMU_SECTION_SIZE 0x00100000
unsigned long virtuladdr, physicaladdr;
unsigned long *mmu_tlb_base = (unsigned long *)0x30000000;
/*
* The starting physical address of Steppingstone is 0, and the starting running address of the first part of the program is also 0.
* In order to still run the first part of the program after turning on the MMU,
* map the virtual addresses of 0 to 1M to the same physical address
*/
virtuladdr = 0;
physicaladdr = 0;
*(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | \
MMU_SECDESC_WB;
/*
* 0x56000000 is the starting physical address of the GPIO register,
* The physical addresses of the two registers GPBCON and GPBDAT are 0x56000010 and 0x56000014,
* In order to operate GPBCON and GPBDAT at addresses 0xA0000010 and 0xA0000014 in the second part of the program,
* Map the 1M virtual address space starting from 0xA0000000 to the 1M physical address space starting from 0x56000000
*/
virtuladdr = 0xA0000000;
physicaladdr = 0x56000000;
*(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | \
MMU_SECDESC;
/*
* The physical address range of SDRAM is 0x30000000~0x33FFFFFF,
* Map the virtual address 0xB0000000~0xB3FFFFFF to the physical address 0x30000000~0x33FFFFFF,
* a total of 64M, involving 64 segment descriptors
*/
virtuladdr = 0xB0000000;
physicaladdr = 0x30000000;
while (virtuladdr < 0xB4000000)
{
*(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | \
MMU_SECDESC_WB;
virtuladdr += 0x100000;
physicaladdr += 0x100000;
}
}
Here *(mmu_tlb_base + (virtuladdr >> 20)) = (physicaladdr & 0xFFF00000) | \MMU_SECDESC_WB;
The virtual address part is shifted 20 bits to the right, the physical address part is saved in [31:20], and the corresponding permissions are set, and the page table is cleverly set. Another thing to note is that here virtualaddr += 0x100000; physicaladdr += 0x100000; because only [31:20] is used, increasing by 1 is also equal to 0x100000.
/*
* Start MMU
*/
void mmu_init(void)
{
unsigned long ttb = 0x30000000;
__asm__(
"mov r0, #0\n"
"mcr p15, 0, r0, c7, c7, 0\n" /* Invalidate ICaches and DCaches */
"mcr p15, 0, r0, c7, c10, 4\n" /* drain write buffer on v4 */
"mcr p15, 0, r0, c8, c7, 0\n" /* Invalidate instruction and data TLB */
"mov r4, %0\n" /* r4 = page table base address */
"mcr p15, 0, r4, c2, c0, 0\n" /* Set page table base register */
"mvn r0, #0\n"
"mcr p15, 0, r0, c3, c0, 0\n" /* Set domain access control register to 0xFFFFFFFF,
* no permission check
*/
/*
* For the control register, read its value first, modify the bits of interest based on this,
* and then write it
*/
"mrc p15, 0, r0, c1, c0, 0\n" /* Read the value of the control register*/
/* The lower 16 bits of the control register mean: .RVI ..RS B... .CAM
* R : Indicates the algorithm used when swapping out entries in the Cache,
* 0 = Random replacement; 1 = Round robin replacement
* V : Indicates the location of the exception vector table,
* 0 = Low addresses = 0x00000000; 1 = High addresses = 0xFFFF0000
* I : 0 = Disable ICaches; 1 = Enable ICaches
* R, S : Used together with the descriptor in the page table to determine memory access permissions
* B : 0 = CPU is little endian; 1 = CPU is big endian
* C : 0 = Disable DCaches; 1 = Enable DCaches
* A : 0 = Do not perform address alignment check on data access; 1 = perform address alignment check on data access
* M : 0 = turn off MMU; 1 = turn on MMU
*/
/*
* Clear unneeded bits first, reset them if needed later
*/
/* .RVI ..RS B... .CAM */
"bic r0, r0, #0x3000\n" /* ..11 .... .... .... Clear V, I bits*/
"bic r0, r0, #0x0300\n" /* .... ..11 .... .... Clear R, S bits*/
"bic r0, r0, #0x0087\n" /* .... .... 1... .111 Clear B/C/A/M */
/*
* Set needed bits
*/
"orr r0, r0, #0x0002\n" /* .... .... .... ..1. Enable alignment check*/
"orr r0, r0, #0x0004\n" /* .... .... .... .1.. Enable DCaches */
"orr r0, r0, #0x1000\n" /* ...1 .... .... .... Enable ICaches */
"orr r0, r0, #0x0001\n" /* .... .... .... ...1 Enable MMU */
"mcr p15, 0, r0, c1, c0, 0\n" /* Write modified value to control register*/
: /* No output*/
: "r" (ttb) );
}
Previous article:S3C6410 pure bare metal boot, self-written SD BOOT boot
Next article:S3C6410 Bare Metal DMA
- 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!
- Rambus Launches Industry's First HBM 4 Controller IP: What Are the Technical Details Behind It?
- 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
- FPGA Learning Notes-----FPGA Competition Adventure
- W806 Lighting
- Analysis of the role of terminal resistance in CAN bus
- Download the information and watch the video to win a prize | Tektronix HDMI 2.1 test solution is now available for download, and you can also watch the supporting video
- Things to note when using C/C++ to write programs based on TMS320 series DSP
- Based on micropython-1.9.4 ESP8266 motor control firmware
- MATLAB reads txt file data and processes it
- Easy to use, LiChuang EDA. Haha!
- [Start at 10:30] Interpretation of TI's latest smart lock, visual doorbell, and network camera solutions, and recommendations for its core components
- C6678 multi-core DSP development - connected domain marking of vlib application