Здравствуйте! У меня возникла проблема с размещением данных строго после кода в готовом бинарном файле без формата.
Вот что я сделал:
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);
}