ecos代码分析(1)
前面分析了u-boot,再分析一下ecos,听说ecos比较复杂,所以还是采取挨船下竿的原则,分析u-boot相似的smdk2410这块开发板。
1. 首先找到链接文件
<hal/arm/arm9/smdk2410/v3_0/include/pkgconf/mlt_arm_arm9_smdk2410_romram.ldi>
7 MEMORY
8 {
9 ram : ORIGIN = 0, LENGTH = 0x4000000
10 sram : ORIGIN = 0x40000000, LENGTH = 0x1000
11 }
13 SECTIONS
14 {
15 SECTIONS_BEGIN
16 SECTION_fixed_vectors (ram, 0x20, LMA_EQ_VMA)
17 SECTION_rom_vectors (ram, 0x8000, LMA_EQ_VMA)
18 SECTION_RELOCS (ram, ALIGN (0x1), LMA_EQ_VMA)
19 SECTION_text (ram, ALIGN (0x4), LMA_EQ_VMA)
20 SECTION_fini (ram, ALIGN (0x4), LMA_EQ_VMA)
21 SECTION_rodata (ram, ALIGN (0x4), LMA_EQ_VMA)
22 SECTION_rodata1 (ram, ALIGN (0x4), LMA_EQ_VMA)
23 SECTION_got (ram, ALIGN (0x4), LMA_EQ_VMA)
24 SECTION_fixup (ram, ALIGN (0x4), LMA_EQ_VMA)
25 SECTION_gcc_except_table (ram, ALIGN (0x4), LMA_EQ_VMA)
26 SECTION_data (ram, ALIGN (0x4), LMA_EQ_VMA)
27 SECTION_bss (ram, ALIGN (0x4), LMA_EQ_VMA)
28 CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
29 SECTIONS_END
30 }
可以看出memory空间的安排 和 sections的安排
其中的宏定义,要看文件
<hal/arm/arch/v3_0/src/arm.ld>
42 STARTUP(vectors.o)
43 ENTRY(reset_vector)
44 INPUT(extras.o)
91 #define SECTIONS_BEGIN \
92 \
93 .debug_aranges 0 : { *(.debug_aranges) } \
94 .debug_pubnames 0 : { *(.debug_pubnames) } \
95 .debug_info 0 : { *(.debug_info) } \
96 .debug_abbrev 0 : { *(.debug_abbrev) } \
97 .debug_line 0 : { *(.debug_line) } \
98 .debug_frame 0 : { *(.debug_frame) } \
99 .debug_str 0 : { *(.debug_str) } \
100 .debug_loc 0 : { *(.debug_loc) } \
101 .debug_macinfo 0 : { *(.debug_macinfo) } \
102 .note.arm.ident 0 : { KEEP (*(.note.arm.ident)) } \
103 /DISCARD/ 0 : { *(.fini_array*) }
345 #define SECTION_bss(_region_, _vma_, _lma_) \
346 .bss _vma_ : _lma_ \
347 { __bss_start = ABSOLUTE (.); \
348 *(.scommon) *(.dynsbss) *(.sbss*) *(.gnu.linkonce.sb.*) \
349 *(.dynbss) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON) \
350 __bss_end = ABSOLUTE (.); } \
351 > _region_
353 #define SECTIONS_END . = ALIGN(4); _end = .; PROVIDE (end = .);
编译过程中会看到
165 arm-eabi-gcc -E -P -Wp,-MD,target.tmp -xc -I/usr/local/ecos/ecos-3.0/build/install/include -I/usr/local/ecos/ecos-3.
0/packages/hal/arm/arch/v3_0 -I/usr/local/ecos/ecos-3.0/packages/hal/arm/arch/v3_0/src -I/usr/local/ecos/ecos-3.0/pac
kages/hal/arm/arch/v3_0/tests -I. -finline-limit=7000 -mcpu=arm9 -Wall -Wpointer-arith -Wstrict-prototypes -Winline -
Wundef -g -O2 -ffunction-sections -fdata-sections -fno-exceptions -mno-thumb-interwork -o /usr/local/ecos/ecos-3.
0/build/install/lib/target.ld /usr/local/ecos/ecos-3.0/packages/hal/arm/arch/v3_0/src/arm.ld
将arm.ld编译生成target.ld,这个作为最终生成文件的链接文件
170 arm-eabi-gcc --no-target-default-spec -Wl,--gc-sections -Wl,-static -g -O2 -nostdlib -mno-thumb-interwork -L/usr/loca
l/ecos/ecos-3.0/build/install/lib -Ttarget.ld -o /usr/local/ecos/ecos-3.0/build/install/bin/redboot.elf /usr/local/ec
os/ecos-3.0/build/install/lib/version.o
看看最终生成的链接文件
1 STARTUP(vectors.o)
2 ENTRY(reset_vector)
3 INPUT(extras.o)
4 GROUP( libtarget.a libgcc.a libsupc++.a )
9 MEMORY
10 {
11 ram : ORIGIN = 0x20000000, LENGTH = 0x2000000
12 sram : ORIGIN = 0x00200000, LENGTH = 0x4000
13 rom : ORIGIN = 0x10000000, LENGTH = 0x200000
14 }
16 SECTIONS
17 {
18 .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } .debug_info 0 : { *(.debug_in
fo) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } .note.arm.
ident 0 : { KEEP (*(.note.arm.ident)) } /DISCARD/ 0 : { *(.fini_array*) }
19 .fixed_vectors 0x00200020 : { . = .; KEEP (*(.fixed_vectors)) } > sram
20 .rom_vectors 0x20010000 : { __rom_vectors_vma = ABSOLUTE(.); . = .; KEEP (*(.vectors)) } > ram __rom_vectors_lma
= LOADADDR(.rom_vectors);
21 .rel.text : { *(.rel.text) *(.rel.text.*) *(.rel.gnu.linkonce.t*) } > ram .rela.text : { *(.rela.text) *(.rela.te
xt.*) *(.rela.gnu.linkonce.t*) } > ram .rel.data : { *(.rel.data) *(.rel.data.*) *(.rel.gnu.linkonce.d*) } > ram .rel
a.data : { *(.rela.data) *(.rela.data.*) *(.rela.gnu.linkonce.d*) } > ram .rel.rodata : { *(.rel.rodata) *(.rel.rodat
a.*) *(.rel.gnu.linkonce.r*) } > ram .rela.rodata : { *(.rela.rodata) *(.rela.rodata.*) *(.rela.gnu.linkonce.r*) } >
ram .rel.got : { *(.rel.got) } > ram .rela.got : { *(.rela.got) } > ram .rel.ctors : { *(.rel.ctors) } > ram .rela.ct
ors : { *(.rela.ctors) } > ram .rel.dtors : { *(.rel.dtors) } > ram .rela.dtors : { *(.rela.dtors) } > ram .rel.init
: { *(.rel.init) } > ram .rela.init : { *(.rela.init) } > ram .rel.fini : { *(.rel.fini) } > ram .rela.fini : { *(.re
la.fini) } > ram .rel.bss : { *(.rel.bss) } > ram .rela.bss : { *(.rela.bss) } > ram .rel.plt : { *(.rel.plt) } > ram
.rela.plt : { *(.rela.plt) } > ram .rel.dyn : { *(.rel.dyn) } > ram
22 .ARM.extab ALIGN (0x4) : { PROVIDE (__stext = ABSOLUTE(.)); _stext = ABSOLUTE(.) ; . = .; } > ram /DISCARD/ 0 : {
*(.ARM.extab* .gnu.linkonce.armextab.*) } . = ALIGN(8); . = ALIGN(8); __exidx_start = ABSOLUTE(.); .ARM.exidx ALIGN(
8) : AT ((LOADADDR (.ARM.extab) + SIZEOF (.ARM.extab) + (8) - 1) & ~ ((8) - 1)) { . = .; } > ram __exidx_end = ABSOLU
TE(.); /DISCARD/ 0 : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } .text ALIGN(8) : AT ((LOADADDR (.ARM.exidx) + SIZEOF
(.ARM.exidx) + (8) - 1) & ~ ((8) - 1)) { *(.text*) *(.gnu.warning) *(.gnu.linkonce.t.*) *(.init) *(.glue_7) *(.glue_
7t) __CTOR_LIST__ = ABSOLUTE (.); KEEP (*(SORT (.ctors*))) __CTOR_END__ = ABSOLUTE (.); __DTOR_LIST__ = ABSOLUTE (.);
KEEP (*(SORT (.dtors*))) __DTOR_END__ = ABSOLUTE (.); } > ram _etext = .; PROVIDE (__etext = .);
23 .fini ALIGN (0x4) : { . = .; *(.fini) } > ram
24 .rodata ALIGN (0x4) : { . = .; *(.rodata*) *(.gnu.linkonce.r.*) } > ram
25 .rodata1 ALIGN (0x4) : { . = .; *(.rodata1) } > ram
26 .got ALIGN (0x4) : { . = .; *(.got.plt) *(.got) _GOT1_START_ = ABSOLUTE (.); *(.got1) _GOT1_END_ = ABSOLUTE (.);
_GOT2_START_ = ABSOLUTE (.); *(.got2) _GOT2_END_ = ABSOLUTE (.); } > ram
27 .fixup ALIGN (0x4) : { . = .; *(.fixup) } > ram
28 .gcc_except_table ALIGN (0x4) : { . = .; } > ram /DISCARD/ 0 : { *(.gcc_except_table*) }
29 .data ALIGN (0x4) : { __ram_data_start = ABSOLUTE (.); *(.data*) *(.data1) *(.gnu.linkonce.d.*) . = ALIGN (4); KE
EP(*( SORT (.ecos.table.*))) ; . = ALIGN (4); __init_array_start__ = ABSOLUTE (.); KEEP (*(SORT (.init_array.*))) KEE
P (*(SORT (.init_array))) __init_array_end__ = ABSOLUTE (.); *(.dynamic) *(.sdata*) *(.gnu.linkonce.s.*) . = ALIGN (4
); *(.2ram.*) } > ram __rom_data_start = LOADADDR (.data); __ram_data_end = .; PROVIDE (__ram_data_end = .); _edata =
.; PROVIDE (edata = .); PROVIDE (__rom_data_end = LOADADDR (.data) + SIZEOF(.data));
30 .bss ALIGN (0x4) : { __bss_start = ABSOLUTE (.); *(.scommon) *(.dynsbss) *(.sbss*) *(.gnu.linkonce.sb.*) *(.dynbs
s) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON) __bss_end = ABSOLUTE (.); } > ram
31 __heap1 = ALIGN (0x8);
32 . = ALIGN(4); _end = .; PROVIDE (end = .);
33 }
内存分配:
11 ram : ORIGIN = 0x20000000, LENGTH = 0x2000000
12 sram : ORIGIN = 0x00200000, LENGTH = 0x4000
13 rom : ORIGIN = 0x10000000, LENGTH = 0x200000
ram 0x20000000 32M
sram 0x00200000 16K
rom 0x10000000 2M
sections分配就暂时不看了,一大堆的
再看最开头
1 STARTUP(vectors.o)
2 ENTRY(reset_vector)
3 INPUT(extras.o)
4 GROUP( libtarget.a libgcc.a libsupc++.a )
说明要从vectors.o文件的reset_vector开始运行,这就是开始的地方。
2. reset_vector开始
在<hal\arm\arch\v3_0\cdl\hal_arm.cdl>
有和vectors.o相关行: <PREFIX>/lib/vectors.o : <PACKAGE>/src/vectors.S
< hal/arm/arch/v3_0/src/vectors.S >
289 .text
290 // Startup code which will get the machine into supervisor mode
291 .global reset_vector
292 .type reset_vector,function
293 reset_vector:
294 PLATFORM_SETUP1 // Early stage platform initialization
295 // which can set DRAM size at 0x40
296 // see <cyg/hal/hal_platform_setup.h>
代码段
PLATFORM_SETUP1是个宏,作用后面的注释有提到,先期初始化平台
<hal/arm/arm9/smdk2410/v3_0/include/hal_platform_setup.h>
#define PLATFORM_SETUP1 _platform_setup1
122 .macro _platform_setup1
123 #ifndef CYG_HAL_STARTUP_RAM
124 ldr r0,=WTCON // watch dog disable
125 ldr r1,=0x0
126 str r1,[r0]
127 #endif
128 RAW_LED_PORT_INIT_MACRO
130 #ifndef CYG_HAL_STARTUP_RAM
131 ldr r0,=INTMSK
132 ldr r1,=0xffffffff // all interrupt disable
133 str r1,[r0]
135 ldr r0,=INTSUBMSK
136 ldr r1,=0x7ff // all sub interrupt disable
137 str r1,[r0]
139 RAW_LED_MACRO 1
141 // Disable and clear caches
142 mrc p15,0,r0,c1,c0,0
143 bic r0,r0,#0x1000 // disable ICache
144 bic r0,r0,#0x000f // disable DCache, write buffer,
145 // MMU and alignment faults
146 mcr p15,0,r0,c1,c0,0
147 nop
148 nop
149 mov r0,#0
150 mcr p15,0,r0,c7,c6,0 // clear data cache
151 #if 0
152 mrc p15,0,r0,c15,c1,0 // disable streaming
153 orr r0,r0,#0x80
154 mcr p15,0,r0,c15,c1,0
155 #endif
157 // To reduce PLL lock time, adjust the LOCKTIME register.
158 ldr r0,=LOCKTIME
159 ldr r1,=0xffffff
160 str r1,[r0]
162 // We must set ratios, set memctl, then change FCLK.
163 ldr r0,=CLKDIVN // Set ratios 1:2:4 for FCLK:HCLK:PCLK
164 ldr r1,=(3)
165 str r1,[r0]
167 // MMU_SetAsyncBusMode //Must select, since we're setting HDIVN=1
168 #define R1_iA (1<<31)
169 #define R1_nF (1<<30)
170 mrc p15,0,r0,c1,c0,0
171 orr r0,r0,#(R1_nF|R1_iA)
172 mcr p15,0,r0,c1,c0,0
175 // Set memory control registers
176 adr r0,1f
177 ldr r1,=BWSCON // BWSCON Address
178 add r2, r0, #52 // End address of SMRDATA
179 0:
180 ldr r3, [r0], #4
181 str r3, [r1], #4
182 cmp r2, r0
183 bne 0b
184 b 2f
186 1:
187 // Memory configuration should be optimized for best performance
188 // The following parameter is not optimized.
189 // Memory access cycle parameter strategy
190 // 1) The memory settings is safe parameters even at HCLK=75Mhz.
191 // 2) SDRAM refresh period is for HCLK=75Mhz.
192
193 .long (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BW
SCON<<28))
194 .long ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) //GCS0
195 .long ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) //GCS1
196 .long ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) //GCS2
197 .long ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) //GCS3
198 .long ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) //GCS4
199 .long ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) //GCS5
200 .long ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) //GCS6
201 .long ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) //GCS7
202 .long ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
203
204 .long 0x32 // SCLK power saving mode, BANKSIZE 128M/128M
205
206 .long 0x30 // MRSR6 CL=3clk
207 .long 0x30 // MRSR7
208 // .long 0x20 // MRSR6 CL=2clk
209 // .long 0x20 // MRSR7
210
211 2:
212 RAW_LED_MACRO 2
213
214 // Configure MPLL
215 ldr r0,=MPLLCON
216 ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV) // Fin=12MHz,Fout=50MHz
217 str r1,[r0]
218
219 #endif
220
221 // Set up a stack [for calling C code]
222 ldr r1,=__startup_stack
223 ldr r2,=SMDK2410_SDRAM_PHYS_BASE
224 orr sp,r1,r2
225
226 // Create MMU tables
227 RAW_LED_MACRO 3
228 bl hal_mmu_init
229 RAW_LED_MACRO 4
230
231 // Enable MMU
232 ldr r2,=10f
233 #ifdef CYG_HAL_STARTUP_ROMRAM
234 ldr r1,=__exception_handlers
235 ldr r9,=0x80000000
236 sub r1,r2,r1
237 add r2,r9,r1 // r9 has ROM offset
238 #endif
239 ldr r1,=MMU_Control_Init|MMU_Control_M
240 mcr MMU_CP,0,r1,MMU_Control,c0
241 mov pc,r2
242 nop
243 nop
244 nop
245 10:
246 RAW_LED_MACRO 5
247
248 #ifdef CYG_HAL_STARTUP_ROMRAM
249 mov r0,r9 // Relocate FLASH/ROM to RAM
250 ldr r1,=__exception_handlers // ram base & length
251 ldr r2,=__rom_data_end
252 20: ldr r3,[r0],#4
253 str r3,[r1],#4
254 cmp r1,r2
255 bne 20b
256 ldr r0,=30f
257 mov pc,r0
258 nop
259 nop
260 nop
261 nop
262 30:
263 #endif
264 RAW_LED_MACRO 6
265 .endm
这里面都是汇编写的,一个一个写寄存器而已,作用注释很清楚,想了解更详细就要看寄存器手册了。