Что значит загружаемый в микроконтроллерах в смысле линикеров

Я пытаюсь ознакомиться с процедурами подключения и запуска в микроконтроллерах ARM Cortex-M4. При просмотре скриптов компоновщика почти все разделы отмечены как загружаемые.

Сначала я подумал, что это означает, что он будет скопирован с флэш-памяти в ОЗУ, но потом я узнал, что это делается по-другому. Итак, что значит загружаемый раздел во флеш-памяти? Разве он уже не загружен и не запускается с места во флеш-памяти? Также я имею в виду раздел, содержащий инструкции.

Означает ли загружаемый в этом контексте загрузку отладчиком в устройство?

незагружаемые разделы — это те, которые, например, содержат символы для отладки   —  person Community    schedule 07.10.2017

все, что используется самой программой, является загружаемым, .text, .rodata, .data, .bss и т. д.   —  person Community    schedule 07.10.2017

какой формат файла, я так понимаю, вы имеете в виду эльфийку? (что не относится к микроконтроллерам, кстати, также используется с операционными системами)   —  person Community    schedule 07.10.2017

Да, эльф. Я не понимаю, когда вы отмечаете раздел как загружаемый, что это значит? Откуда он загружается и куда загружается?   —  person Community    schedule 07.10.2017

для микроконтроллера, который зависит от программного обеспечения, которое вы используете, чтобы идеально загрузить программу во флэш-память. Некоторому программному обеспечению нравятся только необработанные двоичные изображения (arm-any-objcopy myprog.elf -O binary myprog.bin), некоторые могут читать elf, ihex, srec, coff или другие форматы файлов и извлекать соответствующие элементы из этих форматов и загружать их байтов во флеш-память.   —  person Community    schedule 07.10.2017

