上一篇我主要关注的是对那些协处理器进行操作和对协处理器操作的两个指令的说明,这篇再说下具体的代码。
-----------------------------------------------------------------------------------------------------
/* Set the TTB register */
ldr r0, _mmu_table_base
ldr r1, =CFG_PHY_UBOOT_BASE
ldr r2, =0xfff00000
bic r0, r0, r2
orr r1, r0, r1
mcr p15, 0, r1, c2, c0, 0
----------------------------------------------------------------------------------------------
主要说下上面这部分代码,其中有如下定义:
#ifdef CONFIG_ENABLE_MMU
_mmu_table_base:
.word mmu_table
#endif
---------------------------------------
在lowlevel_init.S (board\samsung\smdk6410)文件中有如下定义:
#ifdef CONFIG_ENABLE_MMU
/*
* MMU Table for SMDK6400
*/
/* form a first-level section entry */
.macro FL_SECTION_ENTRY base,ap,d,c,b
.word (\base << 20) | (\ap << 10) | \
(\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
.endm
.section .mmudata, "a"
-----------------------------------------------------------------------------------------------------
关于上面这个GNU的语法,下面这段是我在GNU网站上找到的。
.section name[, "flags"] or .section name[, subsegment]
Use the .section
directive to assemble the following code into a section named name.
If the optional argument is quoted, it is taken as flags to use for the section. Each flag is a single character. The following flags are recognized:
b
bss section (uninitialized data)
n
section is not loaded
w
writable section
d
data section
r
read-only section
x
executable section
m
mergeable section (TIGCC extension, symbols in the section are considered mergeable constants)
u
unaligned section (TIGCC extension, the contents of the section need not be aligned)
s
shared section (meaningful for PE targets, useless for TIGCC)
a
ignored (for compatibility with the ELF version)
If no flags are specified, the default flags depend upon the section name. If the section name is not recognized, the default will be for the section to be loaded and writable. Note the n
and w
flags remove attributes from the section, rather than adding them, so if they are used on their own it will be as if no flags had been specified at all.
-------------------------------------------------------------------------------------------------------------
.align 14 因为MMU的table需4K对齐。
-------------------------------------------------------------------------------------------------------------
.align alignment[, [fill][, max]]
Pad the location counter (in the current subsection) to a particular storage boundary. alignment (which must be absolute) is the alignment required, as described below.
fill (also absolute) gives the fill value to be stored in the padding bytes. It (and the comma) may be omitted. If it is omitted, the padding bytes are normally zero. However, on some systems, if the section is marked as containing code and the fill value is omitted, the space is filled with no-op instructions (I didn't checked whether this is the case in TIGCC).
max is also absolute, and is also optional. If it is present, it is the maximum number of bytes that should be skipped by this alignment directive. If doing the alignment would require skipping more bytes than the specified maximum, then the alignment is not done at all. You can omit the fill value (the second argument) entirely by simply using two commas after the required alignment; this can be useful if you want the alignment to be filled with no-op instructions when appropriate.
The way the required alignment is specified varies from system to system. For the a29k, hppa, m68k, m88k, w65, sparc, Xtensa, and Renesas / SuperH SH, and i386 using ELF format, the first expression is the alignment request in bytes. For example .align 8
advances the location counter until it is a multiple of 8. If the location counter is already a multiple of 8, no change is needed.
For other systems, including the i386 using a.out format, and the arm and strongarm, it is the number of low-order zero bits the location counter must have after advancement. For example .align 3
advances the location counter until it a multiple of 8. If the location counter is already a multiple of 8, no change is needed.
This inconsistency is due to the different behaviors of the various native assemblers for these systems which as
must emulate. as
also provides .balign
and .p2align
directives, which have a consistent behavior across all architectures (but are specific to as
).
------------------------------------------------------------------------
// the following alignment creates the mmu table at address 0x4000.
.globl mmu_table
mmu_table:
.set __base,0
-------------------------------------------------------------------------------------------
.set的用法:
.set symbol, expression
把expression 的值赋给symbol。
Set the value of symbol to expression. This changes symbol's value and type to conform to expression.
You may .set
a symbol many times in the same assembly.
If you .set
a global symbol, the value stored in the object file is the last value stored into it.
-------------------------------------------------------------------------------------------
// 1:1 mapping for debugging
.rept 0xA00
---------------------------------------------------------------------------------------------
Syntax: .rept count 重复
Repeat the sequence of lines between the .rept
directive and the next .endr
directive count times.
For example, assembling
.rept 3 .long 0 .endr
is equivalent to assembling
.long 0 .long 0 .long 0
---------------------------------------------------------------------------------------------
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
// access is not allowed.
.rept 0xC00 - 0xA00
.word 0x00000000
.endr
---------------------------------------------------------------------------------------------
Syntax: .word expressions 分配一段内存单元,并用expressions 初始化
This directive expects zero or more expressions, of any section, separated by commas. For each expression, as
emits a 16-bit number for this target.
----------------------------------------------------------------------------------------------
// 128MB for SDRAM 0xC0000000 -> 0x50000000 这里应该是256M,需要根据自己的开发板配置进行更改
.set __base, 0x500
.rept 0xD00 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
// access is not allowed.
.rept 0x1000 - 0xD00
.word 0x00000000
.endr
#endif
----------------------------------------------------------------------------------
因为上面的分析把代码弄得很散乱,所以在这复制一份完整的,方便对照:如下所示:
/*
* MMU Table for SMDK6400
*/
/* form a first-level section entry */
.macro FL_SECTION_ENTRY base,ap,d,c,b
.word (\base << 20) | (\ap << 10) | \
(\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
.endm
.section .mmudata, "a"
.align 14
// the following alignment creates the mmu table at address 0x4000.
.globl mmu_table
mmu_table:
.set __base,0
// 1:1 mapping for debugging
.rept 0xA00
FL_SECTION_ENTRY __base,3,0,0,0
.set __base,__base+1
.endr
// access is not allowed.
.rept 0xC00 - 0xA00
.word 0x00000000
.endr
// 128MB for SDRAM 0xC0000000 -> 0x50000000
.set __base, 0x500
.rept 0xD00 - 0xC00
FL_SECTION_ENTRY __base,3,0,1,1
.set __base,__base+1
.endr
// access is not allowed.
.rept 0x1000 - 0xD00
.word 0x00000000
.endr
#endif
----------------------------------------------------------------------------
想要弄明白这部分代码,需要对MMU的工作方式有一定的了解,才可以,我的其他博客中,有一些说明,也可以上网上找些资料,有很多这方面的资料。