c7e00000 <_start>:
c7e00000: ea000013
b c7e00054 <reset>
c7e00004: e59ff014
ldr pc, [pc, #20]
; c7e00020 <_undefined_instruction>
c7e00008: e59ff014
ldr pc, [pc, #20]
; c7e00024 <_software_interrupt>
c7e0000c: e59ff014
ldr pc, [pc, #20]
; c7e00028 <_prefetch_abort>
c7e00010: e59ff014
ldr pc, [pc, #20]
; c7e0002c <_data_abort>
c7e00014: e59ff014
ldr pc, [pc, #20]
; c7e00030 <_not_used>
c7e00018: e59ff014
ldr pc, [pc, #20]
; c7e00034 <_irq>
c7e0001c: e59ff014
ldr pc, [pc, #20]
; c7e00038 <_fiq>
c7e00020 <_undefined_instruction>:
c7e00020: c7e00200
.word 0xc7e00200
c7e00024 <_software_interrupt>:
c7e00024: c7e00260
.word 0xc7e00260
c7e00028 <_prefetch_abort>:
c7e00028: c7e002c0
.word 0xc7e002c0
c7e0002c <_data_abort>:
c7e0002c: c7e00320
.word 0xc7e00320
c7e00030 <_not_used>:
c7e00030: c7e00380
.word 0xc7e00380
c7e00034 <_irq>:
c7e00034: c7e003e0
.word 0xc7e003e0
c7e00038 <_fiq>:
c7e00038: c7e00440
.word 0xc7e00440
c7e0003c <_pad>:
c7e0003c: 12345678
.word 0x12345678
c7e00040 <_end_vect>:
c7e00040: c7e00000
.word 0xc7e00000
c7e00044 <_TEXT_PHY_BASE>:
c7e00044: 57e00000
.word 0x57e00000
c7e00048 <_armboot_start>:
c7e00048: c7e00000
.word 0xc7e00000
c7e0004c <_bss_start>:
c7e0004c: c7e34000
.word 0xc7e34000
c7e00050 <_bss_end>:
c7e00050: c7e48c54
.word 0xc7e48c54
c7e00054 <reset>:
一. 在start中開始
c7e00000 <_start>:
c7e00000: ea000013
b c7e00054 <reset>
1. 由於ARM體系結構(流水線的問題)(沒有探討)
所以PC = PC + 8
2.uboot剛開始在steppingstone(0x0c00 0000 ,s3c6410)中執行
所以pc = 0xc00 0000 + 8;
3. b指令是相對跳轉(一共24位,其中第24位爲符號位,所以一共能跳轉 正負2^23 個字的距離, 即 正負 2^25 字節, 即正負32MB)
4. 當執行 b reset 之前時,pc = 0xc00 0008
接着跳轉的距離由編譯器自己算出來, 即:ea000013 中的13, 跳轉 19個字
剛好跳轉到 reset, 這時 pc 的值爲 0xc00 0008 + 19 = 0xc00 001B
二. 如何讓代碼在內存中正常運行?
1.首先
int copy_uboot_to_ram (void)
{
int large_block = 0;
int i;
vu_char id;
NAND_ENABLE_CE();
NFCMD_REG = NAND_CMD_READID;
NFADDR_REG = 0x00;
/* wait for a while */
for (i=0; i<200; i++);
id = NFDATA8_REG;
id = NFDATA8_REG;
if (id > 0x80)
large_block = 1;
/* read NAND Block.
* 128KB ->240KB because of U-Boot size increase. by scsuh
* So, read 0x3c000 bytes not 0x20000(128KB).
*/
//CFG_PHY_UBOOT_BASE = 0x57e0 0000
return nandll_read_blocks(CFG_PHY_UBOOT_BASE, 0x3c000, large_block);
}
2.其次
#ifdef CONFIG_ENABLE_MMU
enable_mmu:
/* enable domain access */
ldr r5, =0x0000ffff
mcr p15, 0, r5, c3, c0, 0
@ load domain access register
/* Set the TTB register */
ldr r0, _mmu_table_base
ldr r1, =CFG_PHY_UBOOT_BASE
//MEMORY_BASE_ADDRESS + 0x7e00000=0x57e00000
ldr r2, =0xfff00000
bic r0, r0, r2
orr r1, r0, r1
mcr p15, 0, r1, c2, c0, 0
/* Enable the MMU */
mmu_on:
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #1
/* Set CR_M to enable MMU */
mcr p15, 0, r0, c1, c0, 0
nop
nop
nop
nop
#endif
3.最後
/*******************************************************************************/
c7e0014c: e51ff004
ldr pc, [pc, #-4]
; c7e00150 <_start_armboot>
c7e00150 <_start_armboot>:
c7e00150: c7e03bbc
.word 0xc7e03bbc
c7e00154 <_mmu_table_base>:
c7e00154: c7e30000
.word 0xc7e30000
1.由於ARM體系結構(流水線的問題)
所以PC = PC + 8
2.uboot剛開始在steppingstone(0x0c00 0000 ,s3c6410)中執行
此時 pc = 0xC00 0154
ldr pc, [pc, #-4]
===---===> ldr pc, [0xc00 0150];
執行完這條指令後 pc = 0xc7e0 3bbc;
由此可見ldr指令是絕對轉移, 而這剛好是start_armboot的地址
/********************************************************************************/
0xc7e0 3bbc 怎樣在內存中執行呢?
首先執行ldr pc, [pc, #-4] 後,cpu開始執行0xc7e0 3bbc地址處 的指令
當cpu取 地址時 ,由於之前已經開啓了MMU, 即轉換爲物理地址.(內存中的物理地址)
即從內存中取指令,由於之前已經uboot將自己拷貝到了內存, 所以正常運行.
關於uboot啓動中地址的問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章
S3C6410-DMA裸機編程
Konwledging
2018-08-23 12:09:46
淺析AM335x GPMC模塊地址區域的劃分–TI–Sitara AM335x系列
Shadow_Walker_yz
2018-08-22 04:42:29