链接 pe-i386 引导扇区
我制作了两个目标文件。一个是用 nasm -f win32 制作的:
C:\home\os> objdump -d boot.obj
boot.obj: file format pe-i386
Disassembly of section .text:
00000000 <.text>:
0: 02 d0 add %al,%dl
2: ba 01 03 00 00 mov $0x301,%edx
7: 00 fb add %bh,%bl
9: 2f das
a: 45 inc %ebp
b: fe 00 incb (%eax)
...
19: 00 00 add %al,(%eax)
1b: 00 20 add %ah,(%eax)
1d: 00 00 add %al,(%eax)
1f: 00 53 fa add %dl,-0x6(%ebx)
22: e8 00 00 00 00 call 27 <.text+0x27>
27: fa cli
28: f4 hlt
另一个是用 gcc -c main.c -nostdlib -nostdinc -fno-builtin -o main.o
C:\home\os>objdump -d main.o
main.o: file format pe-i386
Disassembly of section .text:
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 08 sub $0x8,%esp
6: 83 e4 f0 and $0xfffffff0,%esp
9: b8 00 00 00 00 mov $0x0,%eax
e: 83 c0 0f add $0xf,%eax
11: 83 c0 0f add $0xf,%eax
14: c1 e8 04 shr $0x4,%eax
17: c1 e0 04 shl $0x4,%eax
1a: 89 45 fc mov %eax,-0x4(%ebp)
1d: 8b 45 fc mov -0x4(%ebp),%eax
20: e8 00 00 00 00 call 25 <_main+0x25>
25: e8 00 00 00 00 call 2a <_main+0x2a>
2a: b8 ef be ad de mov $0xdeadbeef,%eax
2f: c9 leave
30: c3 ret
31: 90 nop
32: 90 nop
33: 90 nop
现在,我尝试使用 .. ld 链接这些 它使用这个模板:
OUTPUT_FORMAT("pe-i386")
ENTRY(start)
SECTIONS
{
.text 0x100000 :
{
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data :
{
data = .; _data = .; __data = .;
*(.data)
*(.rodata)
. = ALIGN(4096);
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .; _end = .; __end = .;
}
但它不起作用:
ld -Tlink.ld -o kernel boot.obj main.o
ld: warning: cannot find entry symbol start; defaulting to 00100000
boot.obj:boot.s:(.text+0x23): undefined reference to `main'
main.o:main.c:(.text+0x21): undefined reference to `_alloca'
main.o:main.c:(.text+0x26): undefined reference to `__main'
make: *** [link] Fout 1
我错过了什么?我不习惯使用 Windows,使用 ELF 文件我并没有真正遇到问题。我应该使用不同的链接器吗?我想它调用 alloca 因为我缺少 -fno-stack-protector,但我的 gcc 没有理解该标志。
I made two object files. One is made with nasm -f win32:
C:\home\os> objdump -d boot.obj
boot.obj: file format pe-i386
Disassembly of section .text:
00000000 <.text>:
0: 02 d0 add %al,%dl
2: ba 01 03 00 00 mov $0x301,%edx
7: 00 fb add %bh,%bl
9: 2f das
a: 45 inc %ebp
b: fe 00 incb (%eax)
...
19: 00 00 add %al,(%eax)
1b: 00 20 add %ah,(%eax)
1d: 00 00 add %al,(%eax)
1f: 00 53 fa add %dl,-0x6(%ebx)
22: e8 00 00 00 00 call 27 <.text+0x27>
27: fa cli
28: f4 hlt
And the other is made with gcc -c main.c -nostdlib -nostdinc -fno-builtin -o main.o
C:\home\os>objdump -d main.o
main.o: file format pe-i386
Disassembly of section .text:
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 ec 08 sub $0x8,%esp
6: 83 e4 f0 and $0xfffffff0,%esp
9: b8 00 00 00 00 mov $0x0,%eax
e: 83 c0 0f add $0xf,%eax
11: 83 c0 0f add $0xf,%eax
14: c1 e8 04 shr $0x4,%eax
17: c1 e0 04 shl $0x4,%eax
1a: 89 45 fc mov %eax,-0x4(%ebp)
1d: 8b 45 fc mov -0x4(%ebp),%eax
20: e8 00 00 00 00 call 25 <_main+0x25>
25: e8 00 00 00 00 call 2a <_main+0x2a>
2a: b8 ef be ad de mov $0xdeadbeef,%eax
2f: c9 leave
30: c3 ret
31: 90 nop
32: 90 nop
33: 90 nop
Now, I try to link these using.. ld
It uses this template:
OUTPUT_FORMAT("pe-i386")
ENTRY(start)
SECTIONS
{
.text 0x100000 :
{
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data :
{
data = .; _data = .; __data = .;
*(.data)
*(.rodata)
. = ALIGN(4096);
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .; _end = .; __end = .;
}
But it doesn't work:
ld -Tlink.ld -o kernel boot.obj main.o
ld: warning: cannot find entry symbol start; defaulting to 00100000
boot.obj:boot.s:(.text+0x23): undefined reference to `main'
main.o:main.c:(.text+0x21): undefined reference to `_alloca'
main.o:main.c:(.text+0x26): undefined reference to `__main'
make: *** [link] Fout 1
What am I missing? I'm not used to working with windows, with ELF files I do not really run into problems. Am I supposed to use a different linker? I supposes it calls alloca because I'm missing a -fno-stack-protector, but my gcc does not grok that flag..
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,我设法通过向 main.c 添加一个虚拟 __main 函数,并在 boot.s 中调用 _main 而不是“main”来“修复”它。
谁能解释一下,或者提供更优雅的解决方案?
Ok, I managed to "fix" it by adding a dummy __main function to main.c, and calling _main in boot.s instead of "main".
Can anyone explain this, or provide a more elegant solution?