如何以 16 位模式链接代码。和尝试链接时出现的问题

发布于 2025-01-20 12:54:51 字数 8510 浏览 2 评论 0原文

我想为我的操作系统编写一个引导加载程序,这样我就可以避免 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文