2012-06-13 5 views
0

Я пытаюсь использовать команду ld в linux для файла сборки для ядра. Для его загрузки с grub он должен быть после адреса 1Mb. Поэтому мой сценарий ссылок имеет текст, идущий по адресу 0x00100000.Непредвиденное расположение вывода компоновщика

Вот скрипт линкера Я использую:

SECTIONS { 
     .text 0x00100000 :{ 
      *(.text) 
     } 
     textEnd = .; 
     .data :{ 
      *(.data) 
      *(.rodata) 
     } 
     dataEnd = .; 
     .bss :{ 
      *(.common) 
      *(.bss) 
     } 
     bssEnd = .; 
    } 

Мой вопрос о выходном файле. Когда я смотрю на двоичный файл файла, текстовый раздел начинается с 0x1000. Когда я изменяю текстовое местоположение в скрипте и использую адреса ниже 0x1000, например 0x500, текст начнется там. Но всякий раз, когда я иду выше 0x1000, он округляет его (0x2500 будет помещать текст в 0x500).

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

ответ

0

Вы имеете в виду два разных адресных пространства. Адреса, на которые вы ссылаетесь в связанном файле (например, 0x1000 и 0x500), являются только смещениями файлов. Адреса, указанные в сценарии компоновщика, такие как 0x00100000, относятся к памяти компьютера (то есть ОЗУ).

В случае скрипта компоновщика компоновщику сообщается, что раздел .text двоичного/исполняемого файла должен быть загружен в 1MiB-точке в ОЗУ (то есть 0x00100000). Это меньше связано с компоновкой файла, выводимого компоновщиком, и больше зависит от того, как файл должен быть загружен при выполнении.

Разделы раздела в фактическом файле связаны с выравниванием. То есть, ваш компоновщик, похоже, выравнивает первый раздел с границей 4096 байт. Если, например, каждая секция имеет размер менее 4096 байт и каждая из них размещена на границе 4096 байт, их соответствующие смещения в файле будут 0x1000, 0x2000, 0x3000 и т. Д. По умолчанию это выравнивание также будет выполняться после того, как файл загружается в ОЗУ таким образом, что в предыдущем примере будут отображаться секции, расположенные на 0x00100000, 0x00101000, 0x00102000 и т. д.

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

В течение короткого & сладкого объяснения линкера (описывающий все выше более подробно) рекомендую:

http://www.math.utah.edu/docs/info/ld_3.html

или

http://sourceware.org/binutils/docs-2.15/ld/Scripts.html