2016-04-29 57 views
2

我的平臺是iMX28 + u-boot-2013.10 + Linux-3.12.10。根據我的理解,ARM異常向量應該從0x00000000開始加載到物理地址中。我的u-boot映像被加載到0x40000100,它位於DDR2內存中,iMX28的靜態RAM位於地址0x00000000中。u-boot中的異常向量地址

start.S的代碼如下:

#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG 
.globl _start 
_start: 
.globl _NOR_BOOT_CFG 
_NOR_BOOT_CFG: 
    .word CONFIG_SYS_DV_NOR_BOOT_CFG 
    b reset 
#else 
.globl _start 
_start: 
    b reset 
#endif 
#ifdef CONFIG_SPL_BUILD 
/* No exception handlers in preloader */ 
    ldr pc, _hang 
    ldr pc, _hang 
    ldr pc, _hang 
    ldr pc, _hang 
    ldr pc, _hang 
    ldr pc, _hang 
    ldr pc, _hang 

_hang: 
    .word do_hang 
/* pad to 64 byte boundary */ 
    .word 0x12345678 
    .word 0x12345678 
    .word 0x12345678 
    .word 0x12345678 
    .word 0x12345678 
    .word 0x12345678 
    .word 0x12345678 
#else 
    ldr pc, _undefined_instruction 
    ldr pc, _software_interrupt 
    ldr pc, _prefetch_abort 
    ldr pc, _data_abort 
    ldr pc, _not_used 
    ldr pc, _irq 
    ldr pc, _fiq 

_undefined_instruction: 
    .word undefined_instruction 
_software_interrupt: 
    .word software_interrupt 
_prefetch_abort: 
    .word prefetch_abort 
_data_abort: 
    .word data_abort 
_not_used: 
    .word not_used 
_irq: 
    .word irq 
_fiq: 
    .word fiq 

#endif /* CONFIG_SPL_BUILD */ 
    .balignl 16,0xdeadbeef 


/* 
************************************************************************* 
* 
* Startup Code (reset vector) 
* 
* do important init only if we don't start from memory! 
* setup Memory and board specific bits prior to relocation. 
* relocate armboot to ram 
* setup stack 
* 
************************************************************************* 
*/ 

.globl _TEXT_BASE 
_TEXT_BASE: 
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE) 
    .word CONFIG_SPL_TEXT_BASE 
#else 
    .word CONFIG_SYS_TEXT_BASE 
#endif 

/* 
* These are defined in the board-specific linker script. 
* Subtracting _start from them lets the linker put their 
* relative position in the executable instead of leaving 
* them null. 
*/ 
.globl _bss_start_ofs 
_bss_start_ofs: 
    .word __bss_start - _start 

.globl _image_copy_end_ofs 
_image_copy_end_ofs: 
    .word __image_copy_end - _start 

.globl _bss_end_ofs 
_bss_end_ofs: 
    .word __bss_end - _start 

.globl _end_ofs 
_end_ofs: 
    .word _end - _start 

#ifdef CONFIG_USE_IRQ 
/* IRQ stack memory (calculated at run-time) */ 
.globl IRQ_STACK_START 
IRQ_STACK_START: 
    .word 0x0badc0de 

/* IRQ stack memory (calculated at run-time) */ 
.globl FIQ_STACK_START 
FIQ_STACK_START: 
    .word 0x0badc0de 
#endif 

/* IRQ stack memory (calculated at run-time) + 8 bytes */ 
.globl IRQ_STACK_START_IN 
IRQ_STACK_START_IN: 
    .word 0x0badc0de 

/* 
* the actual reset code 
*/ 

reset: 
    /* 
    * set the cpu to SVC32 mode 
    */ 
    mrs r0,cpsr 
    bic r0,r0,#0x1f 
    orr r0,r0,#0xd3 
    msr cpsr,r0 

    /* 
    * we do sys-critical inits only at reboot, 
    * not when booting from ram! 
    */ 
#ifndef CONFIG_SKIP_LOWLEVEL_INIT 
    bl cpu_init_crit 
#endif 

    bl _main 
... ... 

/* 
* exception handlers 
*/ 
#ifdef CONFIG_SPL_BUILD 
    .align 5 
do_hang: 
    ldr sp, _TEXT_BASE   /* switch to abort stack */ 
1: 
    bl 1b    /* hang and never return */ 
#else /* !CONFIG_SPL_BUILD */ 
    .align 5 
undefined_instruction: 
    get_bad_stack 
    bad_save_user_regs 
    bl do_undefined_instruction 

    .align 5 
software_interrupt: 
    get_bad_stack 
    bad_save_user_regs 
    bl do_software_interrupt 

    .align 5 
prefetch_abort: 
    get_bad_stack 
    bad_save_user_regs 
    bl do_prefetch_abort 

    .align 5 
data_abort: 
    get_bad_stack 
    bad_save_user_regs 
    bl do_data_abort 

    .align 5 
not_used: 
    get_bad_stack 
    bad_save_user_regs 
    bl do_not_used 

#ifdef CONFIG_USE_IRQ 

    .align 5 
irq: 
    get_irq_stack 
    irq_save_user_regs 
    bl do_irq 
    irq_restore_user_regs 

    .align 5 
fiq: 
    get_fiq_stack 
    /* someone ought to write a more effiction fiq_save_user_regs */ 
    irq_save_user_regs 
    bl do_fiq 
    irq_restore_user_regs 

#else 

    .align 5 
irq: 
    get_bad_stack 
    bad_save_user_regs 
    bl do_irq 

    .align 5 
fiq: 
    get_bad_stack 
    bad_save_user_regs 
    bl do_fiq 

#endif 
#endif /* CONFIG_SPL_BUILD */ 

我的問題是

  1. 異常處理程序不在所需的地址00000000,是 是正確的?
  2. 如果< 1>是對的,如何將這些向量複製到 0x00000000?到現在爲止,我找不到複製 東西的代碼。
  3. 如果在u-boot中啓用了MMU,那麼處理程序是否成爲虛擬地址?
  4. 如果< 3>是正確的,是否有必要將虛擬地址轉換爲物理地址,然後將它們複製到0x00000000?

謝謝!

BR 程石

+0

爲了回答你的問題,我們需要知道你想要做什麼知識?你只是想知道異常向量如何工作?你需要改變他們出於某種原因?爲什麼?有沒有你正在調試的問題,導致你相信你在這裏發現了問題?謝謝! –

+0

其實我試着在eboot中加入引用u-boot的異常處理程序。我無法理解u-boot如何實現它的異常處理程序。 – x10

回答

1

這是一個有點更清楚瞭解我們如何通過當前看在寫這篇文章主線的U-Boot設置在U-Boot的異常向量。對於鏈接描述文件,請參考vectors.Sarmv7/start.Su-boot.lds

考慮到所有這些,要回答#1,不,它們最初不是在0x0,而是鏈接器腳本放置它們的圖像內的位置。他們很早就被放置在身體上,以確保他們可以被輕鬆訪問和複製。答案#2的代碼是:

/* Set vector address in CP15 VBAR register */ 

是什麼意思。然後,我不確定#3 /#4是否真的是相關的問題,因爲所有這些都必須儘早發生。

+0

這是否也適用於x86? – Bionix1441

+0

只要您首先閱讀x86的u-boot.lds和start.S文件,是的。 –