Приветствую.
У меня имеется следующий скрипт линкера:
ENTRY (_start)
SECTIONS
{
. = 0x00100000;
/* The kernel will live at 3GB + 1MB in the virtual address space, */
/* which will be mapped to 1MB in the physical address space. */
/* Note that we page-align the sections. */
_kernel_start = .;
.multiboot.data : {
*(.multiboot.data)
}
.multiboot.text : {
*(.multiboot.text)
}
. += 0xC0000000;
/* Add a symbol that indicates the start address of the kernel. */
.text ALIGN (4K) : AT (ADDR (.text) - 0xC0000000)
{
*(.text)
}
.rodata ALIGN (4K) : AT (ADDR (.rodata) - 0xC0000000)
{
*(.rodata)
}
.data ALIGN (4K) : AT (ADDR (.data) - 0xC0000000)
{
*(.data)
}
.bss ALIGN (4K) : AT (ADDR (.bss) - 0xC0000000)
{
*(COMMON)
*(.bss)
*(.bootstrap_stack)
}
/* Add a symbol that indicates the end address of the kernel. */
_kernel_end = .;
}
В коде объявляются несколько символов
.section .bss, "aw", @nobits
.align 4096
boot_page_directory:
.skip 4096
boot_page_table1:
.skip 4096
И затем, для доступа к данным, что скрываются за ними, необходимо вручную вычитать 0xC0000000
.section .multiboot.text, "a"
.global _start
.type _start, @function
_start:
# Physical address of boot_page_table1.
movl $(boot_page_table1 - 0xC0000000), %edi
Почему так происходит? Ведь используя директиву AT() я указываю фактический адрес в который загрузится секция bss, а значит и данные которые в ней хранятся, следовательно символ boot_page_table1 должен указывать на фактический адрес данных и не требовать вычитания.
Получается, таблица символов формируется лишь исходя из счётчика позиции(который «.»)? Или что-то ещё влияет? Если я объявлю символ, который будет указывать на данные в .multiboot.data,
.section .multiboot.data, "aw"
some_data:
.skip 1024
то должен ли я при обращении к нему производить вычитание 0xC0000000?
Я использую для линковки gcc