Здравствуйте! У меня возникла проблема с размещением данных строго после кода в готовом бинарном файле без формата. Вот что я сделал: 1. Компилировал файл с помощью команды: ```bash x86_64-elf-gcc -m32 -ffreestanding -c kernel.c -o kernel.o ``` 2. Линковал объектный файл с помощью команды: ```bash ld.lld -T linker.ld -o kernel --oformat binary kernel.o ``` Теперь, в самом коде на C, я объявляю массивы вне функций следующим образом: ```cpp __attribute__((section(".data_kdata"))) char SCANCODES_QEMU[58] = { '?', '?', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '?', '?', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', '?', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', '?', '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', '?', '?', '?', ' ' }; ``` Я использую атрибут для любых глобальных данных в секции. Однако, несмотря на это, данные в бинарном файле располагаются не так, как я ожидал: сначала идут строки и массивы, затем код, и снова массивы. Как мне правильно расположить данные в бинарном файле?
Для того чтобы данные располагались в бинарном файле строго после кода, вам необходимо правильно настроить файл скрипта компоновщика `linker.ld`. Ваша проблема, скорее всего, заключается в том, что текущая конфигурация скрипта компоновщика не соответствует вашим ожиданиям по расположению секций. Вот шаги, которые вам нужно выполнить, чтобы убедиться, что глобальные массивы располагаются непосредственно после кода: ### 1. Настройка скрипта компоновщика Ваш скрипт компоновщика `linker.ld` должен точно указывать порядок размещения секций. Вот упрощенный пример того, как может выглядеть файл `linker.ld`: ```ld OUTPUT_FORMAT("binary") SECTIONS { . = 0x1000; /* Начальный адрес загрузки, вы можете изменить его на нужный вам */ .text : { *(.text) /* Все секции .text (код) */ } .data_kdata : { *(.data_kdata) /* Все секции .data_kdata (данные) */ } .bss : { *(.bss) /* Все секции .bss (неинициализированные данные) */ } } ``` ### 2. Использование атрибутов секций в коде Вы уже правильно добавили атрибут секции `__attribute__((section(".data_kdata")))` к вашему массиву. Убедитесь, что вы используете правильные секции для всех глобальных данных, включая неинициализированные данные. ### 3. Компиляция и линковка После того, как вы обновите файл компоновщика, выполните те же шаги компиляции и линковки: ```bash x86_64-elf-gcc -m32 -ffreestanding -c kernel.c -o kernel.o ld.lld -T linker.ld -o kernel --oformat binary kernel.o ``` ### 4. Проверка результата Теперь после компиляции и линковки проверьте бинарный файл, чтобы убедиться, что данные располагаются прямо после кода. Вы можете использовать инструменты, такие как `xxd` или `hexdump`, чтобы просмотреть содержимое бинарного файла: ```bash xxd kernel ``` Если вы всё сделали правильно, ваши глобальные данные должны находиться сразу после секции кода `.text`, и вы больше не увидите разрыва секций, которые могут привести к смешиванию данных. Если у вас по-прежнему возникают проблемы, убедитесь, что не осталось лишних секций и что вы не используете дополнительные атрибуты, которые могут влиять на размещение ваших данных и кода.
Нужно явно указать секцию .rodata после секции .text
и attribute section после этого не понадобится:
SECTIONS
{
. = 0x100200;
.text :
{
*(.text)
}
.rodata : <- тут явно указываем секцию
{
*(.rodata)
}
.data :
{
*(.data)
}
.bss :
{
*(.bss)
}
. = ALIGN(4);
}