在MinGW中构建GCC交叉编译器和GDB交叉调试器

46 篇文章 4 订阅
19 篇文章 1 订阅

前文《C语言使用MinGW中的GCC生成平面(flat)二进制文件》中有介绍MinGW中使用GCC生成编写操作系统内核所需要的32位平面(flat)二进制文件。但是如果想要在Loader中使用C语言,即编译16位的汇编与C混合代码,就必须使用ELF格式才能转换成16位平面(flat)二进制文件。MinGW默认的GCC只能生成PE文件,不能生成ELF文件,而pei-386是无法转换成16位平面(flat)二进制文件的。

如果在link.ld中使用OUTPUT_FORMAT("pei-i386"),会报错:

mingw32/bin/ld.exe: unsupported PEI architecture: pei-i386

使用使用OUTPUT_FORMAT("binary"),则会报:

mingw32/bin/ld.exe: cannot perform PE operations on non PE output file 'loader.bin'

所以为了能使用MinGW编译16位汇编与C语言的混合代码,就必须编译一个交叉编译器。

下面笔者就以最新的GCC 12.1为例,介绍如何通过MinGW来构建GCC的交叉编译器。笔者的MinGW为MSYS2中的MinGW64。

一、下载Binutils

https://ftp.gnu.org/gnu/binutils/下载最新的binutils,目前最新的为binutils-2.38.tar.xz

二、下载GCC

https://ftp.gnu.org/gnu/gcc/下载最新的GCC,目前最新的为gcc-12.1.0.tar.gz

三、解压、编译

1.解压

$HOME下新建一个目录,比如src,然后将下载的binutils-2.38.tar.xz以及gcc-12.1.0.tar.gz解压到$HOME/src

2.编译binutils

在编译之前后设置如下环境变量:

export PREFIX="/opt/cross"
export TARGET=i686-elf
export PATH="$PREFIX/bin:$PATH"

如果是想编译成64位的则把TARGET设置为x86_64-elf

然后编译、安装binutils

cd $HOME/src
 
mkdir build-binutils
cd build-binutils
../binutils-2.38/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror
make
make install

3. 编译、安装GCC

cd $HOME/src

# $PREFIX/bin目录必须在路径中,不然找不到as汇编器
which -- $TARGET-as || echo $TARGET-as is not in the PATH

# 进入GCC目录下载必要的依赖
cd gcc-12.1.0/
./contrib/download_prerequisites
cd ..

mkdir build-gcc
cd build-gcc
../gcc-12.1.0/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers
make all-gcc
make all-target-libgcc
make install-gcc
make install-target-libgcc

注意安装时的提示,后面可能会有用:

----------------------------------------------------------------------
Libraries have been installed in:
   /opt/cross/libexec/gcc/i686-elf/12.1.0

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-LLIBDIR' linker flag

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

在这里插入图片描述

编译完成后就可以在$HOME/opt/cross目录下看到相应的程序了:在这里插入图片描述
使用ld -V查看支持的格式:
在这里插入图片描述
可以看到已经支持elf_i386了。Btw:从图中可以看到生成的文件都比较大,像i686-elf-lto-dump.exe达370多M,可以通过使用strip命令删除调试信息来瘦身,在所有生成的exe目录使用:

strip *.exe

以下是瘦身后的大小情况:

在这里插入图片描述

4.编译、安装GDB

下载最新的GDB,目前为gdb-12.1,设置好环境变量后,使用下面的命令进行编译,安装:

$../gdb-12.1/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-multilib --disable-werror
$make -j8
$make install

5.设置路径

为了使用编译好的交叉编译器和调试器,需要添加到路径,编辑~/.bashrc文件,添加一行:

PATH=$PATH:/opt/cross/bin

如果编译遇到麻烦,或者不想自己编译也可以使用别人编译好的,参见:https://wiki.osdev.org/GCC_Cross-Compiler#Prebuilt Toolchains

有了交叉编译器和调试器,就可以使用MinGW构建16位应用程序了,同时也可以进行调试,有兴趣的话请关注后面的博文。

参考资料:
https://wiki.osdev.org/GCC_Cross-Compiler

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值