See the figure below: This is the arm startup process.
First, describe the hardware before startup, so that it is much easier to analyze startup. S. I am using the smartarm2200 Development Board, among which the CPU chip uses the lpc2210 and there is no internal flash (Zhou Gong is too clever ). Therefore, the setting is two points:
1. Boot [1:0] settings. Decide whether to start from internal memory or external memory. In the face of Zhou Gong, we can only start from external memory. Helpless! This triggers the second extended memory setting.
2. bank0 and bank1 settings. If it is used for debugging, set Ram to bank0, which can be started in Ram, so that memory re ing can be easily performed. If Flash is burned, set flash to bank0.
Therefore, the route in the flowchart is always on the rightmost side. Oh, it was originally started from 0x80000000!
Next we will start to enter the code! First, the relationship diagram of the entire file.
The first running address is 0x80000000. How can we arrange our flash or ram? I remember that the org 0 x method is often used in single-chip microcomputer. We can also set Ro, RW, Zi and entry point addresses in ads. However, this can only be applied to some very simple situations. Now it is more complicated, so the "Distributed Loading Mode" is coming soon. Here we would like to summarize the arm link method:
(1) simple mode: (three-point settings) RO (code base) RW (data base includes zi) under output ). Enter object/symble in LayoutStartup. oSectionStart(Depending on the actual situation) option: Fill in the address of the image entry pointer.
(2) scattered mode: (three steps are required) write the. SCF file, enter the file in output, and enter the entry address in option.
The following is an example of the. SCF file.
/************* Mem_ B .scf file *************/
Rom_load 0x80000000 // address range limit (default in this example)
{
Rom_exec 0x80000000 // size of the out-of-chip memory address range (default in this example)
{
Startup. O (vectors, + first) // put the vector segment in the startup file at the beginning
* (+ RO) // code and read-only data of other modules are stored here
}
Iram 0x40000000 // the size of the On-chip RAM address range (default)
{
Startup. O (mystacks) // put the mystacks segment in the startup file at the beginning
}
Stacks_bottom + 0 uninit // The minimum stack address does not require the initialization range size limit (default)
{
Startup. O (stackbottom) // put the mystackbottom segment in the startup file at the beginning
}
Stacks 0x40004000 uninit
{
Startup. O (stacks)
}
Eram 0x80040000
{
* (+ RW, + zi) // All RW and Zi data are placed here, that is, the uninitialized and initialized global variables.
}
Heap + 0 uninit
{
Startup. O (HEAP)
}
Heap_bottom 0x80080000 uninit
{
Startup. O (heaptop)
}
}
You can use files to observe the actual memory pattern. Under the listings tab of arm linker, select the image map check box. In this way, the memory pattern will be displayed during compilation.
Memory Map of the image
Image entry point: 0x80000000
Load region rom_load (base: 0x80000000, size: 0x000005b4, Max: 0 xffffffff, absolute)
Execution region rom_exec (base: 0x80000000, size: 0x000005b4, Max: 0 xffffffff, absolute)
Base ADDR size type ATTR idx E Section name object
0x80000000 0x00000110 code ro 1 * vectors startup. o
0x80000110 0x000000a8 code Ro 53 *!!! _ Main. O (c_a _ UN. l)
0x800001b8 0x000000dc code RO 10. Text target. o
0x80000294 0x00000078 code Ro 42. Text main. o
0x8000030c 0x00000008 code Ro 55. Text _ no_redirect.o (c_a _ UN. l)
0x80000314 0x000000a4 code Ro 57. Text stkheap2.o (c_a _ UN. l)
0x800003b8 0x00000004 code Ro 59. Text use_no_semi.o (c_a _ UN. l)
0x800003bc 0x00000028 code Ro 61. Text kernel. O (c_a _ UN. l)
0x800003e4 0x0000000c code Ro 63. Text libspace. O (c_a _ UN. l)
0x800003f0 0x00000018 code Ro 66. Text exit. O (c_a _ UN. l)
0x80000408 0x000000fc code Ro 68. Text lib_init.o (c_a _ UN. l)
0x80000504 0x00000010 code Ro 72. Text rt_fp_status_addr.o (c_a _ UN. l)
0x80000514 0x00000014 code Ro 70 x $ FPL $ fpinit. O (f_a_p.l)
0x80000528 0x00000020 data Ro 43. constdata main. o
0x80000548 0x00000054 data Ro 74 region $ table anon $ obj. o
0x8000059c 0x00000018 data Ro 75 zisection $ table anon $ obj. o
Execution region Iram (base: 0x40000000, size: 0x00000400, Max: 0 xffffffff, absolute)
Base ADDR size type ATTR idx E Section name object
0x40000000 0x00000400 zero RW 2 mystacks startup. o
Execution region stacks_bottom (base: 0x40000400, size: 0x00000004, Max: 0 xffffffff, absolute, uninit)
Base ADDR size type ATTR idx E Section name object
0x40000400 0x00000004 zero RW 4 stackbottom startup. o
Execution region stacks (base: 0x40004000, size: 0x00000000, Max: 0 xffffffff, absolute, uninit)
Base ADDR size type ATTR idx E Section name object
0x40004000 0x00000000 zero RW 6 stacks startup. o
Execution region Eram (base: 0x80040000, size: 0x00000060, Max: 0 xffffffff, absolute)
Base ADDR size type ATTR idx E Section name object
0x80040000 0x00000060 zero RW 64. BSS libspace. O (c_a _ UN. l)
Execution region heap (base: 0x80040060, size: 0x00000004, Max: 0 xffffffff, absolute, uninit)
Base ADDR size type ATTR idx E Section name object
0x80040060 0x00000004 zero RW 3 heap startup. o
Execution region heap_bottom (base: 0x80080000, size: 0x00000000, Max: 0 xffffffff, absolute, uninit)
Base ADDR size type ATTR idx E Section name object
0x80080000 0x00000000 zero RW 5 heaptop startup. o
Load region LR $ debug (base: 0x00000000, size: 0x00000000, Max: 0 xffffffff, absolute)
Execution region er $ debug (base: 0x00000000, size: 0x00000000, Max: 0 xffffffff, absolute)
Base ADDR size type ATTR idx E Section name object
0x00000000 0x00000010 dbug RW 9. debug_abbrev startup. o
0x00000010 0x000003ec dbug RW 19. debug_abbrev target. o
0x00000000 0x0000014c dbug RW 18. debug_frame target. o
0x0000014c 0x00000058 dbug RW 52. debug_frame main. o
0x000001a4 0x0000003c dbug RW 54. debug_frame _ main. O (c_a _ UN. l)
0x000001e0 0x0000004c dbug RW 56. debug_frame _ no_redirect.o (c_a _ UN. l)
0x0000022c 0x00000094 dbug RW 58. debug_frame stkheap2.o (c_a _ UN. l)
0x000002c0 0x00000044 dbug RW 60. debug_frame use_no_semi.o (c_a _ UN. l)
0x00000304 0x00000058 dbug RW 62. debug_frame kernel. O (c_a _ UN. l)
0x0000035c 0x00000044 dbug RW 65. debug_frame libspace. O (c_a _ UN. l)
0x000003a0 0x0000004c dbug RW 67. debug_frame exit. O (c_a _ UN. l)
0x000003ec 0x0000007c dbug RW 69. debug_frame lib_init.o (c_a _ UN. l)
0x00000468 0x0000004c dbug RW 71. debug_frame fpinit. O (f_a_p.l)
0x000004b4 0x0000004c dbug RW 73. debug_frame rt_fp_status_addr.o (c_a _ UN. l)
0x00000000 0x00000074 dbug RW 7. debug_info startup. o
0x00000074 0x0000007c dbug RW 12. debug_info target. o
0x000000f0 0x00000108 dbug RW 35. debug_info target. o
0x000001f8 0x000000e4 dbug RW 31. debug_info target. o
0x000002dc 0x00000540 dbug RW 15. debug_info target. o
0x0000081c 0x00000110 dbug RW 27. debug_info target. o
0x0000092c 0x00000090 dbug RW 45. debug_info main. o
0x000009bc 0x00000134 dbug RW 49. debug_info main. o
0x00000000 0x0000009c dbug RW 8. debug_line startup. o
0x0000009c 0x000000b8 dbug RW 11. debug_line target. o
0x00000154 0x000000f8 dbug RW 14. debug_line target. o
0x0000024c 0x00000064 dbug RW 26. debug_line target. o
0x000002b0 0x00000050 dbug RW 30. debug_line target. o
0x00000300 0x00000050 dbug RW 34. debug_line target. o
0x00000350 0x00000078 dbug RW 44. debug_line main. o
0x000003c8 0x000000a4 dbug RW 48. debug_line main. o
0x00000000 0x000002c0 dbug RW 17. debug_loc target. o
0x000002c0 0x00000064 dbug RW 51. debug_loc main. o
0x00000000 0x00000190 dbug RW 13. debug_macinfo target. o
0x00000190 0x00000078 dbug RW 29. debug_macinfo target. o
0x00000208 0x0000004c dbug RW 33. debug_macinfo target. o
0x00000254 0x000001f0 dbug RW 37. debug_macinfo target. o
0x00000444 0x00000190 dbug RW 47. debug_macinfo main. o
0x00000000 0x00000128 dbug RW 16. debug_pubnames target. o
0x00000128 0x00000064 dbug RW 28. debug_pubnames target. o
0x0000018c 0x00000058 dbug RW 32. debug_pubnames target. o
0x000001e4 0x00000084 dbug RW 36. debug_pubnames target. o
0x00000268 0x00000020 dbug RW 46. debug_pubnames main. o
0x00000288 0x00000028 dbug RW 50. debug_pubnames main. o
========================================================== ==========================================================
Image component sizes
Code Ro data RW data Zi data debug
612 140 0 1032 8356 object totals
708 0 0 96 860 library totals
========================================================== ==========================================================
Code Ro data RW data Zi data debug
1320 140 0 1128 9216 grand totals
========================================================== ==========================================================
Total Ro size (code + RO data) 1460 (1.43kb)
Total RW size (RW data + Zi data) 1128 (1.10kb)
Total Rom size (code + RO Data + RW data) 1460 (1.43kb)
========================================================== ==========================================================
**************************************** ************************************
Generally, executable programs include code segments and data segments. It can also be viewed as composed of the RO and RW segments. The RO section generally contains code segments and constants, which are read-only during running. The RW segment includes some global and static variables that can be changed during running (read/write ). If some global variables are initialized to zero, the RW segment also contains the Zi segment.
RO: Read Only code segment
RW: Read Write the initialized global variable
Zi: Zero init uninitialized global variables
The RO segment is read-only and cannot be changed during running, the RO segment can reside in Flash (of course it can also be in SDRAM or SRAM ). The RW segment can be read and written. Therefore, it must be loaded into the SDRAM or SRAM during operation.
When compiling with ads, you need to set Ro base and RW base. If you have used ads, you should be clear about this. By setting Ro base and RW base, the linker is notified of the start running address (RO base) and RW segment address (RW base) of the program ). If a program only has Ro segments and has no RW segments, the program can be run in Flash completely without the need for SDRAM or SRAM. If the RW and Ro segments are included, the RW segments of the program must be copied to the SDRAM or SRAM before being accessed to ensure that the program runs properly. The following figure shows the status of a program before (load view) and execute view. We can see that the entire program is placed in the ROM before execution. During execution, the RW segment is copied to a proper location in Ram.
At the beginning, the program is always stored in ROM/flash. Its Ro part can be executed in ROM/flash or transferred to a faster RAM; RW and Zi must be transferred to writable Ram.The initialization of the application execution environment is to complete the necessary data transmission and content clearing from Rom to ram.
Different tool chains provide different mechanisms and methods to help you complete this step, mainly related to the linker. The following is a direct implementation of a common memory model in the arm development tool environment ads:
LDR r0, = | image $ Ro $ limit |; get the address of the next byte at the end of the RO segment, and the start address of RW in the Rom.
LDR R1, = | image $ RW $ base |; obtain the initial address of the RW segment in Ram.
LDR R3, = | image $ Zi $ base |; initial address of the global variable
CMP r0, R1;
Beq loop1
Loop0
CMP R1, R3; whether it is the last address of the RW segment in Ram. If it is not, it will always copy the ROM (flash variation and Data Segment to ram)
Ldrcc R2, [R0], #4; [R0] = [R1]
Strcc R2, [R1], #4;
BCC loop0
Loop1
LDR R1, = | image $ Zi $ limit |; execute loop1 and loop2 to initialize Zi to 0
MoV R2, #0
Loop2
CMP R3, r1
Strcc R2, [R3], #4;
BCC loop2
In ads, some pre-defined variables can be used (linker defined symbol ). In the following implementation, several predefined variables are used:
Image $ Ro $ base this variable specifies the base of the RO segment
Image $ Ro $ limit this variable specifies the limit of the RO segment
Image $ RW $ base this variable specifies the base of the RW segment
Image $ RW $ limit this variable specifies the limit of the RW segment
Image $ Zi $ base this variable specifies the base of the Zi segment
Image $ Zi $ limit this variable specifies the limit of the Zi segment
Note: For more information, see ads linker guide.
Image $ Ro $ limit minus image $ Ro $ base equals the size of the RO segment
Image $ RW $ limit minus image $ RW $ base equals the size of RW segments
Image $ Zi $ limit minus image $ Zi $ base equals the size of the Zi segment
(Image $ Ro $ limit minus image $ Ro $ base)
+ (Image $ RW $ limit minus image $ RW $ base)
= Equal to the size of the entire program
Note: The Zi segment is included in the RW segment.