【问题标题】:exception vector addresses in u-bootu-boot 中的异常向量地址
【发布时间】:2016-05-06 03:35:51
【问题描述】:

我的平台是 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. 如果是正确的,如何将这些向量复制到 0x00000000?直到现在我找不到复制的代码 事物。
  3. 如果在 u-boot 中启用了 MMU,处理程序会变成虚拟地​​址吗?
  4. 如果是正确的,是否需要将虚拟地址转换为物理地址,然后再将它们转换为0x00000000?

谢谢!

BR 程石

【问题讨论】:

  • 为了回答您的问题,我们需要知道您希望用这些知识做什么?你只是想知道异常向量是如何工作的吗?您是否出于某种原因需要更改它们?为什么?您正在调试的问题是否让您相信自己在这里发现了问题?谢谢!
  • 实际上我尝试在 eboot 中添加异常处理程序,并参考 u-boot。我无法理解 u-boot 是如何实现其异常处理程序的。

标签: linux exception memory u-boot


【解决方案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 是否真的是相关问题,因为所有这些都必须很早就发生。

【讨论】:

  • 这也适用于 x86 吗?
  • 就你开始阅读 x86 的 u-boot.lds 和 start.S 文件而言,是的。
猜你喜欢
  • 1970-01-01
  • 2019-12-07
  • 2015-03-23
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-16
相关资源
最近更新 更多