Создание загрузочной программы в RISC-V - PullRequest
0 голосов
/ 27 октября 2019

Я пытаюсь создать загрузочную программу для плат на основе RISC-V. Я следую этому руководству и адаптирую его к riscv. osdev

У меня проблема с переводом этой инструкции. times 510 -( $ - $$ ) db 0

Лучшее, что я мог придумать, - это просто заполнить 63 строки этого .8byte 0 Но это не представляется возможным.

Вот полный код.

#################################
########### Boot Init ###########
#################################

.section .text

start:                          # begins the program
    nop                         # the do nothing instruction
    j start                     # loops back to start

# Todo:: figure out the size of the np and j instruction
# The intent of this portion is to fill the remaning bin file with 0's up until the last two bytes

.section .rodata
    .4byte 0                    # size of start instructions + this

    .8byte 0                    # begins the zero's, currently 510 byte
    .8byte 0
     # repeat 60ish times

    .8byte 0x0000000000aa55     # fills the last two bytes with the universal 
                                # 55aa to indicate boot program

РЕДАКТИРОВАТЬ

Я использую набор инструментов gcc для risc. Найдено здесь . Я использую директиву .rept.

Вот обновленный код.

#################################
########### Boot Init ###########
#################################

start:                          # begins the program
    nop                         # the do nothing instruction
    j start                     # loops back to start

# Todo:: figure out the size of the np and j instruction
# The intent of this portion is to fill the file with 0's up until the last few bytes

    .rept 63
    .8byte 0
    .endr

    .4byte 0                    # size of start instructions + this

    .8byte 0                    # begins the zero's, currently 510 byte
    .8byte 0

    .8byte 0x0000000000aa55     # fills the last two bytes with the universal 
                                # 55aa to indicate boot program

Шестнадцатеричный дамп ниже:

00000000  01 00 fd bf 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000210  55 aa 00 00 00 00 00 00                           |U.......|
00000218

Здесь я вижу, что я явно испортил порядок кода. Однако у меня новый вопрос. Какого чёрта происходит с левым столбцом шестнадцатеричного дампа ?? Я понимаю, что * означает, что он заполнен до 0. Однако строка идет от 0 до 10, затем от 210 до 218, почему она увеличилась сначала на 10, а затем на 8 в конце? почему у меня пустая строка (218)?

РЕДАКТИРОВАТЬ Не нужно рассказывать мне о нумерации строк, теперь я понял, что это гекс. Итак, последний вопрос остается. Как мне указать на эту плату , что программа является загрузочной программой. Есть ли магическое число? Я не смог найти никаких указаний ни в одной из их документации.

Ответы [ 2 ]

2 голосов
/ 27 октября 2019

times не является инструкцией. Это директива ассемблера. $ возвращает ваш текущий адрес, а $$ обозначает начало вашего текущего сектора. Итак, вы заполняете оставшиеся части вашего 512-байтового сектора 0 (магические числа 2 байта). Да, 64 строки кода определенно не будут работать. Поддержка команды times будет зависеть от вашего ассемблера. Итак, если есть ассемблер, который поддерживает TIMES и RISC-V, вы должны иметь возможность использовать times. NASM поддерживает директиву times, и существует версия NASM для RISC-V https://github.com/riscv/riscv-nasm. Итак, вы должны это проверить.

1 голос
/ 28 октября 2019

РЕДАКТИРОВАТЬ только что получил мою доску rev.

Вы можете посмотреть в руководстве по началу работы, чтобы увидеть, как определить доску, используя их песочницу. Но это не обязательно, если у вас есть (gnu) набор инструментов, который поддерживает rv32i или больше, чем этот rv32imac, вы можете создавать программы без других внешних зависимостей.

Сама цепочка инструментов не знает одну плату от другой, одну микросхему от другой.

В документации Sifive говорится:

Плата HiFive1 Rev B поставляется с модифицируемым загрузчикомв начале SPI Flash (0x20000000). В конце выполнения этой программы ядро ​​переходит к основной пользовательской части кода в 0x20010000.

И это критическая информация, которая нам нужна, плюс адресное пространство для памяти в карте памяти для части 0x80000000 0x4000байт sram.

novectors.s

.globl _start
_start:
    lui x2,0x80004
    jal notmain
    j .

