Перемещение U-Boot из внутреннего ПЗУ в SRAM на AT91RM9200

Я пытаюсь понять перемещение u-boot из внутреннего ПЗУ в SRAM. В приведенном ниже коде показано, что u-boot копируется из ПЗУ в SRAM, а затем компьютер переходит к _start_armboot. Однако я не могу понять, где в коде происходит операция переназначения памяти.

Выдержка из u-boot-2010.09\arch\arm\cpu\arm920t\start.S

#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate:               /* relocate U-Boot to RAM       */
    adr r0, _start      /* r0 <- current position of code   */
    ldr r1, _TEXT_BASE      /* test if we run from flash or RAM */
    cmp r0, r1          /* don't reloc during debug         */
    beq stack_setup

    ldr r2, _armboot_start
    ldr r3, _bss_start
    sub r2, r3, r2      /* r2 <- size of armboot            */
    add r2, r0, r2      /* r2 <- source end address         */

copy_loop:
    ldmia   r0!, {r3-r10}       /* copy from source address [r0]    */
    stmia   r1!, {r3-r10}       /* copy to   target address [r1]    */
    cmp r0, r2          /* until source end addreee [r2]    */
    ble copy_loop
#endif  /* CONFIG_SKIP_RELOCATE_UBOOT */

    /* Set up the stack                         */
stack_setup:
    ldr r0, _TEXT_BASE      /* upper 128 KiB: relocated uboot   */
    sub r0, r0, #CONFIG_SYS_MALLOC_LEN  /* malloc area              */
    sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */
#ifdef CONFIG_USE_IRQ
    sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
    sub sp, r0, #12     /* leave 3 words for abort-stack    */
    bic sp, sp, #7      /* 8-byte alignment for ABI compliance */

clear_bss:
    ldr r0, _bss_start      /* find start of bss segment        */
    ldr r1, _bss_end        /* stop here                        */
    mov r2, #0x00000000     /* clear                            */

clbss_l:str r2, [r0]        /* clear loop...                    */
    add r0, r0, #4
    cmp r0, r1
    ble clbss_l

    ldr pc, _start_armboot

В техническом описании AT91RM9200 указано, что внутреннее ПЗУ доступно по адресу 0x0000_0000 после сброса, а SRAM доступно только по адресу 0x0020_0000. После переназначения SRAM также доступна по адресу 0x0000_0000, а внутреннее ПЗУ доступно по адресу 0x0010_0000.

Может ли кто-нибудь помочь мне понять операцию переназначения в u-boot и показать мне код, соответствующий этому?

Спасибо


person Manx    schedule 24.12.2014    source источник
comment
Этот код ничего нам не говорит без каких-либо фактических значений для всех задействованных адресов. Я не знаю это устройство, но в техническом описании указано (стр. 125), что команда переназначения доступна через пользовательский интерфейс контроллера памяти путем записи в поле MC_RCR (регистр управления переназначением) RCB значения 1. Очевидно, MC_RCR живет по адресу 0xFFFFFF00 (стр. 129), так что ищите какой-нибудь код, который записывает туда. Вы уверены, что переназначение происходит даже во время этого перемещения? Согласно обзору загрузки (стр. 83), это происходит только после загрузки пользовательской программы из внешнего EEPROM.   -  person Notlikethat    schedule 24.12.2014


Ответы (2)


Я пытаюсь понять перемещение u-boot из внутреннего ПЗУ в SRAM.

Ваш запрос основан на двух недоразумениях.

Ошибочная предпосылка №1: U-Boot хранится во внутреннем ПЗУ.

U-Boot не хранится во внутреннем ПЗУ AT91RM9200.
Внутреннее ПЗУ содержит собственный код Atmel, который не публикуется. В техническом описании AT91RM9200 функциональность этого внутреннего кода ПЗУ описывается как «программа загрузки» и «загрузчик загрузки».

В следующих версиях SoC AT91, продуктов AT91SAM926x, микропрограмма во внутреннем ПЗУ явно упоминается как программа ROM Boot (также известная как RomBOOT (sic)) и Программа мониторинга SAM-BA.

