如何以 16 位模式链接代码。和尝试链接时出现的问题
我想为我的操作系统编写一个引导加载程序,这样我就可以避免 Multiboot2 的问题。我正在使用 GNU 工具链来编写 16 位代码,但在链接时出现了问题。
我猜: 1.AS没有正确生成16位代码。但我已经在其中写入了“.code16”。
2.AS没有正确设置fie格式。OBJDUMP说“文件格式elf64-x86-64”,所以LD误会了。
3.LD设置不正确,所以它看到a.out为x64文件,但它说“R_X86_64_16”
ENV:
Linux alancui-newvm 5.11.0-49-generic #55-Ubuntu SMP Wed Jan 12 17:36:34 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
AMD [email protected] running on VMware
5GiB memory in DDR3-1600
版本:
gcc (Ubuntu 10.3.0-1ubuntu1) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
GNU assembler (GNU Binutils for Ubuntu) 2.36.1
Copyright (C) 2021 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `x86_64-linux-gnu'.
GNU ld (GNU Binutils for Ubuntu) 2.36.1
Copyright (C) 2021 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty
CMDLINE:
alancui@alancui-newvm:~/osdev/boot/x86$ gcc -E stage1.S -o w.s
alancui@alancui-newvm:~/osdev/boot/x86$ as w.s -o a.out
alancui@alancui-newvm:~/osdev/boot/x86$ ld --oformat binary a.out -o xd
ld输出:
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400000
a.out: in function `display_bootup':
(.text+0x7c0b): relocation truncated to fit: R_X86_64_16 against `.data'+c
a.out: in function `fatal_err':
(.text+0x7c27): relocation truncated to fit: R_X86_64_16 against `.data'+1b
a.out: in function `load_stage_1_5':
(.text+0x7c40): relocation truncated to fit: R_X86_64_16 against `.data'
OBJDUMP:(强制在CMDLINE中使用i8086)
a.out: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_start-0x7c00>:
...
0000000000007c00 <_start>:
7c00: e8 07 00 call 7c0a <display_bootup>
7c03: e8 39 00 call 7c3f <load_stage_1_5>
7c06: f4 hlt
7c07: eb 1d jmp 7c26 <fatal_err>
7c09: f4 hlt
0000000000007c0a <display_bootup>:
7c0a: bd 00 00 mov $0x0,%bp
7c0d: 8c d8 mov %ds,%ax
7c0f: 8e c0 mov %ax,%es
7c11: 8b 0e 0f 00 mov 0xf,%cx
7c15: b0 01 mov $0x1,%al
7c17: b4 13 mov $0x13,%ah
7c19: ba 00 00 mov $0x0,%dx
7c1c: b3 01 mov $0x1,%bl
7c1e: b7 00 mov $0x0,%bh
7c20: cd 10 int $0x10
7c22: 72 02 jb 7c26 <fatal_err>
7c24: c3 ret
7c25: f4 hlt
0000000000007c26 <fatal_err>:
7c26: bd 00 00 mov $0x0,%bp
7c29: 8c d8 mov %ds,%ax
7c2b: 8e c0 mov %ax,%es
7c2d: 8b 0e 0f 00 mov 0xf,%cx
7c31: b0 01 mov $0x1,%al
7c33: b4 13 mov $0x13,%ah
7c35: ba 00 00 mov $0x0,%dx
7c38: b3 01 mov $0x1,%bl
7c3a: b7 00 mov $0x0,%bh
7c3c: cd 10 int $0x10
7c3e: f4 hlt
0000000000007c3f <load_stage_1_5>:
7c3f: be 00 00 mov $0x0,%si
7c42: 8c d8 mov %ds,%ax
7c44: 8e c0 mov %ax,%es
7c46: b4 42 mov $0x42,%ah
7c48: b2 80 mov $0x80,%dl
7c4a: cd 13 int $0x13
7c4c: 72 d8 jb 7c26 <fatal_err>
7c4e: c3 ret
7c4f: f4 hlt
STAGE1.S:
/* Copyright (C) 2022 AlanCui4080
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*
stage1.S
The description of the first sector which will be loaded by bios and which
loads the stage 1.5
*/
/*
Author:AlanCui4080<[email protected]>
Revision:
2022/04/09: init version: AlanCui4080
*/
.section .text
.code16
.org 0x7c00
_start:
stage_1_start:
call display_bootup
call load_stage_1_5
hlt
//call stage_1_5_start //should not be returned
jmp fatal_err
hlt
/*
* display a string which shows that stage 1 has been loaded successfully
*/
display_bootup:
movw $flag_text, %bp //the source address of string
movw %ds, %ax //adjust segment regsister
movw %ax, %es
movw (flag_text_end-flag_text), %cx //length
movb $0x01, %al //MODE1
movb $0x13, %ah //0x13 mode
movw $0x00, %dx //line 0,column 0
movb $0x01, %bl //fg: white,bg:black
movb $0x00, %bh //page 0
int $0x10
jc fatal_err
ret
hlt // protection
/*
* display a string which shows that a fatal error occured
*/
fatal_err:
movw $err_text, %bp //the source address of string
movw %ds, %ax //adjust segment regsister
movw %ax, %es
movw (err_text_end-err_text), %cx //length
movb $0x01, %al //MODE1
movb $0x13, %ah //0x13 mode
movw $0x00, %dx //line 0,column 0
movb $0x01, %bl //fg: white,bg:black
movb $0x00, %bh //page 0
int $0x10
hlt // shut down
/*
* load stage 1.5 whic loads a final loader
*/
load_stage_1_5:
/* MBR-type disk layout (not scaled)*/
/* +================+===============================+
* | MBR (1 sector) | reversed sectors (63 sectors) |
* +================+===============================+
*/
movw $disk_pack, %si //the source address of disk pack
movw %ds, %ax //adjust segment regsister
movw %ax, %es
movb $0x42, %ah //LBA extension
movb $0x80, %dl //primary drive
int $0x13
jc fatal_err
ret
hlt // protection
.section .data
/*
* a struct which describes the infomation of loading stage 1.5
*/
disk_pack:
.byte 0x10 //0x10 bytes
.byte 0x00 //always 0
.short 63 //counting of sectors
.short 0x7c00+512 //target address
.long 0x02 //lower LBAaddress
.short 0x00 //upper LBAaddress
disk_pack_end:
/*
* a ASCII string that shows that stage 1 has been loaded correctly
*/
flag_text:
.ascii "STAGE 1 ACTIVED"
flag_text_end:
/*
* a ASCII string that shows that stage 1 meets a fatal error
*/
err_text:
.ascii "STAGE 1 FATAL "
err_text_end:
/* MBR sector layout (not scaled)*/
/* +===========================+==========================+===================+
* | bootloader (466 bytes) | parttable (64 bytes) | magicbyte (2bytes) |
* +===========================+==========================+===================+
*/
.org 0x7dbe //align to 446
parttable:
_stage_1_parttable:
.globl _stage_1_parttable
.fill 64,1,0 //as a table
.short 0xAA55 //end tag
I want to write a boot loader for my OS so that I can avoid problems of Multiboot2.I'm using GNU toolchain to make a 16 bit code, but while linking, problems happened.
I guess:
1.AS didn't generated 16-bit code correctly.But I already wrote ".code16" in it.
2.AS didn't set the fie format correctly.OBJDUMP said "file format elf64-x86-64",so LD mistook.
3.LD was not set correctly so it saw the a.out as a x64 file,but it said"R_X86_64_16"
ENV:
Linux alancui-newvm 5.11.0-49-generic #55-Ubuntu SMP Wed Jan 12 17:36:34 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
AMD [email protected] running on VMware
5GiB memory in DDR3-1600
VERSIONS:
gcc (Ubuntu 10.3.0-1ubuntu1) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
GNU assembler (GNU Binutils for Ubuntu) 2.36.1
Copyright (C) 2021 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `x86_64-linux-gnu'.
GNU ld (GNU Binutils for Ubuntu) 2.36.1
Copyright (C) 2021 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty
CMDLINE:
alancui@alancui-newvm:~/osdev/boot/x86$ gcc -E stage1.S -o w.s
alancui@alancui-newvm:~/osdev/boot/x86$ as w.s -o a.out
alancui@alancui-newvm:~/osdev/boot/x86$ ld --oformat binary a.out -o xd
ld OUTPUT:
ld: warning: cannot find entry symbol _start; defaulting to 0000000000400000
a.out: in function `display_bootup':
(.text+0x7c0b): relocation truncated to fit: R_X86_64_16 against `.data'+c
a.out: in function `fatal_err':
(.text+0x7c27): relocation truncated to fit: R_X86_64_16 against `.data'+1b
a.out: in function `load_stage_1_5':
(.text+0x7c40): relocation truncated to fit: R_X86_64_16 against `.data'
OBJDUMP: (FORCED to use i8086 in CMDLINE)
a.out: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_start-0x7c00>:
...
0000000000007c00 <_start>:
7c00: e8 07 00 call 7c0a <display_bootup>
7c03: e8 39 00 call 7c3f <load_stage_1_5>
7c06: f4 hlt
7c07: eb 1d jmp 7c26 <fatal_err>
7c09: f4 hlt
0000000000007c0a <display_bootup>:
7c0a: bd 00 00 mov $0x0,%bp
7c0d: 8c d8 mov %ds,%ax
7c0f: 8e c0 mov %ax,%es
7c11: 8b 0e 0f 00 mov 0xf,%cx
7c15: b0 01 mov $0x1,%al
7c17: b4 13 mov $0x13,%ah
7c19: ba 00 00 mov $0x0,%dx
7c1c: b3 01 mov $0x1,%bl
7c1e: b7 00 mov $0x0,%bh
7c20: cd 10 int $0x10
7c22: 72 02 jb 7c26 <fatal_err>
7c24: c3 ret
7c25: f4 hlt
0000000000007c26 <fatal_err>:
7c26: bd 00 00 mov $0x0,%bp
7c29: 8c d8 mov %ds,%ax
7c2b: 8e c0 mov %ax,%es
7c2d: 8b 0e 0f 00 mov 0xf,%cx
7c31: b0 01 mov $0x1,%al
7c33: b4 13 mov $0x13,%ah
7c35: ba 00 00 mov $0x0,%dx
7c38: b3 01 mov $0x1,%bl
7c3a: b7 00 mov $0x0,%bh
7c3c: cd 10 int $0x10
7c3e: f4 hlt
0000000000007c3f <load_stage_1_5>:
7c3f: be 00 00 mov $0x0,%si
7c42: 8c d8 mov %ds,%ax
7c44: 8e c0 mov %ax,%es
7c46: b4 42 mov $0x42,%ah
7c48: b2 80 mov $0x80,%dl
7c4a: cd 13 int $0x13
7c4c: 72 d8 jb 7c26 <fatal_err>
7c4e: c3 ret
7c4f: f4 hlt
STAGE1.S:
/* Copyright (C) 2022 AlanCui4080
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/*
stage1.S
The description of the first sector which will be loaded by bios and which
loads the stage 1.5
*/
/*
Author:AlanCui4080<[email protected]>
Revision:
2022/04/09: init version: AlanCui4080
*/
.section .text
.code16
.org 0x7c00
_start:
stage_1_start:
call display_bootup
call load_stage_1_5
hlt
//call stage_1_5_start //should not be returned
jmp fatal_err
hlt
/*
* display a string which shows that stage 1 has been loaded successfully
*/
display_bootup:
movw $flag_text, %bp //the source address of string
movw %ds, %ax //adjust segment regsister
movw %ax, %es
movw (flag_text_end-flag_text), %cx //length
movb $0x01, %al //MODE1
movb $0x13, %ah //0x13 mode
movw $0x00, %dx //line 0,column 0
movb $0x01, %bl //fg: white,bg:black
movb $0x00, %bh //page 0
int $0x10
jc fatal_err
ret
hlt // protection
/*
* display a string which shows that a fatal error occured
*/
fatal_err:
movw $err_text, %bp //the source address of string
movw %ds, %ax //adjust segment regsister
movw %ax, %es
movw (err_text_end-err_text), %cx //length
movb $0x01, %al //MODE1
movb $0x13, %ah //0x13 mode
movw $0x00, %dx //line 0,column 0
movb $0x01, %bl //fg: white,bg:black
movb $0x00, %bh //page 0
int $0x10
hlt // shut down
/*
* load stage 1.5 whic loads a final loader
*/
load_stage_1_5:
/* MBR-type disk layout (not scaled)*/
/* +================+===============================+
* | MBR (1 sector) | reversed sectors (63 sectors) |
* +================+===============================+
*/
movw $disk_pack, %si //the source address of disk pack
movw %ds, %ax //adjust segment regsister
movw %ax, %es
movb $0x42, %ah //LBA extension
movb $0x80, %dl //primary drive
int $0x13
jc fatal_err
ret
hlt // protection
.section .data
/*
* a struct which describes the infomation of loading stage 1.5
*/
disk_pack:
.byte 0x10 //0x10 bytes
.byte 0x00 //always 0
.short 63 //counting of sectors
.short 0x7c00+512 //target address
.long 0x02 //lower LBAaddress
.short 0x00 //upper LBAaddress
disk_pack_end:
/*
* a ASCII string that shows that stage 1 has been loaded correctly
*/
flag_text:
.ascii "STAGE 1 ACTIVED"
flag_text_end:
/*
* a ASCII string that shows that stage 1 meets a fatal error
*/
err_text:
.ascii "STAGE 1 FATAL "
err_text_end:
/* MBR sector layout (not scaled)*/
/* +===========================+==========================+===================+
* | bootloader (466 bytes) | parttable (64 bytes) | magicbyte (2bytes) |
* +===========================+==========================+===================+
*/
.org 0x7dbe //align to 446
parttable:
_stage_1_parttable:
.globl _stage_1_parttable
.fill 64,1,0 //as a table
.short 0xAA55 //end tag
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论