.globl dummy
dummy:
    ret

.globl PUT32
PUT32:
    sw x11,(x10)
    ret

.globl GET32
GET32:
    lw x10,(x10)
    ret

notmain.c

void PUT32( unsigned int, unsigned int);
unsigned int GET32 ( unsigned int );
void  dummy ( unsigned int );

#define GPIOBASE 0x10012000
#define GPIO_VALUE          (GPIOBASE+0x00)
#define GPIO_INPUT_EN       (GPIOBASE+0x04)
#define GPIO_OUTPUT_EN      (GPIOBASE+0x08)
#define GPIO_PORT           (GPIOBASE+0x0C)
#define GPIO_PUE            (GPIOBASE+0x10)
#define GPIO_OUT_XOR        (GPIOBASE+0x40)

int notmain ( void )
{
    unsigned int rx;

    PUT32(GPIO_OUTPUT_EN,(1<<19)|(1<<21)|(1<<22));
    PUT32(GPIO_PORT,(1<<19)|(1<<21)|(1<<22));
    PUT32(GPIO_OUT_XOR,0);
    while(1)
    {
        PUT32(GPIO_PORT,(1<<19)|(1<<21)|(1<<22));
        for(rx=0;rx<2000000;rx++) dummy(rx);
        PUT32(GPIO_PORT,0);
        for(rx=0;rx<2000000;rx++) dummy(rx);
    }

    return(0);
}

memmap

MEMORY
{
    rom : ORIGIN = 0x20010000, LENGTH = 0x1000
    ram : ORIGIN = 0x80000000, LENGTH = 0x4000
}
SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}

build

riscv32-none-elf-as -march=rv32imac -mabi=ilp32 novectors.s -o novectors.o
riscv32-none-elf-gcc -march=rv32imac -mabi=ilp32 -Wall -O2 -nostdlib -nostartfiles -ffreestanding  -c notmain.c -o notmain.o
riscv32-none-elf-ld novectors.o notmain.o -T memmap -o notmain.elf
riscv32-none-elf-objdump -D notmain.elf > notmain.list
riscv32-none-elf-objcopy notmain.elf -O ihex notmain.hex
riscv32-none-elf-objcopy notmain.elf -O binary notmain.bin 

Теперь теоретически вы можете использовать riscv64-unknown-elf, о котором они говорят, даже если они хотят собрать для rv32, а не rv64 ... Я тоже могу попробовать ...

notmain.list

Disassembly of section .text:

20010000 <_start>:
20010000:   80004137            lui x2,0x80004
20010004:   010000ef            jal x1,20010014 <notmain>
20010008:   a001                    j   20010008 <_start+0x8>

2001000a <dummy>:
2001000a:   8082                    ret

2001000c <PUT32>:
2001000c:   c10c                    sw  x11,0(x10)
2001000e:   8082                    ret

20010010 <GET32>:
20010010:   4108                    lw  x10,0(x10)
20010012:   8082                    ret

20010014 <notmain>:
20010014:   1141                    addi    x2,x2,-16
20010016:   c04a                    sw  x18,0(x2)
20010018:   10012937            lui x18,0x10012
2001001c:   00890513            addi    x10,x18,8 # 10012008 <_start-0xfffdff8>
20010020:   006805b7            lui x11,0x680
20010024:   c606                    sw  x1,12(x2)
20010026:   c226                    sw  x9,4(x2)
20010028:   c422                    sw  x8,8(x2)
2001002a:   37cd                    jal 2001000c <PUT32>
2001002c:   00c90513            addi    x10,x18,12
20010030:   006805b7            lui x11,0x680
20010034:   3fe1                    jal 2001000c <PUT32>
20010036:   04090513            addi    x10,x18,64
2001003a:   4581                    li  x11,0
2001003c:   001e84b7            lui x9,0x1e8
20010040:   37f1                    jal 2001000c <PUT32>
20010042:   0931                    addi    x18,x18,12
20010044:   48048493            addi    x9,x9,1152 # 1e8480 <_start-0x1fe27b80>
20010048:   006805b7            lui x11,0x680
2001004c:   854a                    mv  x10,x18
2001004e:   3f7d                    jal 2001000c <PUT32>
20010050:   4401                    li  x8,0
20010052:   8522                    mv  x10,x8
20010054:   0405                    addi    x8,x8,1
20010056:   3f55                    jal 2001000a <dummy>
20010058:   fe941de3            bne x8,x9,20010052 <notmain+0x3e>
2001005c:   4581                    li  x11,0
2001005e:   854a                    mv  x10,x18
20010060:   3775                    jal 2001000c <PUT32>
20010062:   4401                    li  x8,0
20010064:   8522                    mv  x10,x8
20010066:   0405                    addi    x8,x8,1
20010068:   374d                    jal 2001000a <dummy>
2001006a:   fe941de3            bne x8,x9,20010064 <notmain+0x50>
2001006e:   bfe9                    j   20010048 <notmain+0x34>