Ошибочная предпосылка №2: U-Boot загружается в SRAM

U-Boot (обычно) не загружается во встроенную SRAM AT91RM9200.
Внутренняя SRAM AT91RM9200 слишком мала (всего 16 КБ минус 3 КБ для стека и переменных), чтобы содержать (типичную) копию U-Boot. .

U-Boot обычно загружается во внешнюю SDRAM загрузчиком второго уровня (в SRAM) (известным как AT91Bootstrap в последующих продуктах AT91SAM).
На AT91M9200 (и других продуктах AT91SAM) U-Boot обычно используется как загрузчик третьего уровня.

При использовании AT91M9200 не должно происходить перемещения U-Boot из внутреннего ПЗУ.


Последовательность загрузки AT91RM9200 была формализована для последующих SoC AT91SAM и показана в следующем Linux4SAM схема. В левой части описываются модули кода и последовательность загрузки, а в правой — физическая память с установленными или загруженными (указаны стрелками) программами.введите здесь описание изображения


ДОПОЛНЕНИЕ

Также см. эту ветку, посвященную загрузчикам AT91RM9200 (для загрузки в u-boot).
Основной текст: "... u-boot (который слишком велик для загрузчика ПЗУ)".
Также упоминается "atmel appnote", по-видимому, о начальной загрузке AT91RM9200, но я не могу найти его на сайте Atmel. Кто-то заархивировал это приложение, Решения для программирования флэш-памяти AT91RM9200DK U-Boot, но эта плата обычно загружается с внешней флэш-памяти NOR (т. е. BMS=1, что отключает внутреннее ПЗУ).

ДОПОЛНЕНИЕ №2

См. эту тему для окончательного (и подтверждения ) отвечает разработчик U-Boot (Вольфганг Денк) и инженер Atmel (Ульф Самуэльссон).
Основной текст: "Как я понял из инструкций от Atmel, перед U-Boot всегда стоит загрузчик. , загрузив его из флэш-памяти данных, последовательного порта или [NAND] Flash ..." (если вы не загружаетесь с внешней NOR-флэш-памяти и BMS=1, т.е. отключите внутреннее ПЗУ).

ДОПОЛНЕНИЕ №3

Пояснение относительно CONFIG_SKIP_RELOCATE_UBOOT:
U-Boot после загрузки в основную память может перемещаться в старшую память, чтобы максимизировать доступную память.
Например, я загрузил образ U-Boot, который был связан для запуска в 0x03F30000 при условии, что было 64 МБ. Однако на самом деле на плате было 128 МБ ОЗУ. Я нашел дубликат образа U-Boot по адресу 0x07F70000.
Выполнение mtest 0x00000000 0x07F00000 протестировано и перезаписало все, кроме самого большого мегабайта ОЗУ, и доказало, что U-Boot, загруженный по адресу 0x03F30000, больше не выполняется. Выполнение mtest 0x04000000 0x08000000 для проверки верхней половины памяти вело себя неправильно/сбой и показало, что U-Boot выполнялся из верхней части памяти, а не в исходном загруженном месте.

person sawdust    schedule 29.12.2014

Я подозреваю, что этот код, если он находится в ПЗУ, был скомпилирован/собран для работы по определенному адресу в ОЗУ (будь то SRAM или SDRAM не имеет значения). Фрагмент кода, который вы опубликовали, написан с использованием независимого от позиции кода. Независимый от позиции код копирует себя в ОЗУ, а затем загружает ПК с фактическим адресом ОЗУ для следующего выполнения. Ваш фрагмент не показывает, где находится _start_armboot, но я предполагаю, что метка находится на следующей инструкции. Здесь не происходит аппаратного переназначения. Вы можете убедиться в этом сами, пошагово пройдя код. Сначала отладчик, вероятно, сможет показать вам только дизассемблированные инструкции, пока вы не пройдете через инструкцию «ldr pc, _start_armboot», когда фактический источник волшебным образом появится (по крайней мере, это то, что сделал бы GDB).

person Richard Pennington    schedule 27.12.2014