u-boot

时间:2016-04-29 08:28:41

标签: linux exception memory u-boot

我的平台是iMX28 + u-boot-2013.10 + Linux-3.12.10。

根据我的理解,ARM异常向量应该从0x00000000开始加载到物理地址中。我的u-boot映像加载到DDR2内存中的0x40000100,而iMX28的静态RAM位于地址0x00000000中。

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. 异常处理程序不在所需的地址0x00000000中,是 对的?
  2. 如果< 1>是对的,如何将这些载体复制到 00000000?到现在为止,我找不到复制的代码 的东西。
  3. 如果在u-boot中启用了MMU,那么处理程序是否会成为虚拟地址?
  4. 如果< 3>是对的,是否有必要在将虚拟地址转换为0x00000000之前将其转换为物理地址?
  5. 谢谢!

    BR 程世

1 个答案:

答案 0 :(得分:1)

通过查看写作主线U-Boot中的当前内容,了解如何在U-Boot中设置异常向量更清楚一点。有关此vectors.S的参考,请参阅此链接器脚本armv7/start.S和此u-boot.lds

考虑到所有这些,回答#1,不,它们最初不在0x0,而是在链接器脚本放置它们的图像中。它们很早就放置在物理上,以确保它们可以轻松访问和复制。 #2的答案是代码:

/* Set vector address in CP15 VBAR register */

就是那样做的。然后我不确定#3 /#4是否真的是相关的问题,因为所有这些都必须很早发生。