Важно проверить, прежде чем пытаться загрузить программу на устройство, наш желаемый код ввода, первые инструкции novectors.s должны быть в 0x20010000 для этой платы / чипа в комплекте (заводской загрузчик). И это.

notmain.hex

:020000042001D9
:1000000037410080EF00000101A082800CC1828096
:100010000841828041114AC0372901101305890027
:10002000B705680006C626C222C4CD371305C9002D
:10003000B7056800E13F130509048145B7841E0038
:10004000F137310993840448B70568004A857D3F3C
:10005000014422850504553FE31D94FE81454A85F0
:1000600075370144228505044D37E31D94FEE9BF31
:0400000520010000D6
:00000001FF

скопируйте notmain.hex на подключенный носитель HiFive. Теперь это заняло у меня час или два, пытаясь выяснить, что такое шестнадцатеричный файл, когда я начал, здесь это не сработало. скачал их sdk, выкопанный, который нашел elf2hex, но это был плохой касательный, который был для работы с fpga. Разобрался, и все, что они делают, это riscv ... objcopy -O ihex, как и я, попробовал еще раз. И теперь это работает. Я получаю fail.txt, говоря, что он не мог подключиться к процессору раньше. Не знаю, что я делал или не делал, чтобы сделать эту работу.

Теоретически вы можете вырезать и вставить вышеупомянутый шестнадцатеричный файл, сохранить его и скопировать. Почему ни у кого нет примера шестнадцатеричного файла, вам нужно правильно установить 75 специальных вещей и запустить сборку, а не предоставлять здесь полный пример с промежуточными файлами. Я, конечно, сделаю это в моих примерах для этой платформы. Или, по крайней мере, тот, что приведен выше.

Вместо их мигающего радужного светодиода, приведенный выше заставит его мигать «белым» с регулярной частотой.

Примечание: светодиоды горят одинаковоЛинии GPIO на оборотной плате, загрузчик приземляется по другому адресу 0x20400000, чем rev b 0x20010000. Таким образом, то же самое можно построить для доски объявлений с этим одним изменением карты памяти.

Если вы или читатель хотите вернуться к версии a, если она есть, это модифицированный openocd, который на момент написания этой статьи находился в проекте github riscv user riscv-openocd. обычный ./bootstrap, ./configure, make для получения инструментов и в директории tcl есть файл конфигурации riscv openocd, показанный выше

interface ftdi
ftdi_device_desc "Dual RS232-HS"
ftdi_vid_pid 0x0403 0x6010

был ключом, доска rev2 lsusb:

Bus 001 Device 018: ID 1366:1051 SEGGER 

и нет совпадений с этими значениями pid / vid в конфигурационных файлах openocd. Приводим к прочтению большей части руководства по началу работы.


Первый ответ / перед редактированием выше

У меня есть оригинальная доска hifive1, как вы получили rev b?

В любом случае ...

Для исходной платы руководство по началу работы говорит следующее:

Плата HiFive1 поставляется с модифицируемым загрузчиком при запуске SPI Flash (0x20000000). В конце выполнения этой программы ядро ​​переходит к основной пользовательской части кода в 0x20400000.

Для платы rev b это говорит:

Плата HiFive1 Rev B поставляется смодифицируемый загрузчик при запуске SPI Flash (0x20000000). В конце выполнения этой программы ядро ​​переходит к основной пользовательской части кода в 0x20010000.

Обе микросхемы показывают 0x80000000 для оперативной памяти и 0x20000000 для (внешней) вспышки. Предположим, что это интерфейс, на котором они поместили флешку на плату rev B.

