Hi all, I am investigating the source code of 2440init.s file to understand how to boot from NAND flash. Basically, I understand the whole code of the file but the problem is that I don't understand how s3c2440 executes the boot process and runs the main function. As I know that the MCU will copy program code from NAND flash to its 4K internal SRAM for execution. From that execution, program code from NAND flash will be copied to an external SRAM. The problem is: - In uVision project, it sets the ROM base addr to 0x30000000 which is the start addr of SRAM space => All labels will have addresses above 0x30000000 (belong to SRAM space) - But at the begining, there is no code exists in SRAM space yet until the boot code copy program code to it. => How MCU executes the boot code in 2440init.s file ???? Ex: At power-on event, MCU copies code of 2440init.s file from NAND flash to the internal SRAM and executes it. The instruction "b ResetHandler" which is transleted to "b 0x3000011C" instructs the MCU to jump to addr 0x3000011C and exececute code from there. But the MCU has not copied program from NAND flash to SRAM yet => no code at addr 0x3000011C => how the MCU continues its execution ??? I tried to search for such question but no result yet. Can anyone help me to understand the execution flow of the MCU for booting NAND flash? Thanks Huy
mini2440test: How to relocate program code from NAND to SRAM?
Are you sure it jumps to 0x3000011C? I guess it branches to "current address + 0x11C" instead. Just an idea.
Hi, I also think about that. But the instruction "b ResetHandler" uses absolute address, not relative address (from ARM instruction set manual) And I am still confused about how it jumps to SRAM to starts user application: In case of booting from NAND, it copies program code from NAND to SRAM starting from 0x3000000. Then it initializes BSS region and executes "bl Main" instruction to jump to main function. => How the instruction "bl Main" jumps to Main function located in SRAM?? Or it just jumps to Main function stored in NAND flash???? Currently, I am stuck in there and need help from everybody.
Where is the 2440init.s file from? it's just one part of the puzzle from what I can see from various sources, it appears that this file is just one part in a bigger project where there is C and/or more assembler that actually handles setting up the registers and memory allocation and jump address correctly. If you look at the datasheet at Table 5-1. Bank 6/7 Addresses, 0x30000000 is the correct place for the ram to start in the virtual address space, 0x3000_0000 is actually 0x0 in your ram. if it's friendlyarm demo code then it's using memcfg.inc and the 2440addr.inc files to pull in the correct addresses :) The memcfg.inc file gives it the 0x3000_0000 start address for ram, the 2440addr.inc file gives it the register addresses, again you can check these against the datasheet, 0x4800_0000 for instance will find you the bwscon register in the datasheet :) you can study those files here: https://github.com/ceeback/FriendlyARM_DemoCode
Hi, Thanks for your response. 1/ In my project, there are two assembler files. 2440init.s is one of them, the other is used as library to access co-processor of ARM7 And I see the code of 2440init.s does booting process. 2/ I do not concern about register addresses defined n 2440addr.inc, but how the MCU execute the booting code. Lets me summarize my understanding and my problem: - At power-on event, if it boots from NAND, the MCU will copy program code from NAND to its 4K stepping stone SRAM for execution => it copies 2440init.s to its internal SRAM - The first instruction in 2440init.s is "b ResetHandler" which instructs the MCU to jump to location of "ResetHandler" and execute code from there However, "ResetHandler" refers to SRAM space (it is 0x3000xxxx). So I am confused because SRAM has no program code at the beginning !!!! I know there is something wrong in my understanding because I can compile and run the project successfully. But I want to correct my knowledge. I put my project to Dropbox, I am appreciate if you take a look and help me to understand it. https://www.dropbox.com/s/097zn0169wt6q6p/33753140keil_2440_000.zip Thanks, Huy
> But the instruction "b ResetHandler" uses absolute address, > not relative address (from ARM instruction set manual) You are wrong. This instruction *branches*, it does not *jump*! The final assembler instruction is always relative to its current address From our bootloader barebox 33e00000: ea00007a b 33e001f0 <barebox_arm_reset_vector> [...] 33e001f0 <barebox_arm_reset_vector>: 0x7a << 2 + 8 = 0x1f0 -> 0x33e00000 + 0x1f0 = 33e001f0 From the ARMARM: --------------------------------------------------------------------- <target_address> Specifies the address to branch to. The branch target address is calculated by: 1. Sign-extending the 24-bit signed (two’s complement) immediate to 32 bits. 2. Shifting the result left two bits. 3. Adding this to the contents of the PC, which contains the address of the branch instruction plus 8. The instruction can therefore specify a branch of approximately ±32MB. --------------------------------------------------------------------- You "bl 0x3000011C" jumps to 0x3000011C when it runs from 0x30000000, but jumps to 0x0000011C if it runs from the stepping stone SRAM in NAND boot case.
Hi Juergen Beisert, I got it. Thank you very much for your information. One more thing I want to ask is how the boot code instructs the MCU to branch to main function in SRAM after it copies all program code from NAND flash to SRAM. I see that it just uses instruction "bl Main" at the end of the routine =>I think it branch to Main function in internal SRAM not the external SRAM Here is the code: ResetHandler ........... ; initialize hardware ........... ; copy program code from NAND to external SRAM InitRam ........... ; initialize bss region in external SRAM bl Main ; => branch to main function in internal SRAM ???? How the instruction gets the MCU branch to the main function in the external SRAM ?? I am appriciate your support. It get me much headache a lot ^_^; Thanks Huy
As the internal SRAM will be used for any kind of data transfer from and to the NAND, the first thing your routine has to do after initializing the external SDRAM is to copy itself out of the way. The regular way is to copy itself to the destination address (linked address) in the external SDRAM and then jump to this address to continue bootstrapping. Then it loads the remaining part from NAND into the external SDRAM. And since your routine already runs from external SDRAM also the branch's target address will be the final address in the external SDRAM.
Hi Juergen Beisert Thank you for your response. I understand your idea. However, I do not see the execution flow of the program as your suggestion (copy from internal SRAM to external SRAM, jump to external SRAM and copy the remaining part of NAND to external SRAM) I attach 2440init file here. Could you have a look and help me to point out: - Where it copies from internal SRAM to external SRAM - Where it jumps to external SRAM - Where it loads the remaining part of NAND to external SRAM I am sorry for asking you many question. I am new in bootloader project and want to get comprehensive knowledge for it. Thanks, Huy
Arrghh, what a ugly code. Sorry, no idea and no time to dig into this code. BTW: please stop using "external SRAM". There is no. The external memory is of type "SDRAM". Only the SoC internal memory is of type "SRAM".
Hi Juergen Beisert, It is OK. I will try to search and investigate more about it. Anyway, thank you for your support. BRs, Huy