Reputation: 1406
Suppose I'm writing my own mbr
section and I want to run some C code where. To do so I need firstly initialize stack and after that call C code. I did that in a way like this
boot.S
file:
.code16
.section .bootstrap_stack #initializing stack here
stack_bottom:
.skip 16384
stack_top:
.text
.global _start
_start:
cli
movl $stack_top, %esp
call kmain
loop:
jmp loop
In my C code I have function kmain
.
My linker.ld
file looks like this:
OUTPUT_FORMAT(binary)
OUTPUT_ARCH(i8086)
ENTRY(_start)
SECTIONS
{
. = 0x7C00;
.text : { *(.text) }
.sig : AT(0x7DFE)
{
SHORT(0xaa55);
}
}
So the question is where in memory section .bootstrap_stack
placed? I dont tell linker script anything about it. But if I do then the size of output file is more than 512 bytes and I can't use it as mbr
. Why after this C stack works correctly?
Upvotes: 1
Views: 324
Reputation: 39591
If you use the -M
option of ld so that it produces a map file, you'll see that it assigns the address 0 to .bootstrap_stack
:
Name Origin Length Attributes
*default* 0x0000000000000000 0xffffffffffffffff
Linker script and memory map
0x0000000000007c00 . = 0x7c00
.text 0x0000000000007c00 0x9
*(.text)
.text 0x0000000000007c00 0x9 t95.o
0x0000000000007c00 _start
.sig 0x0000000000007c09 0x2 load address 0x0000000000007dfe
0x0000000000007c09 0x2 SHORT 0xaa55
LOAD t95.o
OUTPUT(a.out binary)
.data 0x0000000000007c0b 0x0 load address 0x0000000000007e00
.data 0x0000000000007c0b 0x0 t95.o
.bss 0x0000000000007c0b 0x0 load address 0x0000000000007e00
.bss 0x0000000000007c0b 0x0 t95.o
.bootstrap_stack
0x0000000000000000 0x4000
.bootstrap_stack
0x0000000000000000 0x4000 t95.o
You can verify this by disassembling generated binary:
$ objdump -b binary -m i8086 --adjust-vma=0x7c00 -D a.out
...
7c00: fa cli
7c01: 66 bc 00 40 00 00 mov $0x4000,%esp
7c07: eb fe jmp 0x7c07
...
7dfd: 00 55 aa add %dl,-0x56(%di)
Instead of using a section that won't actually appear in your generated output, I'd recommend loading SP (not ESP) with a fixed constant that you know is safe. You also need to load SS at the same time, as the actual address of the stack is SS:SP, that is, it's located at SS * 16 + SP
. For example:
_start:
xor %ax, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %ss
mov $0x7c00, %sp # stack grows downwards from start of boot loader
Upvotes: 2