Первая программа.

novectors.s

.globl _start
_start:
    lui x2,0x80004
    jal notmain
    sbreak
    j .

.globl dummy
dummy:
    ret

notmain.c

void  dummy ( unsigned int );
int notmain ( void )
{
    unsigned int ra;

    for(ra=0;;ra++) dummy(ra);
    return(0);
}

memmap

MEMORY
{
    ram : ORIGIN = 0x80000000, LENGTH = 0x4000
}
SECTIONS
{
    .text : { *(.text*) } > ram
    .rodata : { *(.rodata*) } > ram
    .bss : { *(.bss*) } > ram
}

build

riscv32-none-elf-as -march=rv32i -mabi=ilp32 novectors.s -o novectors.o
riscv32-none-elf-gcc -march=rv32i -mabi=ilp32 -Wall -O2 -nostdlib -nostartfiles -ffreestanding  -c notmain.c -o notmain.o
riscv32-none-elf-ld novectors.o notmain.o -T memmap -o notmain.elf
riscv32-none-elf-objdump -D notmain.elf > notmain.list
riscv32-none-elf-objcopy notmain.elf -O binary notmain.bin 

теоретически вы можете использовать riscv32-что угодно-что угодно (riscv32-unknown-elf и т. Д.). Поскольку этот код достаточно универсален. Также обратите внимание, что я использую минимальный rv32i, вы, вероятно, можете использовать rv32imac для всей энчилады.

Проверьте разборку:

Disassembly of section .text:

80000000 <_start>:
80000000:   80004137            lui x2,0x80004
80000004:   010000ef            jal x1,80000014 <notmain>
80000008:   00100073            ebreak
8000000c:   0000006f            j   8000000c <_start+0xc>

80000010 <dummy>:
80000010:   00008067            ret

80000014 <notmain>:
80000014:   ff010113            addi    x2,x2,-16 # 80003ff0 <notmain+0x3fdc>
80000018:   00812423            sw  x8,8(x2)
8000001c:   00112623            sw  x1,12(x2)
80000020:   00000413            li  x8,0
80000024:   00040513            mv  x10,x8
80000028:   fe9ff0ef            jal x1,80000010 <dummy>
8000002c:   00140413            addi    x8,x8,1
80000030:   ff5ff06f            j   80000024 <notmain+0x10>

в случае rv32i это все 32-битные инструкции, и это нормально. Эта программа предназначена для загрузки в оперативную память и запуска там с отладчиком, я использую openocd и telnet в.

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger

Затем

halt
load_image notmain.elf
resume 0x80000000

в окне telnet

Затем вы можете снова остановиться.

80000024:   00040513            mv  x10,x8
80000028:   fe9ff0ef            jal x1,80000010 <dummy>
8000002c:   00140413            addi    x8,x8,1
80000030:   ff5ff06f            j   80000024 <notmain+0x10>

вы можете проверить либо x8, либо x10, чтобы увидеть, что он насчитал

resume
halt

, и снова изучить регистры, которые они должны были увеличить. Первая программа работает, продолжает работать.

Вторая программа использует этот скрипт компоновщика вместо

memmap

MEMORY
{
    rom : ORIGIN = 0x20010000, LENGTH = 0x4000
    ram : ORIGIN = 0x80000000, LENGTH = 0x4000
}

SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}

проверка разборки.

Disassembly of section .text:

20010000 <_start>:
20010000:   80004137            lui x2,0x80004
20010004:   010000ef            jal x1,20010014 <notmain>
20010008:   00100073            ebreak
2001000c:   0000006f            j   2001000c <_start+0xc>

20010010 <dummy>:
20010010:   00008067            ret

20010014 <notmain>:
20010014:   ff010113            addi    x2,x2,-16 # 80003ff0 <notmain+0x5fff3fdc>
20010018:   00812423            sw  x8,8(x2)
2001001c:   00112623            sw  x1,12(x2)
20010020:   00000413            li  x8,0
20010024:   00040513            mv  x10,x8
20010028:   fe9ff0ef            jal x1,20010010 <dummy>
2001002c:   00140413            addi    x8,x8,1
20010030:   ff5ff06f            j   20010024 <notmain+0x10>