См. также:  Переместить код исходного файла группы в определенный раздел сценария компоновщика
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 1
  1. Community

    полнофункциональная программа cortex-m

    flash.s

    .thumb
    
    .thumb_func
    .global _start
    _start:
    stacktop: .word 0x20001000
    .word reset
    .word hang
    .word hang
    
    .thumb_func
    reset:
        bl notmain
        b hang
    
    .thumb_func
    hang:   b .
    .align
    
    .thumb_func
    .globl dummy
    dummy:
        bx lr
    

    so.c

    void dummy ( unsigned int );
    int notmain ( void )
    {
        unsigned int ra;
    
        for(ra=0;ra<10;ra++) dummy(ra);
        return(0);
    }
    

    flash.ld ПАМЯТЬ {rom: ORIGIN = 0x00000000, LENGTH = 0x1000 ram: ORIGIN = 0x20000000, LENGTH = 0x1000}

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

    строить

    arm-none-eabi-as --warn --fatal-warnings -mcpu=cortex-m0 flash.s -o flash.o
    arm-none-eabi-gcc -Wall  -O2 -nostdlib -nostartfiles -ffreestanding -mthumb -c so.c -o so.o
    arm-none-eabi-ld -o so.elf -T flash.ld flash.o so.o
    arm-none-eabi-objdump -D so.elf > so.list
    arm-none-eabi-objcopy so.elf so.bin -O binary
    

    (можно использовать cortex-m4 либо работает)

    so.list

    00000000 <_start>:
       0:   20001000    andcs   r1, r0, r0
       4:   00000011    andeq   r0, r0, r1, lsl r0
       8:   00000017    andeq   r0, r0, r7, lsl r0
       c:   00000017    andeq   r0, r0, r7, lsl r0
    
    00000010 <reset>:
      10:   f000 f804   bl  1c <notmain>
      14:   e7ff        b.n 16 <hang>
    
    00000016 <hang>:
      16:   e7fe        b.n 16 <hang>
    
    00000018 <dummy>:
      18:   4770        bx  lr
      1a:   46c0        nop         ; (mov r8, r8)
    
    0000001c <notmain>:
      1c:   b510        push    {r4, lr}
      1e:   2400        movs    r4, #0
      20:   0020        movs    r0, r4
      22:   3401        adds    r4, #1
      24:   f7ff fff8   bl  18 <dummy>
      28:   2c0a        cmp r4, #10
      2a:   d1f9        bne.n   20 <notmain+0x4>
      2c:   2000        movs    r0, #0
      2e:   bc10        pop {r4}
      30:   bc02        pop {r1}
      32:   4708        bx  r1
    

    будучи менее сложным скриптом компоновщика, и программа эльфа имеет меньше вещей

    часть readelf

    Section Headers:
      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 0]                   NULL            00000000 000000 000000 00      0   0  0
      [ 1] .text             PROGBITS        00000000 010000 000034 00  AX  0   0  4
      [ 2] .ARM.attributes   ARM_ATTRIBUTES  00000000 010034 00002d 00      0   0  1
      [ 3] .comment          PROGBITS        00000000 010061 000011 01  MS  0   0  1
      [ 4] .symtab           SYMTAB          00000000 010074 0000f0 10      5  12  4
      [ 5] .strtab           STRTAB          00000000 010164 00003d 00      0   0  1
      [ 6] .shstrtab         STRTAB          00000000 0101a1 00003a 00      0   0  1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
      L (link order), O (extra OS processing required), G (group), T (TLS),
      C (compressed), x (unknown), o (OS specific), E (exclude),
      y (purecode), p (processor specific)
    
    There are no section groups in this file.
    
    Program Headers:
      Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
      LOAD           0x010000 0x00000000 0x00000000 0x00034 0x00034 R E 0x10000
    

    hexdump -C so.bin

    00000000  00 10 00 20 11 00 00 00  17 00 00 00 17 00 00 00  |... ............|
    00000010  00 f0 04 f8 ff e7 fe e7  70 47 c0 46 10 b5 00 24  |........pG.F...$|
    00000020  20 00 01 34 ff f7 f8 ff  0a 2c f9 d1 00 20 10 bc  | ..4.....,... ..|
    00000030  02 bc 08 47                                       |...G|
    00000034
    

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

    Шестнадцатеричный дамп, поступающий из objcopy, также показывает части, которые мы должны видеть процессору для запуска программы или загружать их в адресное пространство / память (в данном случае флэш-память находится в памяти или адресном пространстве).

    Но «двоичный» файл elf также содержит символы отладки на тот случай, если вы хотите запустить отладчик, добавить еще несколько параметров в командную строку цепочки инструментов, и вы получите еще больше информации о том, где эти элементы находятся в файле исходного кода, чтобы вы в некоторых случаях мог видеть язык высокого уровня при пошаговом прохождении кода. Это не загружаемые разделы, они описывают программу или служат только для помощи, они не являются машинным кодом или данными, которые нужны процессору для выполнения программы, поэтому их не нужно загружать в область памяти.

    еще один «двоичный» формат файла

    arm-none-eabi-objcopy so.elf -O ihex so.hex
    cat so.hex 
    :100000000010002011000000170000001700000081
    :1000100000F004F8FFE7FEE77047C04610B5002483
    :1000200020000134FFF7F8FF0A2CF9D1002010BCA2
    :0400300002BC0847BF
    :00000001FF
    

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

    другой формат двоичного файла

    S00A0000736F2E7372656338
    S1130000001000201100000017000000170000007D
    S113001000F004F8FFE7FEE77047C04610B500247F
    S113002020000134FFF7F8FF0A2CF9D1002010BC9E
    S107003002BC0847BB
    S9030000FC
    

    также большая часть этого программного обеспечения.

    elf — это просто еще один формат файла (довольно популярный среди инструментов GNU, но все еще просто другой формат файла), он содержит машинный код и необходимые данные, а также множество других вещей, машинный код и данные — это то, что мы должны загрузить в RAM, если это операционная система, или то, что мы в идеале загружаем во флеш-память для микроконтроллера, но не все микроконтроллеры одинаковы, некоторые из них основаны только на оперативной памяти, и программа загружается через usb во время перечисления (в оперативную память). и другие решения, или при отладке у вас, вероятно, могут быть элементы, загруженные в оперативную память, в зависимости от mcu и инструментов, хотя это не то, как загружается вещь, поэтому это не будет действительно хорошим двоичным файлом.

    если вы чувствуете необходимость обнулить .bss и иметь какие-либо .data, тогда вам нужна дополнительная информация, смещение и размер .bss, а также смещение и содержимое .data, затем начальная загрузка обнуляет и копирует эти элементы, и вам это нужно информация в энергонезависимой флэш-памяти / ПЗУ, это просто дополнительные данные, которые требуются от машинного кода и данных, необходимых для запуска программы. Если вы позволяете другим писать код за вас, то, возможно, существуют адаптированные сценарии компоновщика и код начальной загрузки, который позволяет вам просто иметь элементы .data и нажимать кнопку сборки на графическом интерфейсе, и все это волшебным образом оказывается на месте, когда ваша точка входа (основная () по соглашению и / или стандартно) запускает выполнение кода, представляющего ваш высокоуровневый код, в точке входа C.

    Если вы используете инструменты GNU, у вас есть все необходимое для изучения происходящего, вы можете разобрать объекты и посмотреть, как они влияют на окончательную программу. формат файла elf довольно прост для синтаксического анализа, вы можете написать свою собственную программу для анализа, если хотите, 30-минутный проект. можно увидеть старые и все еще используемые форматы записи Intel hex или Motorola, просто посмотрите их в Википедии, чтобы узнать, что там происходит, очевидно, что преимущество перед файлом необработанного образа памяти заключается в том, что у вас есть разные разделы данных, которые не являются линейными Вам не нужно использовать подушечку, вы можете перейти к person Community; 07.10.2017

    в пространстве, так как в каждой строке данных есть начальный адрес. person Community; 07.10.2017

    вы можете видеть в дампе readelf, что фактическая программа помечена AX, и это то, что должно быть в устройстве, я мог бы добавить .bss или другой и сделать программу больше, и это может создать новые разделы, которые также должны быть ( загружен) в устройство. person Community; 07.10.2017

    также таблица символов показана в дампе readelf, имена меток и тому подобное, если вы хотите, скажем, … дизассемблировать программу (objdump -D) и получить несколько меток вместо необработанных адресов … (явно не должен быть в устройстве для работы, не загружается). person Community; 07.10.2017

    Как побочный вопрос: почему ячейки памяти за стеком (по-видимому, несут адреса для меток start и hang) смещены на 1? ELF говорит, что эти метки на 10 и 16 соответственно, не так ли? person Community; 10.10.2017

    он привязан к инструкции bx / blx и расширен за ее пределы. Инструкции Arm 32-битные, 32-битные выровненные, инструкции большого пальца — одно или два 16-битных полуслова, выровненные полуслова. поэтому lsbit всегда равен нулю. они использовали lsbit для обозначения режима большого пальца при использовании таких инструкций, как bx. Lsbit потребляется и помещается в cpsr (бит большого пальца), а также используется, чтобы оставаться в или переключать режимы. Тогда по какой-то причине эта таблица векторов работает точно так же, даже если это явно только большой палец cortex-m. Так что исторически это имеет смысл, но почему именно это вопрос к ARM. person Community; 10.10.2017

    в качестве метки функции они или помечены единицей, поскольку фактический адрес, по которому инструкции извлекаются из lsbit, равен нулю. person Community; 10.10.2017

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: