Source: http://blog.csdn.net/embeddedfly/article/details/6150452
Detailed analysis of MMU setting process in ce5.0-eboot Assembly startup. s
The following is the startup code of the smdk Development Board startup. S.
;-------------------------------------------------------------------------------
Memorymap equ 0x2a4
Bank_size equ 0x00100000; 1 MB per bank in memorymap Array
Bank_shift equ 20
; Define Ram space for the page tables:
;
Phybase equ 0x30000000; physical start
PTS equ 0x30010000; 1st level page table address (phybase + 0x10000)
; Save room for interrupt vectors.
;------------------------------------------------------------------------------
; Copy boot loader to memory
ANDS R9, PC, #0xff000000; see if we are in flash or in Ram
// If the 8-byte height is not 0, the PC is already in Ram; otherwise, the PC is located in the 0x00000000 address range after the reset [Luther. gliethttp]
BNE % F20; go ahead if we are already in Ram // The 8-byte high is not 0, indicating that eboot is already in DDR and jumps to the 20 mark below
; This is the loop that perform copying.
LDR r0, = 0x38000; offset into the RAM
Add r0, R0, # phybase; add physical base // The final physical address of eboot is 0x30038000, Which is platform/smdk2440a/src/bootloader/eboot_usb/boot. the
// Eboot link address: eboot 8c038000 00016800 ramimage // A. allows a ramimageworkflow to generate a corresponding. binfile, which is generated by romimage.exe. nb0 simultaneously fills the ptoc global variable pointer of eboot [Luther. gliethttp]
MoV R1, R0; (R1) Copy destination
// When the S3C2440 is started, the first 4 k Data in the NAND is read to the 4 k ram in the S3C2440, and the ram is mapped to 0 address, CPU
// Jump to Ram and start executing the first 4 K code data read from NAND. Therefore, reading the 4 K data after the 0 address in Ram is equivalent to reading the first 4 k Data of NAND [Luther. gliethttp].
LDR R2, = 0x0; (R2) Flash started at physical address 0
LDR R3, = 0x10000; counter (0x40000/4) // read 4 K Bytes cyclically
10 LDR R4, [R2], #4
STR R4, [R1], #4
Subs R3, R3, #1
BNE % B10
; Restart From the ram position after copying.
MoV PC, R0 // jump to the physical address 0x30038000 and re-execute the above reset code. When the re-execution is performed because it is already in Ram, the above BNE % F20 statement [Luther. gliethttp] will be executed.
NOP // Add the maximum number of null commands that may exist for the pipeline
NOP
NOP
; Shouldn't get here.
B.
Include oemaddrtab_cfg.inc // This is the MMU ing table of eboot, which is located in platform/smdk2440a/src/INC/oemaddrtab_cfg.inc
/*
Export g_oaladdresstable [Data]
G_oaladdresstable
DCD 0x80000000, 0x32000000, 32; 32 mb dram Bank 6
DCD 0x82000000, 0x08000000, 32; 32 MB srom (SRAM/ROM) Bank 1
DCD 0x84000000, 0x10000000, 32; ngcs2: PCMCIA/pccard
DCD 0x86000000, 0x18000000, 32; 32 MB srom (SRAM/ROM) Bank 3
DCD 0x88000000, 0x20000000, 32; 32 MB srom (SRAM/ROM) Bank 4
DCD 0x8a000000, 0x28000000, 32; 32 MB srom (SRAM/ROM) Bank 5
DCD 0x8c000000, 0x30000000, 32; 32 mb dram Bank 6
DCD 0x90800000, 0x48000000, 1; memory control register
DCD 0x90900000, 0x49000000, 1; USB Host register
DCD 0x90a00000, 0x4a000000, 1; interrupt control register
DCD 0x90b00000, 0x4b000000, 1; DMA control register
DCD 0x90c00000, 0x4c000000, 1; clock & Power register
DCD 0x90d00000, 0x4d000000, 1; LCD control register
DCD 0x90e00000, 0x4e000000, 1; NAND Flash control register
DCD 0x90f00000, 0x4f000000, 1; camera control register
DCD 0x91000000, 0x50000000, 1; UART control register
DCD 0x91100000, 0x51000000, 1; PWM timer register
DCD 0x91200000, 0x52000000, 1; USB device register
DCD 0x91300000, 0x53000000, 1; watchdog timer register
DCD 0x91400000, 0x54000000, 1; IIC control register
DCD 0x91500000, 0x55000000, 1; IIS control register
DCD 0x91600000, 0x56000000, 1; I/O port register
DCD 0x91700000, Zero X 57000000, 1; RTC control register
DCD 0x91800000, 0x58000000, 1; A/D convert register
DCD 0x91900000, 0x59000000, 1; SPI register
DCD 0x91a00000, 0x5a000000, 1; SD interface register
DCD 0x92000000, 0x00000000, 32; 32 MB srom (SRAM/ROM) Bank 0
DCD 0x00000000, 0x00000000, 0; end of table
*/
; Compute physical address of the oemaddresstable.
20 Add R11, PC, # g_oaladdresstable-(. + 8)
LDR R10, = PTS; (R10) = 1st level page table
Zero X 20000000
; Setup 1st level page table (using section descriptor)
; Fill in first level page table entries to create "un-mapped" regions
; From the contents of the memorymap array.
;
; (R10) = 1st level page table
; (R11) = PTR to memorymap Array
// The PTR address is selected at the offset starting with DDR. CE is a 64 K offset, and Linux does the same.
// Then the 1st-level MMU entry is the 14-bit high of the PC address (18-bit low) [Luther. gliethttp]
// For example, the 1st-level MMU entry offset corresponding to the 0x80000000 address is 0x80000000> 18 = 0x2000
Add R10, R10, #0x2000; (R10) = PTR to 1st PTE for "unmapped space"
// R10 stores the corresponding address of 0x80000000 virtual address in PTR
MoV r0, # 0x0e; (R0) = PTE for 0: 1 MB cachable bufferable // high-speed cache C and write buffer B
ORR r0, R0, #0x400; Set kernel R/W permission
25 mov R1, R11; (R1) = PTR to memorymap Array
30 LDR R2, [R1], #4; (R2) = Virtual Address to map bank
LDR R3, [R1], #4; (r3) = physical address to map from
LDR R4, [R1], #4; (R4) = num MB to map
CMP R4, #0; end of table?
Beq % F40 // indicates the cachable address 0x80000000 ~ 0xa0000000 mming MMU is created. The table ends and jumps to the 40 mark before creating the corresponding Uncached mming MMU [Luther. gliethttp].
LDR R5, = 0x1ff00000
And R2, R2, R5; VA needs 512 MB, 1 MB aligned. // align the VA virtual address MB [Luther. gliethttp]
// That is, the upper limit of R2 cannot exceed 0x20000000 or 512 M, because R10 now points to the 0x80000000 virtual address of the level 1 ing table,
// Because the address 0x80000000 + 0x20000000 = 0xa0000000 is used to store the Uncached address, the M data limit [Luther. gliethttp] is required here.
LDR R5, = 0xfff00000
And R3, R3, R5; PA needs 4 GB, 1 MB aligned. // 4 GB aligned for Pa physical addresses
Add R2, R10, R2, LSR #18
Add r0, R0, R3; (R0) = PTE for next physical page // append the mapped PA physical address on the basis of the MMU flag [Luther. gliethttp]
35 STR r0, [R2], #4 // save to the PTR offset corresponding to R2
Add r0, R0, #0x00100000; (R0) = PTE for next physical page // 1 m increments, because 1 <18 = 256 k, and each PTE describes 4 K pages, so the final description is 256 K * 4 k = 1 M address space [Luther. gliethttp]
Sub R4, R4, #1; Decrement Number of MB left
CMP R4, #0
BNE % b35; map next MB // traverse to the end of the Region
Bic r0, R0, #0xf0000000; clear section base address field
Bic r0, R0, #0x0ff00000; clear section base address field // clear the address information in R0 [lutehr. gliethttp]
B % B30; get next element // continue to create the next region [Luther. gliethttp] described by oemaddrtab_cfg.inc
// Create the corresponding Uncached mming MMU table starting with 0xa0000000
40 TST r0, #8
// Compare whether the cache of C is still set. If it is still set, it indicates that the Uncached creation has not been executed. If the C-bit has been cleared, the Uncached loop has been executed, so I jumped back to the 25 label and continued to create [Luther. gliethttp]
Bic r0, R0, # 0x0c; clear cachable & bufferable bits in PTE // clear B write buffer and C high speed cache [Luther. gliethttp]
Add R10, R10, #0x0800; (R10) = PTR to 1st PTE for "unmapped Uncached space" // R10 now corresponds to the PTR start address of the 0x80000000 virtual address, hex (0x20000000> 18) is 0x800,
// Therefore, R10 = R10 + 0x800; then R10 points to the PTR start address corresponding to the 0xa0000000 Virtual Address [Luther. gliethtp]
BNE % b25; go setup PTES for Uncached Space
// OK. Now the 0x80000000 cachable space and 0xa0000000 Uncached space have been created [Luther. gliethttp]
Sub R10, R10, #0x3000; (R10) = restore address of 1st level page table // This sentence seems to have a problem, but fortunately before R10 is used later, the R10 value is re-assigned. Therefore, this statement is meaningless. gliethttp]
// Create a caching between cachable and Uncached for the virtual 0 Address [lutehr. gliethttp]
; Setup MMU to map (Va = 0) to (Pa = 0x30000000 ).
LDR r0, = PTS; PTE entry for VA = 0
LDR R1, = 0x3000040e; uncache/unbuffer/RW, PA base = 0x30000000 // map virtual addresses 0 to PA physical addresses 0x30000000 in the way C and B are enabled
STR R1, [R0]
; Uncached area.
Add r0, R0, #0x0800; PTE entry for VA = 0x0200.0000, Uncached // The next 0x2000000 virtual address is mapped to the Uncached start address of the virtual 0 Address [Luther. gliethttp]
LDR R1, = 0x30000402; uncache/unbuffer/RW, base = 0x30000000 // use C, B does not enable ing virtual address 0 to PA physical address 0x30000000
STR R1, [R0]
// You can see through the above settings
// The virtual address 0 corresponds to the cachable of 0x30000000
// The virtual address 0x2000000 corresponds to the Uncached of 0x30000000. [Luther. gliethttp]
; Comment:
; The following loop is to direct map Ram Va = pa. I. e.
; VA = 0x30xxxxxx => Pa = 0x30xxxxxx for s3c2400
; Fill in 8 entries to have a direct mapping for dram
;
LDR R10, = PTS; restore address of 1st level page table
LDR r0, = phybase // phybase is 0x30000000. The virtual address is mapped to the same physical address.
Add R10, R10, # (0x3000/4); (R10) = PTR to 1st PTE for 0x30000000 // (0x30000000> 16)> 2 (0x30000000> 16)/4 [Luther. gliethttp]
// Now R10 points to the PTR address corresponding to the PA address equal to the DDR address
Add r0, R0, # 0x1e; 1 MB cachable bufferable
ORR r0, R0, #0x400; Set kernel R/W permission
MoV R1, #0
MoV R3, #64 // ing 64 m space, because our physical DDR only has 64 m (see the oemaddrtab_cfg.inc table above), cannot exceed 512, because the following only supports up to 512 cycles (R1 is the number of cycles, once each cycle, create a 1m ing table of 1 MB space) [Luther. gliethtp]
45 mov R2, R1; (R2) = Virtual Address to map bank
CMP R2, #0x20000000: SHR: bank_shift // 0x20000000> 20 = 512 m,
Add R2, R10, R2, LSL # BANK_SHIFT-18 // Add R2, R10, R2, 4 r2 = R10 + R2 * 4; exactly the 4-byte boundary [Luther. gliethttp]
Strlo r0, [R2] // if the operation has not reached 512 M, fill in the PTR. If the ing operation has completed M, ignore
Add r0, R0, #0x00100000; (R0) = PTE for next physical page
Subs R3, R3, #1
Add R1, R1, #1
Bgt % b45
LDR R10, = PTS; (R10) = restore address of 1st level page table
; The page tables and exception vectors are setup.
; Initialize the MMU and turn it on.
MoV R1, #1
MCR P15, 0, R1, C3, C0, 0; Setup access to domain 0
MCR P15, 0, R10, C2, C0, 0
MCR P15, 0, R0, C8, C7, 0; flush I + D tlbs // flush all MMU-Related Spaces
MoV R1, #0x0071; Enable: MMU // set to enable the MMU flag to r1
ORR R1, R1, #0x0004; enable the cache // set to enable the cache flag to r1
LDR r0, = virtualstart // obtain the virtual address value obtained during virtualstart compilation. The value ranges from 0x30038000 ~ Between 0x30038000 + eboot_size [Luther. gliethtp]
CMP r0, #0; make sure no stall on "mov PC, R0" below // execute this comparison, so that R0 can read the virtualstart value practically.
MCR P15, 0, R1, C1, C0, 0 // write the MMU setting flag to the P15 coprocessor. The effective setting is [Luther. gliethttp].
MoV PC, R0; & jump to new virtual address // jump past, now MMU is enabled, all permitted virtual addresses are defined in platform/smdk2440a/src/INC/oemaddrtab_cfg.inc [Luther. gliethttp]
NOP
; MMU & caches now enabled.
; (R10) = physcial address of 1st level page table
;
Virtualstart
MoV sp, #0x8c000000 // set the stack space. From here, the physical address of the DDR corresponding to the SP stack top is 0x30030000, and then grows down from boot. bib.
/*
Memory
; Name start Size Type
;---------------------------
ARGs 8c020800 00000800 Reserved
Binfs 8c021000 00005000 Reserved
Ram 8c026000 00006000 Ram
Stack 8c02c000 00004000 reserved // 0x2c000 + 0X4000 = 0x30000 reserve this 16 K address space as the SP stack space of eboot
Eboot 8c038000 00016800 ramimage
*/
We can see that the SP stack space is retained by. bib, which is located between 0x30030000 and ~ 0x3002c000, the stack SP grows down from 0x30030000 [Luther. gliethttp]
Add SP, SP, #0x30000; arbitrary initial super-page Stack pointer
B Main // jump to the main function, startup. s does not perform DDR release initialization for the global variables or static variables defined by the C function. For details about how to fill eboot with ce5.0-romimage.exe, see my other article. the ptoc special pointer in BIN to generate eboot. nb0