Появляетсябыть независимым от позиции, поэтому он должен был просто работать, как это было с другим скриптом компоновщика, но лучше использовать правильные адреса.

Мои заметки говорят:

flash protect 0 64 last off
program notmain.elf verify
resume 0x20010000

И теперь вы должны быть в состояниидля сброса или выключения питания платы, подключитесь к openocd таким способом, который не сбрасывает (или делает, если хотите), и тогда вам не нужно загружать что-либо, что он должен был запустить их загрузчик, который затем запустил ваш загрузчик по этому адресу (прыгнул к нему)как они упоминают). Изучите r8 или r10 (r10 для этого abi - первый переданный параметр, поэтому, даже если ваш gcc собирается с использованием чего-то отличного от r8, r10 все равно должен отражать счетчик) resume, halt, reg, resume, halt, reg ...

Прежде чем перезаписать их загрузчик на 0x20000000, я бы его сбросил и убедился, что у вас есть хорошая копия, и, возможно, у них есть копия на их веб-сайте. Затем вы можете изменить скрипт компоновщика на 0x20000000. Прежде чем делать это лично, я бы разбирал и проверял их загрузчик и выяснял, что, если что-то делает, стоит ли его хранить и т. Д. В их тексте написано «модифицируемый»

Я порезал себе риск-v зубыплата hifive1, но теперь она перешла на ядра с открытым исходным кодом, платы hifive довольно дорогие. Я также сделал минимальную печатную плату и отложил некоторые пять частей, собирался только закончить оперативную память и т. Д., Но моя доска была слишком минимальной, и я не стал возвращаться и пытаться снова, небольшая поддержка на их форумах для работы печатных плат и их документовоставил желать лучшего. Я предполагаю, что когда доски rev b станут доступны, я подберу одну. увидим. удачи.

Укажите, что существует множество ядер, которые вы можете симулировать с помощью verilator или другого, и видеть, как все происходит, и вы не можете ни кирпичить, ни выпустить дым, потому что это сим.

Обратите внимание на rv32ic

riscv32-none-elf-as -march=rv32ic -mabi=ilp32 novectors.s -o novectors.o
riscv32-none-elf-gcc -march=rv32ic -mabi=ilp32 -Wall -O2 -nostdlib -nostartfiles -ffreestanding  -c notmain.c -o notmain.o
riscv32-none-elf-ld novectors.o notmain.o -T memmap -o notmain.elf
riscv32-none-elf-objdump -D notmain.elf > notmain.list
riscv32-none-elf-objcopy notmain.elf -O binary notmain.bin 

, и вы можете увидеть, что он использует сжатые инструкции, где он может

20010000 <_start>:
20010000:   80004137            lui x2,0x80004
20010004:   00a000ef            jal x1,2001000e <notmain>
20010008:   9002                    ebreak
2001000a:   a001                    j   2001000a <_start+0xa>

2001000c <dummy>:
2001000c:   8082                    ret

2001000e <notmain>:
2001000e:   1141                    addi    x2,x2,-16
20010010:   c422                    sw  x8,8(x2)
20010012:   c606                    sw  x1,12(x2)
20010014:   4401                    li  x8,0
20010016:   8522                    mv  x10,x8
20010018:   3fd5                    jal 2001000c <dummy>
2001001a:   0405                    addi    x8,x8,1
2001001c:   bfed                    j   20010016 <notmain+0x8>

, также довольно легко написать свой собственный эмулятор. Зависит от того, как вы хотите организовать обучение этой платформе. Сколько стоит освоение набора инструкций в сравнении с набором инструментов против конкретного чипа и его периферийных устройств.

Вам определенно нужны документы risc-v от riscv.org, которые соответствуют версии, поддерживаемой ядром, множеству внутренних регистров ядра и тому подобному, а также набору инструкций. А также начало работы и документация на чип для рассматриваемого чипа. Если вы хотите сделать свое дело. Если вы хотите играть в одной из их песочниц и использовать сторонние библиотеки, то вам нужно изучить их и играть в их песочнице, а не заниматься своими делами. Похоже, вы хотите заниматься своими делами.

Примечание. Я использую текущую версию gcc / binutils из основных источников gnu, созданную вручную.

riscv32-none-elf-gcc --version
riscv32-none-elf-gcc (GCC) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

riscv32-none-elf-as --version
GNU assembler (GNU Binutils) 2.32
Copyright (C) 2019 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `riscv32-none-elf'.

Приведенный выше код прекрасно работал несколько лет назад против оригинального hifive1, и этот стиль работает для основных версий gnu, и я использовал этот набор инструментов против других ядер riscv, поэтому, даже если у вас он старше, он все равно должен работать. Наиболее важным является сопоставление арки (-march) с наборами команд, поддерживаемыми ядром, или, по крайней мере, подмножество rv32i должно поддерживаться всеми ядрами, сжатые и умноженные, и такие не всегда поддерживаются.

Мой файл конфигурации openocd для первой платы

adapter_khz     10000

interface ftdi
ftdi_device_desc "Dual RS232-HS"
ftdi_vid_pid 0x0403 0x6010

ftdi_layout_init 0x0008 0x001b
ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020

set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913

set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1

flash bank onboard_spi_flash fespi 0x20000000 0 0 0 $_TARGETNAME
init

openocd -f riscv.cfg в одном терминале / окне, а затем telnet localhost 4444 в другом.

Теперь, насколько нюанс ассемблера gnu васмы просим вас увидеть ассемблер gnu, или даже лучше использовать как можно меньше специфических ассемблерных / инструментальных цепочек, как это возможно, и / или вы можете менять инструменты когда-нибудь. YMMV

Инструменты GNU не знают эту доску из дыры в стене. вы рассказываете инструментам gnu об архитектуре ядра процессора и в скрипте компоновщика карту памяти. Ваш код, прямо или косвенно (если вы используете чей-либо сценарий начальной загрузки и скрипт компоновщика), должен соответствовать загрузочным свойствам ядра процессора, будь то RISC-V из Siveive или какое-либо ядро ​​ARM, MIPS или X86 и т. Д. Векторная таблица или нет,выполнить по какому-либо адресу и т. д. В приведенном выше случае их загрузчик переходит на 0x20010000, поэтому вам нужно поместить первую инструкцию в 0x20010000, что выполняется, если эта инструкция будет первой в источнике начальной загрузки, и если она не указана в сценарии компоновщикасначала поместив этот объект в командную строку ld, и проанализировав разборку, чтобы убедиться, что она работает, прежде чем пытаться запустить ее на оборудовании. Ядра riscv, которые я использовал, не имеют векторной таблицы, для сброса они просто запускают выполнение с какого-то адреса. Таким образом, вы бы использовали тот же подход, если у вас не было перехода к предварительному загрузчику. Для других архитектур, не относящихся к risc-v, построение программы для платы / платформы будет отличаться, если это переход к объекту адреса по сравнению с элементом таблицы вектора.

Теперь говорят, что если вы используете их песочницу, тоэто вопрос о песочнице, а не вопрос о наборе инструментов gnu.

Документация и / или веб-сайт платы указывают на то, что плата rev b использует микросхему FE310-G002 в документации FE310-G002, которую вы найдетекарта памяти. Это также указывает на то, что это архитектура risc-v, и из этого вы переходите к основанию riscv.org и получаете документацию для этой архитектуры, в которой рассказывается, как она загружается. И обратно в FE310-G002 он сообщает вам процесс загрузки с выводов MSEL. Который вам нужно будет изучить схемы. Таким образом, реальность такова, что их документация говорит вам, как указать, что это программа загрузчика, предоставляя информацию, которую вы должны предоставить gnu.

Говоря, что ... некоторые эксперименты желательны / необходимы. Можно / легко написать простой бесконечный цикл позиции, построить для 0x00000000, но загрузить в 0x20010000 на основе их документации и использовать openocd, чтобы проверить счетчик программы, чтобы увидеть, действительно ли он основан на 0x20010000. Исходя из этого, вы можете предположить, что в конечном итоге при поставке плата проходит через свой загрузчик к вам через любой выбранный MSEL.

Хммм:

При включении питания вектор сброса ядра0x1004.

И далее указываются разные адреса первых команд для каждого из вариантов ремешка MSEL. Поэтому, если вы возьмете на себя их загрузчик и замените его своим собственным, основываясь на документации, вы бы связали 0x20000000 и имели бы точку входа там.

...