2016-08-02 20 views
0

При работе с небольшим 32-битным ядром для архитектуры x86 я обнаружил что-то странное, так как ld обрабатывает разделы nobits.ld игнорирует размер входного раздела nobits

В моем ядре я определяю раздел .bootstrap_stack, который содержит временный стек для инициализирующей части системы. Я также храню символы для начала и конца стека. Эта секция ввода перенаправляется в выходной раздел .bss. Каждый выходной раздел моего ядра имеет символ для начала и конца раздела.

Проблема в том, что в конечном исполняемом файле символ конца стека равен после конец раздела .bss. В приведенных ниже примерах символы stack_top и _kernel_ebss_kernel_end) имеют то же значение, что и не то, что я хотел.

Я ожидал, что _kernel_ebss равным stack_bottom.

Однако, как только я переименую .bootstrap_stack в .bss, этого не произойдет. Удаление nobits также работает, но полученный двоичный файл значительно больше.

Вот зачищенные файлы, воспроизводящие мой вопрос:

boot.S

section .bootstrap_stack, nobits ; this does not work 
;section .bootstrap_stack  ; this works 
;section .bss     ; this also works 

stack_top: 
resb 8096 
stack_bottom: 

section .text 
global _start 
_start: 
    hlt 
    jmp _start 

linker.ld

ENTRY(_start) 

SECTIONS 
{ 
    . = 0xC0100000; 

    _kernel_start = .; 

    .text ALIGN(4K) : AT(ADDR(.text) - 0xC0000000) 
    { 
     _kernel_text = .; 
     *(.multiboot) 
     *(.text) 
     _kernel_etext = .; 
    } 

    .bss ALIGN(4K) : AT(ADDR(.bss) - 0xC0000000) 
    { 
     _kernel_bss = .; 
     *(COMMON) 
     *(.bss) 
     *(.bootstrap_stack) 
     _kernel_ebss = .; 
    } 
    _kernel_end = .; 
} 

Вот символы:

$ objdump -t kernel | sort 
00000000 l df *ABS*    00000000 boot.s 
c0100000 g  .text    00000000 _kernel_start 
c0100000 g  .text    00000000 _kernel_text 
c0100000 g  .text    00000000 _start 
c0100000 l d .text    00000000 .text 
c0100003 g  .text    00000000 _kernel_etext 
c0101000 g  .text    00000000 _kernel_bss 
c0101000 g  .text    00000000 _kernel_ebss 
c0101000 g  .text    00000000 _kernel_end 
c0101000 l  .bootstrap_stack, 00000000 stack_top 
c0101000 l d .bootstrap_stack, 00000000 .bootstrap_stack, 
c0102fa0 l  .bootstrap_stack, 00000000 stack_bottom 

Переименовав .bootstrap_stack до .bss Я получаю то, что ожидал.

00000000 l df *ABS* 00000000 boot.s 
c0100000 g  .text 00000000 _kernel_start 
c0100000 g  .text 00000000 _kernel_text 
c0100000 g  .text 00000000 _start 
c0100000 l d .text 00000000 .text 
c0100003 g  .text 00000000 _kernel_etext 
c0101000 g  .bss 00000000 _kernel_bss 
c0101000 l  .bss 00000000 stack_top 
c0101000 l d .bss 00000000 .bss 
c0102fa0 g  .bss 00000000 _kernel_ebss 
c0102fa0 g  .bss 00000000 _kernel_end 
c0102fa0 l  .bss 00000000 stack_bottom 

Вопрос в том, ожидается ли это поведение ld. Если да, то в чем проблема с моим примером, потому что, насколько я понимаю, .bss также является благородным разделом, но он дает ожидаемый результат?

ответ

0

Хорошо, я понял.

По-видимому, у вас не должно быть запятой справа после названия раздела. objdump содержит запятую в названии раздела, что ясно показывает, что это ошибка.

Так

section .bootstrap_stack, nobits 

должен быть

section .bootstrap_stack nobits