从0创建一个OS (十二) 创建gcc交叉编译器

本节将学习如何为特定目标平台创建专属编译器

关键字: 交叉编译器

目标: 创建一个可以用来建立我们的kernel的开发环境

理论基础

鉴于以后我们将使用C语言编辑我们的操作系统核,因此需要对开发环境进行新的布置,也就是创建一个交叉编译器.

为什么要搞一个交叉编译器?

事实上类Unix系统的编译环境已经足够完善,但其缺点是太完善了,我们在编译时不知道到底使用了什么样的库文件,因此我们需要创建一个交叉编译器,只包含标准C语言库文件.

搞一个交叉编译器需要什么东西?

在生成交叉编译器时,我们需要从网上下载2个源码,对这两个源码进行编译.
binutils
gcc
尽量选择最新版本.本节使用的是binutils2.32和gcc9.2.0. 英文原文教程使用的是binutils2.24和gcc4.9.1.

生成交叉编译器

我使用的是ubuntu16.04环境,在多次尝试之后总结了以下生成交叉编译器的步骤.

接下来的操作务必在同一个Terminal中完成.如果过程中不甚关闭Terminal,需要从头开始.

  1. 首先需要进入超级管理员模式,不然会报很多权限不足的错误.
    sudo su
  2. 确定你的本机gcc位置,使用which gcc指令.我的gcc位置为/usr/bin/gcc.
  3. 使用以下指令,完成对环境变量的暂时修改(退出该Termial之后环境变量会恢复)
    在这里插入图片描述
# 注意这里的gcc-5是我打开/usr/bin,搜索gcc看到的gcc版本,需要根据自身的环境进行调整 export CC=/usr/bin/gcc-5 export LD=/usr/bin/gcc-5 # PREFIX是最终编译完成的交叉编译器总的存储位置,可以修改为你想要存储的地方 # TARGET是交叉编译器的目标平台,这里选择386平台 # PATH即交叉编译器目录下的bin中含有所有可执行文件 export PREFIX="/usr/local/i386elfgcc" export TARGET=i386-elf export PATH="$PREFIX/bin:$PATH"

 

  1. 创建临时文件夹src, 将下载到的binutils和gcc放到该文件夹中
mkdir /tmp/src cd /tmp/src

 

在这里插入图片描述

  1. 先编译binutils
tar xf binutils-2.32.tar.gz mkdir binutils-build cd binutils-build ../binutils-2.32/configure --target=$TARGET --enable-interwork --enable-multilib --disable-nls --disable-werror --prefix=$PREFIX 2>&1 | tee configure.log make all install 2>&1 | tee make.log

 

  1. 再编译gcc
cd .. tar xf gcc-9.2.0.tar.bz2 mkdir gcc-build cd gcc-build # 如果这一步报错说什么gmp\mpfr等库出现问题,使用以下解决办法 # 解决办法:在gcc的根目录下,在terminal中运行 ./contrib/download_prerequisites # 如果有vpn请开vpn,下载会加速 # 运行之后进入gcc-build文件夹重新configure ../gcc-9.2.0/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --disable-libssp --enable-languages=c --without-headers make all-gcc make all-target-libgcc make install-gcc make install-target-libgcc

 

编译完成的结果:

------ update 2021.4.9 -------------

重新编译安装后,发现/usr/local/i386elfgcc/bin中的所有程序都变为没有了i386-elf前缀,暂时没有找到原因,可能是gcc-10.2.0和binutils-2.36的搭配导致i386不被支持了。

 

在这里插入图片描述

  1. 修改环境变量,使我们能够直接在terminal中使用交叉编译器进行编译,而无需每次使用时都要切换到/usr/local/i386elfgcc/bin目录下.
sudo vim /etc/profile # 在最后加上 export PATH="$PATH:/usr/local/i386elfgcc/bin" # 然后在terminal中输入 source /etc/profile # 重启termial即可

 

测试

正常情况下如果上面的每一步都不报错,交叉编译器算是生成成功了,这里给出一个示例,跟下一节的内容由部分重合.

首先新建一个c代码文件,test.c,在文件中输入如下源码:

int my_function() { return 0xBABA; }

 

再在该文件目录下打开terminal,输入

# 如果出现了i386-elf-gcc无法识别的错误,就直接使用gcc -fno-pie -m32替代i386-elf-gcc
i386-elf-gcc -ffreestanding -c test.c -o test.o
# 如果出现了i386-elf-gcc无法识别的错误,就直接使用objdump -m i386 代替
i386-elf-objdump
i386-elf-objdump -d test.o

 

如果显示如下则表示我们本节的创建gcc交叉编译器成功.
在这里插入图片描述

2020.4.4更新
如果发现:

Configuring for a x86_64-pc-linux-gnuoldld host.
Invalid configuration x86_64-pc-linux-gnuoldld': machinex86_64-pc’ not recognized
Invalid configuration x86_64-pc-linux-gnuoldld': machinex86_64-pc’ not recognized
Unrecognized host system name x86_64-pc-linux-gnuoldld.

就参考这里is-there-another-version-of-the-binutils-for-x86-64

 


__EOF__

本文作者EwanHai
本文链接https://www.cnblogs.com/haiyonghao/p/14623196.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   EwanHai  阅读(327)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示