#assembly #x86 #ld #linker-scripts #objcopy
#сборка #x86 #ld #компоновщик-скрипты #objcopy
Вопрос:
Итак, у меня есть этот файл сборки, который я собираю с помощью GNU as и связываю с GNU ld с помощью скрипта компоновщика.
Скрипт компоновщика ( boot.ld
):
INPUT(boot.o)
OUTPUT(boot.out)
ENTRY(boot_start)
SECTIONS {
. = 0x7c00;
.text : { *(.text) }
.data : { *(.data) }
. = 0x7dfe;
.boot_end : { *(.boot_end) }
}
Как вы видите, я пытаюсь сделать файл ровно 512 байт, как это необходимо для загрузчика, выполнив . = 0x7cdfe
. .boot_end
содержит подпись загрузки и, таким образом, заполняет оставшиеся два байта.
Я создаю загрузчик следующим образом:
m4 boot.S | as -o boot.o
ld -T boot.ld
objcopy -O binary boot.out boot.img
boot.out
содержит разделы, уже имеющие абсолютные адреса, и все кажется нормальным. .boot_end
находится в 0x7dfe
, и я ожидаю, что отверстия будут заполнены нулями, но нет, boot.img
всего 55 байт. Для меня странно то, что файл даже не содержит подписи загрузки. Это просто .text
и .data
без каких-либо .boot_end
или пропущенных байтов.
Как мне переместить ld, чтобы пропустить эти байты? И куда пропала моя подпись загрузки?
Комментарии:
1. Какие имена разделов вы использовали для недостающих частей и какие флаги вы установили (что вы вводите
as
)? Также может иметь значение, используете ли вы ELF или COFF или любой другой формат объекта.2. @tofro
.boot_end
— это раздел, который мне не хватает, и я собралas
его так же, как написано в моем вопросе. Я использую ELF.3. И вы все еще не сказали, какие
.section
флаги вы указываете вas
коде. Дело в том, что еслиas
в ELF не заданы флаги раздела для нестандартного (не.text
или.data
или подобного) имени раздела, раздел не будет выделен. Попробуйте заменить вашу (предположительно) голую.section boot_end
директиву воas
входных данных на.section boot_end,"a"
(или больше флагов, например, чтобы сделать ее исполняемой, в зависимости от того, что вам нужно) и повторите попытку.4. @tofro О, хорошо, я попробую.
5. @tofro Большое спасибо, это сработало. Я попробовал
.section .boot_end "", @progbits
сначала, но результат был тот же. Я попробовал еще раз.section .boot_end "a", @progbits
, просто ради этого, и это сработало. Дело в том, чтоa
указывает на выделяемые разделы, а.boot_end
это не так. Есть мысли о том, какой флаг я мог бы использовать? И почему GNU as не будет генерировать данные для пользовательских разделов без флагов?
Ответ №1:
Скорее всего, у вас отсутствует флаг раздела. Дело в том, что если as
при последующей ссылке на ELF для нестандартного (не .text
или .data
или подобного) имени раздела не заданы флаги раздела, раздел не будет выделен в дампе (т.Е. Будет молча игнорироваться objcopy
, обратите внимание, что это ведет себя по-разному при создании coff
файлов)
Попробуйте заменить ваш (предположительно) голый
.section boot_end
директива во входном файле ассемблера с
.section boot_end,"a"
(или больше флагов, например, чтобы сделать его исполняемым, в зависимости от того, что вам нужно) и повторите попытку.
Флаг «a» делает раздел выделяемым, т. Е. Сообщает обоим ld
, и objcopy
вы хотите, чтобы он был в вашем двоичном файле.