Vivi analysis-head. S-> main. c

Source: Internet
Author: User

I have been reading Vivi recently. By the way, I want to streamline the useful parts of VIVI to make up my own code.

After completing the Assembly, head. s finally jumped into main. C. In this process, I add functions one by one. Each time a function is added, the next function is added until the test is successful. I think this accumulation is also beneficial. I may have a detailed understanding of each function module and every step, and I can quickly locate the problem. Of course, the most important thing is to go deep into the details, where you can learn a lot and learn a lot. ("Learning" is different from "Mastering)

 

I jumped from head. s to main. C and made a mistake in this process. In fact, I have some knowledge about the running domain and the loading domain, but I am stuck here. Here we will analyze:

 

First of all, it must be clear that the B/BL command cannot be used for this jump. Because 2410 of SDRAM is generally stored in bank6 (0x30000000), we need to jump from bank0 to bank6, b/BL only has a range of +/-32 m (which has been analyzed in another article ). Therefore, this jump can only be achieved by writing values directly to the PC.

This jump process in vivi adopts the "Spring bed" technique. Let's take a look at how it is implemented in Vivi:

@ 10 jump to ram
LDR R1, = on_the_ram // Save the on_the_ram address to r1
Add PC, R1, #0 // load the address to PC and jump into on_the_ram
NOP
NOP
1:
B.


// After the link, the code after on_the_ram will be linked to a location in the SDRAM
On_the_ram:
MoV R1, # gpio_ctl_base
Add R1, R1, # ogpio_f
MoV R2, # 0xff
STR R2, [R1, # ogpio_dat]

@ Print prompt information
LDR R1, serbase
LDR r0, str_stack
BL printword
LDR r0, dw_stack_start
BL printhexword
MoV r0, PC
BL printhexword

LDR sp, dw_stack_start
MoV FP, #0
MoV A2, #0
// The previous sentence is used for testing. Turn off the light and print the stack address and the current PC address to the serial port.

BL main // here, a streaming light is written in Main. C to help you see the effect.

MoV PC, # flash_base

As you can see above, after the sentence "add PC, R1, #0", the program has started to run in SDRAM.

Second, pay attention to the following details: "location-independent code" and "location-related code ".

Location-independent code, that is, code runs correctly wherever it is placed after the link. The program runs in sequence, but the location issue arises during the jump. How is the jump Destination Address calculated? In command B/BL, the target address is calculated by the current PC, and the target address is a relative volume (relative to the current PC ).

Location-related code. After the link, the Code must be placed in the specified place to run correctly. When linking, it mainly links the symbol in the program and gives it an address. In the LDR R1, = on_the_ram command, the address value of on_the_ram is determined after the link. That is to say, the CPU will jump to the specified address after it, and we must put our code in the specified address so that the CPU can run the correct command. Otherwise, an error occurs.

Let's take a look at the compilation process of these programs:

vivi:head.S nand_read.c
     arm-linux-gcc -c head.S -I ../../include/ -o head.o
     arm-linux-gcc -c nand_read.c -I ../../include/ -o nand_read.o
     arm-linux-gcc -c main.c -o main.o
     arm-linux-ld -Ttext 0x33f00000 head.o nand_read.o main.o -o tmp.o
     arm-linux-objcopy -O binary -S tmp.o vivi
     arm-linux-objdump -D -b binary -m arm vivi > aaa

clean:
     rm *~ -f
     rm *.o -f
     rm vivi -f

Makefile is a beginner. The link address of the program is 0x33f00000. That is, after the link, the on_the_ram address value must be after 0x33f00000 (in bank6), instead of the address in bank0.

You can also directly write a link script to make it more intuitive:
Sections {
First 0x33f00000: {head. O nand_read.o main. O}
}
It is also very simple here, and it is directly linked to 0x33f00000. All previous operations in LDR R1, = on_the_ram are location-independent code. Copying nand_read.c of NAND is naturally a location-independent code, these operations can be correctly executed whether starting from 0 or 0x33f00000.

Again, why is the link 0x33f00000? In fact, it is very simple. In head. S, I copied the entire code to the beginning of 0x33f00000. If the link reaches 0x30000000, the CPU is allocated to on_the_ram from the corresponding position after 0x30000000, which is naturally not found. I made a mistake and linked it to 0x30000000.

 

Finally, let's look at the disassembly code.

DC: e59f13e8 LDR R1, [PC, #1000]; 0x4cc // This sentence is LDR R1, = on_the_ram, which assigns the value at 0x4cc to R1, that is, R1 = 0x33f000f0
   e0:     e281f000     add     pc, r1, #0    ; 0x0
   e4:     e1a00000     nop            (mov r0,r0)
   e8:     e1a00000     nop            (mov r0,r0)
   ec:     eafffffe      b     0xec
   f0:     e3a01456     mov     r1, #1442840576    ; 0x56000000 //
This is nowOn_the_ram, all of which are in the SDRAM
F4: e2811050 add R1, R1, #80; 0x50
F8: e3a020ff mov R2, #255; 0xff
FC: e582134 STR R2, [R1, #4] // turn off the light
100: e59f138c LDR R1, [PC, #908]; 0x494
104: e59f03b2 LDR r0, [PC, #946]; 0x4be
108: eb1_c0 BL 0x410 // call the subroutine for printing information
10c: e59f038c LDR r0, [PC, #908]; 0x4a0
110: eb1_a3 BL 0x3a4 // call the subroutine for printing information
114: e1a0000f mov r0, PC
118: eb1_a1 BL 0x3a4 // call the subroutine for printing information
11c: e59fd37c LDR sp, [PC, #892]; 0x4a0
120: e3a0b000 mov FP, #0; 0x0
124: e3a01000 mov R1, #0; 0x0
128: eb000174 BL 0x700 // 0x700 is followed by the content in main.
12c: e3a0f000 mov PC, #0; 0x0

4cc: 33f000f0 mvnccs r0, #240; 0xf0 // the machine code of this command is 33f000f0, which actually stores such a value
4d0: 127f830 andeq PC, R0, R0, LSR R8 // This is also the same principle. The 0x0000f830 value is stored. It looks familiar. It is used to configure NAND Flash.

Finally, paste the printed information:

@ 000000d4 // print the Pc value for the first time after the UART is initialized
MTST-OK // memory Detection
OK // NAND copy
NAND-OK // detected after Replication
St

33 defffc // Stack pointer
33f0011c // current PC

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.